digitalmars.D.learn - Bug in import(...) on Windows?
- Andrey Zherikov (25/25) Sep 02 2020 My code (test.d):
- Andrey Zherikov (19/19) Sep 02 2020 Adding some verbosity:
- Adam D. Ruppe (11/12) Sep 02 2020 I think it is an old bug filed (I can't find it though) about
- Andrey Zherikov (4/17) Sep 02 2020 If I provide -Jfoo to dmd, doesn't it mean my consent to use the
- Adam D. Ruppe (5/7) Sep 02 2020 Yeah, but dmd has been inconsistent on platforms about if it
- Andrey Zherikov (7/15) Sep 02 2020 I think the issue is here:
- Andrey Zherikov (19/21) Sep 02 2020 Yes, issue is there. This change (removal of "c == '\\' || ")
- Steven Schveighoffer (8/22) Sep 02 2020 Is this the problem though? It works on DMD Linux, which shares the same...
- Andrey Zherikov (20/22) Sep 02 2020 This actually works:
- Steven Schveighoffer (6/35) Sep 02 2020 I don't know why it wouldn't work with native paths on Windows. But I'm
My code (test.d): ======= void main() { import std.path: buildPath; pragma(msg, import("file")); pragma(msg, import(buildPath(".", "file"))); } ======= Content of file "file" is one line with "hello" text. Running command: dmd -J. -run test.d Result on Ubuntu: ======= hello hello ======= Result on Windows: ======= hello test.d(46): Error: file ".\\file" cannot be found or not in a path specified with -J test.d(46): while evaluating pragma(msg, import(buildPath([".", "file"][]))) ======= Is this a bug in dmd?
Sep 02 2020
Adding some verbosity: pragma(msg, import("file")); pragma(msg, buildPath(".", "file")); pragma(msg, import(buildPath(".", "file"))); Result on Ubuntu: ======= hello ./file hello ======= Result on Windows: ======= hello .\file parser.d(47): Error: file ".\\file" cannot be found or not in a path specified with -J parser.d(47): while evaluating pragma(msg, import(buildPath([".", "file"][]))) =======
Sep 02 2020
On Wednesday, 2 September 2020 at 17:39:04 UTC, Andrey Zherikov wrote:Is this a bug in dmd?I think it is an old bug filed (I can't find it though) about inconsistent platform behavior but it is allowed by spec for the compiler to reject any path components. import("") is supposed to just give a filename, no directory path. See: https://dlang.org/spec/expression.html#import_expressions "Implementations may restrict the file name in order to avoid directory traversal security vulnerabilities. A possible restriction might be to disallow any path components in the file name."
Sep 02 2020
On Wednesday, 2 September 2020 at 17:47:47 UTC, Adam D. Ruppe wrote:On Wednesday, 2 September 2020 at 17:39:04 UTC, Andrey Zherikov wrote:If I provide -Jfoo to dmd, doesn't it mean my consent to use the contents of directory foo?Is this a bug in dmd?I think it is an old bug filed (I can't find it though) about inconsistent platform behavior but it is allowed by spec for the compiler to reject any path components. import("") is supposed to just give a filename, no directory path. See: https://dlang.org/spec/expression.html#import_expressions "Implementations may restrict the file name in order to avoid directory traversal security vulnerabilities. A possible restriction might be to disallow any path components in the file name."
Sep 02 2020
On Wednesday, 2 September 2020 at 18:40:55 UTC, Andrey Zherikov wrote:If I provide -Jfoo to dmd, doesn't it mean my consent to use the contents of directory foo?Yeah, but dmd has been inconsistent on platforms about if it allows subdirectories. Right now I think it just strips all slashes out so your .\ path there just gets caught in the filter.
Sep 02 2020
On Wednesday, 2 September 2020 at 19:13:47 UTC, Adam D. Ruppe wrote:On Wednesday, 2 September 2020 at 18:40:55 UTC, Andrey Zherikov wrote:I think the issue is here: https://github.com/dlang/dmd/blob/master/src/dmd/root/filename.d#L736-L748 Does it makes sense to allow paths in import(file) unless path points through parent directory, i.e. !buildNormalizedPath(file).startsWith("..")?If I provide -Jfoo to dmd, doesn't it mean my consent to use the contents of directory foo?Yeah, but dmd has been inconsistent on platforms about if it allows subdirectories. Right now I think it just strips all slashes out so your .\ path there just gets caught in the filter.
Sep 02 2020
On Wednesday, 2 September 2020 at 20:55:34 UTC, Andrey Zherikov wrote:I think the issue is here: https://github.com/dlang/dmd/blob/master/src/dmd/root/filename.d#L736-L748Yes, issue is there. This change (removal of "c == '\\' || ") fixes it: diff --git a/src/dmd/root/filename.d b/src/dmd/root/filename.d index 09810df8e..673582d0e 100644 --- a/src/dmd/root/filename.d +++ b/src/dmd/root/filename.d -741,7 +741,7 nothrow: for (const(char)* p = name; *p; p++) { char c = *p; - if (c == '\\' || c == ':' || c == '%' || (c == '.' && p[1] == '.') || (c == '/' && p[1] == '/')) + if (c == ':' || c == '%' || (c == '.' && p[1] == '.') || (c == '/' && p[1] == '/')) { return null; }
Sep 02 2020
On 9/2/20 1:47 PM, Adam D. Ruppe wrote:On Wednesday, 2 September 2020 at 17:39:04 UTC, Andrey Zherikov wrote:Is this the problem though? It works on DMD Linux, which shares the same front end. What I'm wondering is if it needs to be ./file instead of .\file. Can you hard code that and see if it works? FYI, I know vibe diet templates DEPEND on this behavior, and I'd be surprised if it doesn't work at all on Windows. -SteveIs this a bug in dmd?I think it is an old bug filed (I can't find it though) about inconsistent platform behavior but it is allowed by spec for the compiler to reject any path components. import("") is supposed to just give a filename, no directory path. See: https://dlang.org/spec/expression.html#import_expressions "Implementations may restrict the file name in order to avoid directory traversal security vulnerabilities. A possible restriction might be to disallow any path components in the file name."
Sep 02 2020
On Wednesday, 2 September 2020 at 20:23:15 UTC, Steven Schveighoffer wrote:What I'm wondering is if it needs to be ./file instead of .\file. Can you hard code that and see if it works?This actually works: pragma(msg, import("file")); pragma(msg, buildPath(".", "file")); pragma(msg, import("./file")); Result on Ubuntu: ======= hello ./file hello ======= Result on Windows: ======= hello .\file hello ======= This seems weird that I can't use std.path functions or use valid "foo\bar" paths on Windows.
Sep 02 2020
On 9/2/20 4:48 PM, Andrey Zherikov wrote:On Wednesday, 2 September 2020 at 20:23:15 UTC, Steven Schveighoffer wrote:I don't know why it wouldn't work with native paths on Windows. But I'm not a DMD maintainer, so I don't know where to look in the code to see why it doesn't work. It might be worth filing a bug. https://issues.dlang.org -SteveWhat I'm wondering is if it needs to be ./file instead of .\file. Can you hard code that and see if it works?This actually works: pragma(msg, import("file")); pragma(msg, buildPath(".", "file")); pragma(msg, import("./file")); Result on Ubuntu: ======= hello ../file hello ======= Result on Windows: ======= hello ..\file hello ======= This seems weird that I can't use std.path functions or use valid "foo\bar" paths on Windows.
Sep 02 2020