[quickjs-devel] Re: loaded modules cache can have duplicate entries for the same module

  • From: Alex Protasenko <aprotasenko@xxxxxxxxx>
  • To: quickjs-devel@xxxxxxxxxxxxx
  • Date: Wed, 20 May 2020 21:33:06 -0400

Sorry about all the fuss, but important clarification: module will be loaded twice only when relative path crosses the boundary of basepath of the main module. To demonstrate,

consider the main module ./main.js:

```

import { r } from "./dep.js";
import { r as r1 } from "../existing-parent-dir/dep.js";
console.log(r == r1);
```

where module ./dep.js is defined as so:

```

export let r = Math.random();

```

The output of `qjs -m ./main.js` will be: "false", which proves the same module ./deps.js was loaded twice.

The fix could be as simple as use "realpath" to convert script name passed to qjs.c. Then all relative paths in module names will be converted to absolute and the problem goes away


Regards

Alex

On 5/19/20 11:21 PM, Alex Protasenko wrote:

Hello,


JSModuleDef.module_name can be stored as either relative or absolute path depending on particular combination of import module name and script file name specified. E.g. if script is loaded using absolute path, i.e. "qjs -m /abs/path/a.js", then module_name will always have absolute path for all loaded modules.

If, on the other hand, script was loaded using relative path, e.g. "qjs -m ./a.js", then the JSModuleDef.module_name will have either relative or absolute path depending on how the import name was specified. And that's where the problem occurs.

Suppose a module is imported using relative path and elsewhere the same module is imported using absolute path. As it happens, js_find_loaded_module() fails to match relative and absolute paths as referring to the same module and JSContext.loaded_modules list ends up having duplicate entries. This probably means the module is loaded twice as well. In fact, if one gets creative with relative paths in import, i.e. ../../blah, one could get many copies of the same module loaded.

Another interesting feature is `import "a.js"` means import a.js from $PWD, although it should probably mean the same as `import "./a.js"`

Anyway, JSModuleDef.module_name should probably be specified in canonical absolute path form to avoid ambiguities,


Thanks

Alex




Other related posts: