Luca's meaningless thoughts   SponsorGitHub SponsorsLiberapayPaypalBuy Me A CoffeePatreonFlattr

Improved string imports

by Leandro Lucarella on 2009- 12- 01 22:38 (updated on 2009- 12- 01 22:38)
tagged d, en, import, patch, string import - with 0 comment(s)

D has a very nice capability of string imports. A string import let you read a file at compile time as a string, for example:

pragma(msg, import("hello.txt"));

Will print the contents of the file hello.txt when it's compiled, or it will fail to compile if hello.txt is not readable or the -J option is not used. The -J option is needed because of security reasons, otherwise compiling a program could end up reading any file in your filesystem (storing it in the binary and possibly violating your privacy). For example you could compile a program as root and run it as an unprivileged user thinking it can't possibly read some protected data, but that data could be read at compile-time, with root privileges.

Anyway, D ask you to use the -J option if you are doing string imports, which seems reasonable. What doesn't look so reasonable is that string imports can't access a file in a subdirectory. Let's say we have a file test.d in the current directory like this:

immutable s = import("data/hello.txt");

And in the current directory we have a subdirectory called data and a file hello.txt in it. This won't compile, ever (no matter what -J option you use). I think this is an unnecessary limitation, using -J. should work. I can see why this was done like that, what if you write:

immutable s = import("../hello.txt");

It looks like this shouldn't work, so we can ban .. from string imports, but what about this:

immutable s = import("data/../data/hello.txt");

This should work, it's a little convoluted but it should work. And what about symbolic links?

Well, I think this limitation can be relaxed (other people think that too, there is even a bug report for this), at least on POSIX-compatible OSs, because we can use the realpath() function to resolve the file. If you resolve both the -J directories and the resulting files, it's very easy to check if the string import file really belongs to a -J subdirectory or not.

This looks very trivial to implement, so I gave it a shot and posted a patch and a couple of test cases to that very same bug report :)

The patch is incomplete, though, because it's only tested on Linux and it lacks Windows support (I don't know how to do this on Windows and don't have an environment to test it). If you like this feature and you know Windows, please complete the patch, so it has better chances to make it in D2, you only have to implement the canonicalName() function. If you have other supported POSIX OS, please test the patch and report any problems.