Bug 21227 – import(".\\file") doesn't work on Windows
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2020-09-05T14:52:24Z
Last change time
2020-09-22T18:36:37Z
Assigned to
No Owner
Creator
Andrey Zherikov
Comments
Comment #0 by andrey.zherikov — 2020-09-05T14:52:24Z
Imports with backslash doesn't work on Windows although backslash is a valid path character there.
This can be reproduced with this:
======= test.d
void main()
{
pragma(msg, import("./file"));
pragma(msg, import(".\\file"));
}
======= file
hello
=======
Command to reproduce:
>dmd -J. -run test.d
hello
test.d(4): Error: file ".\\file" cannot be found or not in a path specified with -J
test.d(4): while evaluating pragma(msg, import(".\\file"))
DMD used to reproduce:
- DMD32 D Compiler v2.091.0-dirty
- latest master (DMD64 D Compiler v2.093.1-524-g1e09d998f)
The issue is in if condition here: https://github.com/dlang/dmd/blob/master/src/dmd/root/filename.d#L744
And this change efficiently fixes it although I'm not sure whether something else should be done:
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;
}
Comment #1 by moonlightsentinel — 2020-09-05T15:19:53Z
Plainly allowing is not the right fix (given the contract of the function) because it allows to write absolute paths:
Try e.g.:
pragma(msg, import(`\papth\to\dmd\README.md`));
Comment #2 by andrey.zherikov — 2020-09-06T15:30:04Z
(In reply to moonlightsentinel from comment #1)
> Plainly allowing is not the right fix (given the contract of the function)
> because it allows to write absolute paths:
>
> Try e.g.:
>
> pragma(msg, import(`\papth\to\dmd\README.md`));
Whether to allow absolute path or not is a separate question and I agree with denying them. The issue here is in rejecting the valid path character.
Another issue here is that error message is useless because it doesn't shed any light why file ".\file" can't be found although it exists for sure.
Comment #3 by andrey.zherikov — 2020-09-06T16:50:28Z
I'm not an expert in this subject but IMO the restrictions should simple:
- Do not allow absolute path. There is FileName.absolute function that can be used: https://github.com/dlang/dmd/blob/master/src/dmd/root/filename.d#L103
- Do not allow reference to parent (i.e. ".." ) directory anywhere in the path
Comment #4 by dlang-bot — 2020-09-10T16:18:48Z
@andrey-zherikov created dlang/dmd pull request #11720 "Fix path validation in import expression (issue #21227)" mentioning this issue:
- Fix path validation in import expression (issue #21227)
https://github.com/dlang/dmd/pull/11720
Comment #5 by dlang-bot — 2020-09-16T04:57:36Z
dlang/dmd pull request #11720 "Fix path validation in import expression (issue #21227)" was merged into master:
- b6ac2891b28d4f25136b5c2bf5100f4837748af6 by Andrey Zherikov:
Fix issue 21227: import(".\file") doesn't work on Windows
https://github.com/dlang/dmd/pull/11720
Comment #6 by dlang-bot — 2020-09-22T18:36:37Z
dlang/dmd pull request #11748 "E2E tests for issue 21227: import(".\file") doesn't work on Windows" was merged into master:
- 5bee37fa5cf05a97b3d7ac0fdeb968fbb4db89b6 by Andrey Zherikov:
E2E tests for issue 21227: import(".\file") doesn't work on Windows
https://github.com/dlang/dmd/pull/11748