[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Incorrect parsing of DOS/Windows paths ??

From: Eli Zaretskii
Subject: Re: Incorrect parsing of DOS/Windows paths ??
Date: Sun, 18 Dec 2016 22:10:44 +0200

> From: Paul Smith <address@hidden>
> Cc: address@hidden
> Date: Sun, 18 Dec 2016 13:29:56 -0500
> This function is called wherever the next thing the parser wants to see
> is a list of files, and it wants to break them up into multiple
> individual filenames.  However, most of those places don't treat colons
> specially.  For example in the wildcard function we don't check for
> colons at all: only whitespace is considered to be a stop-char.
> The only place where we treat colons specially is in parsing the targets
> of rules, where we have to stop if we find the colon between the target
> and the prerequisite, because this syntax is valid:
>   foo:bar ; echo hi
> which should be parsed as the same as:
>   foo : bar ; echo hi

That's what I knew.  But a target name doesn't have to be a valid file
name, does it?

> > > E.g., from what I can see this will accept the following as a valid,
> > > single pathname:
> > > 
> > >   foo:/bar:\biz
> > > 
> > > ???
> > 
> > Yes, it will.  And then Make will properly display an error message
> > where the results are used as file names.  Is that wrong?  Won't the
> > same happen on Unix, if a file /bar:\biz doesn't exist?
> No, in UNIX the above will be broken into separate files like this:
>   foo
>   /bar:\biz

I think you are taking the example too literally.  I never said that
on Unix the line will be parsed identically, just that Make will react
the same there to file names that don't exist.

IOW, IMO whether a target names a valid file or not is up to the user;
Make should not make these decisions, as it doesn't on Unix.  The fact
that almost any string is a valid file name on Unix is immaterial, IMO.

> Maybe it would be clearer what the issue was if we removed the second
> colon:
>   foo:/bar ; @echo hi
> In UNIX this would be "foo : /bar ; @echo hi" which is a valid rule.

On Windows, this is ambiguous, i.e. it invokes "undefined behavior".
There's no reason for Make on Windows to second-guess that the user
meant "foo : /bar".  (In practice, no one writes such rules, certainly
not on Windows.)

> If I understand this code correctly (I haven't tested this) then on
> Windows with DOS_PATHS make would parse the target as "foo:/bar" and
> then give a "missing separator" error.

Yes.  And why is that a problem?  Support for target/file names with
drive letters is already a certain violation of the Makefile grammar,
so this is uncharted territory.  We can set any rules that are
convenient to us.

> > > Why wouldn't the correct algorithm be: if we stopped due to a drive
> > > specifier (the pathname starts with "[A-Za-z]:")
> > 
> > A nit: DOS drive letters can be A-z, including the few characters
> > between Z and a.
> You can really have a drive named "\" or "]"?

Yes, but only on DOS.  Windows doesn't allow that.

> > >   C:foo.o:C:foo.c
> > > 
> > > Breaks down as:
> > > 
> > >   C:foo.o
> > >   C:foo.c
> > 
> > Which I'd rather not support, because it could also be an error, with
> > the real target being just C.  IOW, it's ambiguous, and Make had
> > better not second-guessed the luser.
> OK, we can make that rule (that the only valid drive specifier syntax in
> target list must have a slash or backslash after the colon).  Note,
> though, that this won't apply to other places where we parse filenames,
> because those places don't treat colons specially so this test would
> never succeed (p never equals ':' because colon is not a stopchar).

That's fine with me.  Once again, it's the user's fault: using
drive-relative file names on Windows is inherently dangerous, because,
unlike on DOS, the current directory on each drive is per-process, not
a system-global setting.  In practice, in most cases C:foo resolves to
C:/foo on Windows, unless the same process already have set the
current directory on drive C, something that rarely happens,
definitely so in the context of Make invoking other programs.

> So, the only place make would enforce the rule that you must use "C:/"
> and cannot use "C:foo" would be in the target list: not prerequisites,
> not wildcard arguments, etc.


> > Bottom line: can you tell what can and cannot be on lines that are
> > parsed by that function?  Does it have to be one or two valid file
> > names?  Otherwise I feel like we are talking about an issue at least
> > one of us -- myself -- doesn't fully understand.
> If it's still not clear after my explanation above let me know.

Well, one issue is that a target name doesn't have to be a valid file
name, right?  Do we want to support such target names?

And I still feel we should have some kind of formal definition of what
constitutes a valid line parsed by that function.  Leaving this to the
code to tell is less desirable, IMO.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]