Skip to content

Commit 5fc5887

Browse files
committed
Make module imports relative to referencing module
1 parent 2a37c46 commit 5fc5887

File tree

10 files changed

+66
-51
lines changed

10 files changed

+66
-51
lines changed

bin/ch/Helpers.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ uint ConcatPath(LPCSTR filenameLeft, uint posPathSep, LPCSTR filenameRight, char
155155
return totalLength;
156156
}
157157

158-
HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UINT* lengthBytesOut /*= nullptr*/)
158+
HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UINT* lengthBytesOut /*= nullptr*/, std::string* fullPath /*= nullptr*/)
159159
{
160160
static char sHostApplicationPathBuffer[MAX_URI_LENGTH];
161161
static uint sHostApplicationPathBufferLength = (uint) -1;
@@ -169,7 +169,7 @@ HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UIN
169169
FILE * file = NULL;
170170
size_t bufferLength = 0;
171171

172-
LPCSTR filename = filenameToLoad;
172+
LPCSTR filename = fullPath == nullptr ? filenameToLoad : LPCSTR(fullPath->c_str());
173173
if (sHostApplicationPathBufferLength == (uint)-1)
174174
{
175175
// consider incoming filename as the host app and base its' path for others
@@ -188,7 +188,7 @@ HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UIN
188188
}
189189
sHostApplicationPathBuffer[sHostApplicationPathBufferLength] = char(0);
190190
}
191-
else if (filename[0] != '/' && filename[0] != '\\') // make sure it's not a full path
191+
else if (filename[0] != '/' && filename[0] != '\\' && fullPath == nullptr) // make sure it's not a full path
192192
{
193193
// concat host path and filename
194194
uint len = ConcatPath(sHostApplicationPathBuffer, sHostApplicationPathBufferLength,

bin/ch/Helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class Helpers
88
{
99
public :
10-
static HRESULT LoadScriptFromFile(LPCSTR filename, LPCSTR& contents, UINT* lengthBytesOut = nullptr);
10+
static HRESULT LoadScriptFromFile(LPCSTR filename, LPCSTR& contents, UINT* lengthBytesOut = nullptr, std::string* fullPath = nullptr);
1111
static LPCWSTR JsErrorCodeToString(JsErrorCode jsErrorCode);
1212
static void LogError(__in __nullterminated const char16 *msg, ...);
1313
static HRESULT LoadBinaryFile(LPCSTR filename, LPCSTR& contents, UINT& lengthBytes, bool printFileOpenError = true);

bin/ch/WScriptJsrt.cpp

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ JsValueRef WScriptJsrt::LoadScriptFileHelper(JsValueRef callee, JsValueRef *argu
223223
hr = Helpers::LoadScriptFromFile(*fileName, fileContent);
224224
if (FAILED(hr))
225225
{
226-
// check if have it registered
227226
fprintf(stderr, "Couldn't load file '%s'\n", fileName.GetString());
228227
IfJsrtErrorSetGo(ChakraRTInterface::JsGetUndefinedValue(&returnValue));
229228
return returnValue;
@@ -1232,7 +1231,6 @@ JsValueRef __stdcall WScriptJsrt::LoadTextFileCallback(JsValueRef callee, bool i
12321231

12331232
if (FAILED(hr))
12341233
{
1235-
// check if have it registered
12361234
fprintf(stderr, "Couldn't load file '%s'\n", fileName.GetString());
12371235
IfJsrtErrorSetGo(ChakraRTInterface::JsGetUndefinedValue(&returnValue));
12381236
return returnValue;
@@ -1396,7 +1394,6 @@ JsValueRef __stdcall WScriptJsrt::LoadBinaryFileCallback(JsValueRef callee,
13961394

13971395
if (FAILED(hr))
13981396
{
1399-
// check if have it registered
14001397
fprintf(stderr, "Couldn't load file '%s'\n", fileName.GetString());
14011398
IfJsrtErrorSetGoLabel(ChakraRTInterface::JsGetUndefinedValue(&returnValue), Error);
14021399
return returnValue;
@@ -1845,12 +1842,14 @@ HRESULT WScriptJsrt::CallbackMessage::CallFunction(LPCSTR fileName)
18451842
return hr;
18461843
}
18471844

1848-
WScriptJsrt::ModuleMessage::ModuleMessage(JsModuleRecord module, JsValueRef specifier)
1845+
WScriptJsrt::ModuleMessage::ModuleMessage(JsModuleRecord module, JsValueRef specifier, std::string* fullPathPtr)
18491846
: MessageBase(0), moduleRecord(module), specifier(specifier)
18501847
{
1848+
fullPath = nullptr;
18511849
ChakraRTInterface::JsAddRef(module, nullptr);
18521850
if (specifier != nullptr)
18531851
{
1852+
fullPath = new std::string (*fullPathPtr);
18541853
// nullptr specifier means a Promise to execute; non-nullptr means a "fetch" operation.
18551854
ChakraRTInterface::JsAddRef(specifier, nullptr);
18561855
}
@@ -1861,6 +1860,7 @@ WScriptJsrt::ModuleMessage::~ModuleMessage()
18611860
ChakraRTInterface::JsRelease(moduleRecord, nullptr);
18621861
if (specifier != nullptr)
18631862
{
1863+
delete fullPath;
18641864
ChakraRTInterface::JsRelease(specifier, nullptr);
18651865
}
18661866
}
@@ -1885,19 +1885,18 @@ HRESULT WScriptJsrt::ModuleMessage::Call(LPCSTR fileName)
18851885
errorCode = specifierStr.GetError();
18861886
if (errorCode == JsNoError)
18871887
{
1888-
hr = Helpers::LoadScriptFromFile(*specifierStr, fileContent);
1888+
hr = Helpers::LoadScriptFromFile(*specifierStr, fileContent, nullptr, fullPath);
18891889

18901890
if (FAILED(hr))
18911891
{
1892-
// check if have it registered
18931892
if (!HostConfigFlags::flags.MuteHostErrorMsgIsEnabled)
18941893
{
18951894
fprintf(stderr, "Couldn't load file '%s'\n", specifierStr.GetString());
18961895
}
1897-
LoadScript(nullptr, *specifierStr, nullptr, "module", true, WScriptJsrt::FinalizeFree, false);
1896+
LoadScript(nullptr, fullPath == nullptr ? *specifierStr : fullPath->c_str(), nullptr, "module", true, WScriptJsrt::FinalizeFree, false);
18981897
goto Error;
18991898
}
1900-
LoadScript(nullptr, *specifierStr, fileContent, "module", true, WScriptJsrt::FinalizeFree, true);
1899+
LoadScript(nullptr, fullPath == nullptr ? *specifierStr : fullPath->c_str(), fileContent, "module", true, WScriptJsrt::FinalizeFree, true);
19011900
}
19021901
}
19031902
Error:
@@ -1936,9 +1935,9 @@ JsErrorCode WScriptJsrt::FetchImportedModuleHelper(JsModuleRecord referencingMod
19361935
{
19371936
GetDir(fullPath, &moduleDirMap[moduleRecord]);
19381937
InitializeModuleInfo(specifier, moduleRecord);
1939-
moduleRecordMap[std::string(fullPath)] = moduleRecord;
1940-
ModuleMessage* moduleMessage =
1941-
WScriptJsrt::ModuleMessage::Create(referencingModule, specifier);
1938+
std::string pathKey = std::string(fullPath);
1939+
moduleRecordMap[pathKey] = moduleRecord;
1940+
ModuleMessage* moduleMessage = WScriptJsrt::ModuleMessage::Create(referencingModule, specifier, &pathKey);
19421941
if (moduleMessage == nullptr)
19431942
{
19441943
return JsErrorOutOfMemory;
@@ -1973,14 +1972,6 @@ JsErrorCode WScriptJsrt::FetchImportedModule(_In_ JsModuleRecord referencingModu
19731972
JsErrorCode WScriptJsrt::FetchImportedModuleFromScript(_In_ JsSourceContext dwReferencingSourceContext,
19741973
_In_ JsValueRef specifier, _Outptr_result_maybenull_ JsModuleRecord* dependentModuleRecord)
19751974
{
1976-
// ch.exe assumes all imported source files are located at .
1977-
auto scriptDirEntry = scriptDirMap.find(dwReferencingSourceContext);
1978-
if (scriptDirEntry != scriptDirMap.end())
1979-
{
1980-
std::string dir = scriptDirEntry->second;
1981-
return FetchImportedModuleHelper(nullptr, specifier, dependentModuleRecord, dir.c_str());
1982-
}
1983-
19841975
return FetchImportedModuleHelper(nullptr, specifier, dependentModuleRecord);
19851976
}
19861977

bin/ch/WScriptJsrt.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,18 @@ class WScriptJsrt
3636
private:
3737
JsModuleRecord moduleRecord;
3838
JsValueRef specifier;
39+
std::string* fullPath;
3940

40-
ModuleMessage(JsModuleRecord module, JsValueRef specifier);
41+
ModuleMessage(JsModuleRecord module, JsValueRef specifier, std::string* fullPathPtr);
4142

4243
public:
4344
~ModuleMessage();
4445

4546
virtual HRESULT Call(LPCSTR fileName) override;
4647

47-
static ModuleMessage* Create(JsModuleRecord module, JsValueRef specifier)
48+
static ModuleMessage* Create(JsModuleRecord module, JsValueRef specifier, std::string* fullPath = nullptr)
4849
{
49-
return new ModuleMessage(module, specifier);
50+
return new ModuleMessage(module, specifier, fullPath);
5051
}
5152

5253
};

test/es6module/bug_issue_3257.js

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,9 @@
33
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
44
//-------------------------------------------------------------------------------------------------------
55

6-
WScript.RegisterModuleSource("mod0.js", `
7-
import 'mod1.js';
8-
import 'mod2.js';
6+
// Test that ch handles relative paths for module imports correctly
7+
// See orriginal issue https://github.com/Microsoft/ChakraCore/issues/3257
8+
// and repeat (following reversion) https://github.com/Microsoft/ChakraCore/issues/5237
99

10-
console.log("mod0");
11-
`);
12-
13-
WScript.RegisterModuleSource("mod1.js",`
14-
import 'mod2.js';
15-
console.log("mod1");
16-
`);
17-
18-
WScript.RegisterModuleSource("mod2.js",`
19-
import 'mod0.js';
20-
console.log("mod2");
21-
`);
22-
23-
WScript.RegisterModuleSource("script0.js",`
24-
console.log("script0");
25-
import('mod1.js');
26-
import('mod2.js');
27-
`);
28-
29-
WScript.LoadScriptFile("mod0.js", "module");
30-
WScript.LoadScriptFile("script0.js");
10+
WScript.LoadScriptFile("bug_issue_3257/mod/mod0.js", "module");
11+
WScript.LoadScriptFile("bug_issue_3257/script/script0.js");
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// static imports in a module - relative to the module
7+
8+
import '../mod1.js';
9+
import '../mod2/mod2.js';
10+
11+
// dynamic import in a module - relative to the module
12+
13+
import('../mod1.js').catch(e => print("Should not be printed"));
14+
15+
print("mod0");

test/es6module/bug_issue_3257/mod1.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// static import in a module, relative to the module
7+
8+
import 'mod2/mod2.js';
9+
print("mod1");
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
//static import in a module, relative to module
7+
8+
import '../mod/mod0.js';
9+
print("mod2");
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// Dynamic import from a Script - relative to CWD not the script
7+
print("script0");
8+
import('bug_issue_3257/mod1.js').catch(e => print ("Should not be printed"));
9+
import('bug_issue_3257/mod2/mod2.js').catch(e => print ("Should not be printed"));

test/es6module/rlexe.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
<files>bug_issue_3257.js</files>
138138
<compile-flags>-ESDynamicImport</compile-flags>
139139
<baseline>bug_issue_3257.baseline</baseline>
140-
<tags>exclude_sanitize_address</tags>
140+
<tags>exclude_sanitize_address,exclude_jshost</tags>
141141
</default>
142142
</test>
143143
<test>

0 commit comments

Comments
 (0)