Skip to content

Commit 98b1be0

Browse files
addaleaxsxa
authored andcommitted
src: return proper URLs from node_api_get_module_file_name
Using `file://${path}` does not properly escape special URL characters. PR-URL: #41758 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Michael Dawson <midawson@redhat.com>
1 parent ecb5980 commit 98b1be0

2 files changed

Lines changed: 41 additions & 9 deletions

File tree

‎src/node_api.cc‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include"node_buffer.h"
1010
#include"node_errors.h"
1111
#include"node_internals.h"
12+
#include"node_url.h"
1213
#include"threadpoolwork-inl.h"
1314
#include"tracing/traced_value.h"
1415
#include"util-inl.h"
@@ -589,13 +590,13 @@ void napi_module_register_by_symbol(v8::Local<v8::Object> exports,
589590
if (module->ToObject(context).ToLocal(&modobj) &&
590591
modobj->Get(context, node_env->filename_string()).ToLocal(&filename_js) &&
591592
filename_js->IsString()) {
592-
node::Utf8Value filename(node_env->isolate(), filename_js);// Cast
593+
node::Utf8Value filename(node_env->isolate(), filename_js);
593594

594595
// Turn the absolute path into a URL. Currently the absolute path is always
595596
// a file system path.
596597
// TODO(gabrielschulhof): Pass the `filename` through unchanged if/when we
597598
// receive it as a URL already.
598-
module_filename = std::string("file://") + (*filename);
599+
module_filename = node::url::URL::FromFilePath(filename.ToString()).href();
599600
}
600601

601602
// Create a new napi_env for this specific module.

‎test/node-api/test_general/test.js‎

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,46 @@
11
'use strict';
22

33
constcommon=require('../../common');
4+
consttmpdir=require('../../common/tmpdir');
5+
constchild_process=require('child_process');
6+
constfs=require('fs');
7+
constpath=require('path');
8+
consturl=require('url');
49
constfilename=require.resolve(`./build/${common.buildType}/test_general`);
510
consttest_general=require(filename);
611
constassert=require('assert');
712

8-
// TODO(gabrielschulhof): This test may need updating if/when the filename
9-
// becomes a full-fledged URL.
10-
assert.strictEqual(test_general.filename,`file://${filename}`);
13+
tmpdir.refresh();
1114

12-
const[major,minor,patch,release]=test_general.testGetNodeVersion();
13-
assert.strictEqual(process.version.split('-')[0],
14-
`v${major}.${minor}.${patch}`);
15-
assert.strictEqual(release,process.release.name);
15+
{
16+
// TODO(gabrielschulhof): This test may need updating if/when the filename
17+
// becomes a full-fledged URL.
18+
assert.strictEqual(test_general.filename,url.pathToFileURL(filename).href);
19+
}
20+
21+
{
22+
consturlTestDir=path.join(tmpdir.path,'foo%#bar');
23+
consturlTestFile=path.join(urlTestDir,path.basename(filename));
24+
fs.mkdirSync(urlTestDir,{recursive: true});
25+
fs.copyFileSync(filename,urlTestFile);
26+
// Use a child process as indirection so that the native module is not loaded
27+
// into this process and can be removed here.
28+
constreportedFilename=child_process.spawnSync(
29+
process.execPath,
30+
['-p',`require(${JSON.stringify(urlTestFile)}).filename`],
31+
{encoding: 'utf8'}).stdout.trim();
32+
assert.doesNotMatch(reportedFilename,/foo%#bar/);
33+
assert.strictEqual(reportedFilename,url.pathToFileURL(urlTestFile).href);
34+
fs.rmSync(urlTestDir,{
35+
force: true,
36+
recursive: true,
37+
maxRetries: 256
38+
});
39+
}
40+
41+
{
42+
const[major,minor,patch,release]=test_general.testGetNodeVersion();
43+
assert.strictEqual(process.version.split('-')[0],
44+
`v${major}.${minor}.${patch}`);
45+
assert.strictEqual(release,process.release.name);
46+
}

0 commit comments

Comments
 (0)