[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.
Yup.
> > 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.
Thanks.