relative imports and duplicate includes

Kristian Lyngstol kly at redpill-linpro.com
Tue Nov 17 14:36:24 CET 2015


On Tue, Nov 17, 2015 at 10:16:26AM +0000, Poul-Henning Kamp wrote:
> --------
> In message <CABaBnj4AVVgkkc6d2fjdu8FTrxmWAGZDV7JcUdopsCSPK0_duA at mail.gmail.com>, Kacper Wysocki writes:
> 
> >attached is a patch to make 'import foo' relative to the importing source file,
> 
> We thought a lot about this originally, and the conclusion back
> then was to not do it for reasons of predictability and security.

(...)

Extensive snipping applied.

There are two separate, but related issues here:

1. Duplicate "import" statements.
2. Relative paths for "include".

I speak now of expected behavior from a user-perspective, not
implementation. (convenient!)

For 1., the most obvious issue is the "import foo;" vs "import foo from
...". These should be treated as conflicts. You should not be able to
load foo twice from different places. To do so would require name spaces
for each included VCL file, and we don't want to open that can of worms.

As import statements have nothing to do with VCL search paths, the
location or search mechanics of VCLs is irrelevant to import statements.
You either get the system default, or you specify the path. Whether
vmod_dir should be a list or not is also secondary to this. List or not,
it's not defined by the location of the VCL. "import foo;" means the
same thing in all VCL files.

For 2., we should look to what others have done before us. I briefly
revisited Python's way of treating module search paths [1] and
gcc/C's way of treating header files[2].

If it wasn't already obvious, both suggest that vcl_dir should in fact
be a list of paths.

#include "foo" and #include <foo> are a bit different in C, but I'm
leaning towards treating our include statements as #include "foo", which
would also align closer to Python's module search path. That would
suggest searching for a file first in the same directory as the input
file, then system directories.

Assuming vcl_dir is "/usr/share/varnish/vcls/", a file in
/etc/varnish/default.vcl stating "include foo/bar.vcl" will then first
look for /etc/varnish/foo/bar.vcl, then
"/usr/share/varnish/vcls/foo/bar.vcl". If foo/bar.vcl was found in
/etc/varnish/foo/bar.vcl and contains an other include statement, say
"include blatti/blop.vcl", we will look first for
"/etc/varnish/foo/blatti/blop.vcl", then for
"/usr/share/varnish/vcls/blatti/blop.vcl".

With in-line VCL, there is no current directory. Any include statement
would have to be found in the vcl_dir search path if a relative URL is
used.

This seems fairly predictable, in line with how others have done it, and
not particularly dangerous. If one is concerned for security, set
vcl_dir to blank.

An issue that has not been addressed:

#ifndef _FOO_H
#define _FOO_H
do stuff
#endif

We need to be able to do similar things in VCL in the long run. You want
to be able to build VCL libraries where it's safe to include the same
VCL multiple times. This, however, can be a separate discussion. I
believe the C-approach would suffice.

[1] https://docs.python.org/2/tutorial/modules.html#the-module-search-path
[2] https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html

- Kristian




More information about the varnish-dev mailing list