Skip to content

Commit 6199b5e

Browse files
boingoingpleath
authored andcommitted
1 parent 3bee8f0 commit 6199b5e

File tree

4 files changed

+76
-4
lines changed

4 files changed

+76
-4
lines changed

lib/Parser/Scan.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,20 +193,30 @@ void Scanner<EncodingPolicy>::PrepareForBackgroundParse(Js::ScriptContext *scrip
193193
// This is used to determine a length of BSTR, which can't contain a NUL character.
194194
//-----------------------------------------------------------------------------
195195
template <typename EncodingPolicy>
196-
charcount_t Scanner<EncodingPolicy>::LineLength(EncodedCharPtr first, EncodedCharPtr last)
196+
charcount_t Scanner<EncodingPolicy>::LineLength(EncodedCharPtr first, EncodedCharPtr last, size_t* cb)
197197
{
198+
Assert(cb != nullptr);
199+
198200
charcount_t result = 0;
199201
EncodedCharPtr p = first;
200202

201203
for (;;)
202204
{
205+
EncodedCharPtr prev = p;
203206
switch( this->template ReadFull<false>(p, last) )
204207
{
205208
case kchNWL: // _C_NWL
206209
case kchRET:
207210
case kchLS:
208211
case kchPS:
209212
case kchNUL: // _C_NUL
213+
// p is now advanced past the line terminator character.
214+
// We need to know the number of bytes making up the line, not including the line terminator character.
215+
// To avoid subtracting a variable number of bytes because the line terminator characters are different
216+
// number of bytes long (plus there may be multiple valid encodings for these characters) just keep
217+
// track of the first byte of the line terminator character in prev.
218+
Assert(prev >= first);
219+
*cb = prev - first;
210220
return result;
211221
}
212222
result++;
@@ -2313,10 +2323,11 @@ HRESULT Scanner<EncodingPolicy>::SysAllocErrorLine(int32 ichMinLine, __out BSTR*
23132323
typename EncodingPolicy::EncodedCharPtr pStart = static_cast<size_t>(ichMinLine) == IchMinLine() ? m_pchMinLine : m_pchBase + this->CharacterOffsetToUnitOffset(m_pchBase, m_currentCharacter, m_pchLast, ichMinLine);
23142324

23152325
// Determine the length by scanning for the next newline
2316-
charcount_t cch = LineLength(pStart, m_pchLast);
2326+
size_t cb = 0;
2327+
charcount_t cch = LineLength(pStart, m_pchLast, &cb);
23172328
Assert(cch <= LONG_MAX);
23182329

2319-
typename EncodingPolicy::EncodedCharPtr pEnd = static_cast<size_t>(ichMinLine) == IchMinLine() ? m_pchMinLine + cch : m_pchBase + this->CharacterOffsetToUnitOffset(m_pchBase, m_currentCharacter, m_pchLast, cch);
2330+
typename EncodingPolicy::EncodedCharPtr pEnd = static_cast<size_t>(ichMinLine) == IchMinLine() ? m_pchMinLine + cb : m_pchBase + this->CharacterOffsetToUnitOffset(m_pchBase, m_currentCharacter, m_pchLast, cch);
23202331

23212332
*pbstrLine = SysAllocStringLen(NULL, cch);
23222333
if (!*pbstrLine)

lib/Parser/Scan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ class Scanner : public IScanner, public EncodingPolicy
780780

781781
void ScanNewLine(uint ch);
782782
void NotifyScannedNewLine();
783-
charcount_t LineLength(EncodedCharPtr first, EncodedCharPtr last);
783+
charcount_t LineLength(EncodedCharPtr first, EncodedCharPtr last, size_t* cb);
784784

785785
tokens ScanIdentifier(bool identifyKwds, EncodedCharPtr *pp);
786786
BOOL FastIdentifierContinue(EncodedCharPtr&p, EncodedCharPtr last);

test/Bugs/bug_5585.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
7+
8+
let line = 't("摩"2)';
9+
let module_name = 'temp.js';
10+
WScript.RegisterModuleSource(module_name, line);
11+
12+
var tests = [
13+
{
14+
name: "Syntax error thrown parsing dynamic module",
15+
body: function () {
16+
let source = `import(module_name)
17+
.then(v => {
18+
assert.fail("Parsing this module should not succeed");
19+
}, e => {
20+
assert.areEqual(line, e.source, "Source line causing compile error");
21+
}).catch(e => {
22+
console.log('fail: ' + e);
23+
throw e;
24+
});`
25+
26+
testRunner.LoadModule(source, 'samethread', true, false);
27+
}
28+
},
29+
{
30+
name: "Syntax error thrown parsing module code",
31+
body: function () {
32+
try {
33+
WScript.LoadScriptFile(module_name, 'module');
34+
assert.fail("Parsing this module should not succeed");
35+
} catch(e) {
36+
assert.areEqual(line, e.source, "Source line causing compile error");
37+
}
38+
}
39+
},
40+
{
41+
name: "Error line which contains multi-byte UTF-8 sequence which is an end-of-line character",
42+
body: function () {
43+
WScript.RegisterModuleSource('temp2.js', 't("\u2028"2)');
44+
45+
try {
46+
WScript.LoadScriptFile('temp2.js', 'module');
47+
assert.fail("Parsing this module should not succeed");
48+
} catch(e) {
49+
assert.areEqual('t("', e.source, "Source line causing compile error");
50+
}
51+
}
52+
}
53+
];
54+
55+
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });

test/Bugs/rlexe.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,4 +530,10 @@
530530
<tags>exclude_jshost</tags>
531531
</default>
532532
</test>
533+
<test>
534+
<default>
535+
<files>bug_5585.js</files>
536+
<compile-flags>-esdynamicimport -mutehosterrormsg -args summary -endargs</compile-flags>
537+
</default>
538+
</test>
533539
</regress-exe>

0 commit comments

Comments
 (0)