@@ -37,8 +37,6 @@ const Import = 0;
3737const ExportAssign = 1;
3838const ExportStar = 2;
3939
40- const strictReserved = new Set(['implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield', 'enum']);
41-
4240function parseCJS (source, name = '@') {
4341 resetState();
4442 try {
@@ -49,14 +47,39 @@ function parseCJS (source, name = '@') {
4947 e.loc = pos;
5048 throw e;
5149 }
52- const result = { exports: [..._exports].filter(expt => ! unsafeGetters.has(expt)), reexports: [...reexports] };
50+ const result = { exports: [..._exports].filter(expt => expt !== undefined && ! unsafeGetters.has(expt)), reexports: [...reexports].filter(reexpt => reexpt !== undefined) };
5351 resetState();
5452 return result;
5553}
5654
57- function addExport (name) {
58- if (!strictReserved.has(name))
59- _exports.add(name);
55+ function decode (str) {
56+ if (str[0] === '"' || str[0] === '\'') {
57+ try {
58+ const decoded = (0, eval)(str);
59+ // Filter to exclude non-matching UTF-16 surrogate strings
60+ for (let i = 0; i < decoded.length; i++) {
61+ const surrogatePrefix = decoded.charCodeAt(i) & 0xFC00;
62+ if (surrogatePrefix < 0xD800) {
63+ // Not a surrogate
64+ continue;
65+ }
66+ else if (surrogatePrefix === 0xD800) {
67+ // Validate surrogate pair
68+ if ((decoded.charCodeAt(++i) & 0xFC00) !== 0xDC00)
69+ return;
70+ }
71+ else {
72+ // Out-of-range surrogate code (above 0xD800)
73+ return;
74+ }
75+ }
76+ return decoded;
77+ }
78+ catch {}
79+ }
80+ else {
81+ return str;
82+ }
6083}
6184
6285function parseSource (cjsSource) {
@@ -173,10 +196,8 @@ function parseSource (cjsSource) {
173196 // TODO: <!-- XML comment support
174197 break;
175198 case 39/*'*/:
176- singleQuoteString();
177- break;
178199 case 34/*"*/:
179- doubleQuoteString( );
200+ stringLiteral(ch );
180201 break;
181202 case 47/*/*/: {
182203 const next_ch = source.charCodeAt(pos + 1);
@@ -329,11 +350,9 @@ function tryParseObjectDefineOrKeys (keys) {
329350 pos++;
330351 ch = commentWhitespace();
331352 if (ch !== 39/*'*/ && ch !== 34/*"*/) break;
332- let quot = ch;
333- const exportPos = ++pos;
334- if (!identifier() || source.charCodeAt(pos) !== quot) break;
335- expt = source.slice(exportPos, pos);
336- pos++;
353+ const exportPos = pos;
354+ stringLiteral(ch);
355+ expt = source.slice(exportPos, ++pos);
337356 ch = commentWhitespace();
338357 if (ch !== 44/*,*/) break;
339358 pos++;
@@ -360,7 +379,7 @@ function tryParseObjectDefineOrKeys (keys) {
360379 pos += 5;
361380 ch = commentWhitespace();
362381 if (ch !== 58/*:*/) break;
363- addExport( expt);
382+ _exports.add(decode( expt) );
364383 pos = revertPos;
365384 return;
366385 }
@@ -403,8 +422,7 @@ function tryParseObjectDefineOrKeys (keys) {
403422 else if (ch === 91/*[*/) {
404423 pos++;
405424 ch = commentWhitespace();
406- if (ch === 39/*'*/) singleQuoteString();
407- else if (ch === 34/*"*/) doubleQuoteString();
425+ if (ch === 39/*'*/ || ch === 34/*"*/) stringLiteral(ch);
408426 else break;
409427 pos++;
410428 ch = commentWhitespace();
@@ -427,13 +445,13 @@ function tryParseObjectDefineOrKeys (keys) {
427445 pos++;
428446 ch = commentWhitespace();
429447 if (ch !== 41/*)*/) break;
430- addExport( expt);
448+ _exports.add(decode( expt) );
431449 return;
432450 }
433451 break;
434452 }
435453 if (expt) {
436- unsafeGetters.add(expt);
454+ unsafeGetters.add(decode( expt) );
437455 }
438456 }
439457 else if (keys && ch === 107/*k*/ && source.startsWith('eys', pos + 1)) {
@@ -801,7 +819,7 @@ function tryParseObjectDefineOrKeys (keys) {
801819
802820 const starExportSpecifier = starExportMap[id];
803821 if (starExportSpecifier) {
804- reexports.add(starExportSpecifier);
822+ reexports.add(decode( starExportSpecifier) );
805823 pos = revertPos;
806824 return;
807825 }
@@ -863,7 +881,7 @@ function tryParseExportsDotAssign (assign) {
863881 const endPos = pos;
864882 ch = commentWhitespace();
865883 if (ch === 61/*=*/) {
866- addExport( source.slice(startPos, endPos));
884+ _exports.add(decode( source.slice(startPos, endPos) ));
867885 return;
868886 }
869887 }
@@ -874,19 +892,15 @@ function tryParseExportsDotAssign (assign) {
874892 pos++;
875893 ch = commentWhitespace();
876894 if (ch === 39/*'*/ || ch === 34/*"*/) {
877- pos++;
878895 const startPos = pos;
879- if (identifier() && source.charCodeAt(pos) === ch) {
880- const endPos = pos++;
881- ch = commentWhitespace();
882- if (ch !== 93/*]*/)
883- break;
884- pos++;
885- ch = commentWhitespace();
886- if (ch !== 61/*=*/)
887- break;
888- addExport(source.slice(startPos, endPos));
889- }
896+ stringLiteral(ch);
897+ const endPos = ++pos;
898+ ch = commentWhitespace();
899+ if (ch !== 93/*]*/) break;
900+ pos++;
901+ ch = commentWhitespace();
902+ if (ch !== 61/*=*/) break;
903+ _exports.add(decode(source.slice(startPos, endPos)));
890904 }
891905 break;
892906 }
@@ -921,39 +935,21 @@ function tryParseRequire (requireType) {
921935 if (ch === 40/*(*/) {
922936 pos++;
923937 ch = commentWhitespace();
924- const reexportStart = pos + 1;
925- if (ch === 39/*'*/) {
926- singleQuoteString();
927- const reexportEnd = pos++;
928- ch = commentWhitespace();
929- if (ch === 41/*)*/) {
930- switch (requireType) {
931- case ExportAssign:
932- reexports.add(source.slice(reexportStart, reexportEnd));
933- return true;
934- case ExportStar:
935- reexports.add(source.slice(reexportStart, reexportEnd));
936- return true;
937- default:
938- lastStarExportSpecifier = source.slice(reexportStart, reexportEnd);
939- return true;
940- }
941- }
942- }
943- else if (ch === 34/*"*/) {
944- doubleQuoteString();
945- const reexportEnd = pos++;
938+ const reexportStart = pos;
939+ if (ch === 39/*'*/ || ch === 34/*"*/) {
940+ stringLiteral(ch);
941+ const reexportEnd = ++pos;
946942 ch = commentWhitespace();
947943 if (ch === 41/*)*/) {
948944 switch (requireType) {
949945 case ExportAssign:
950- reexports.add(source.slice(reexportStart, reexportEnd));
946+ reexports.add(decode( source.slice(reexportStart, reexportEnd) ));
951947 return true;
952948 case ExportStar:
953- reexports.add(source.slice(reexportStart, reexportEnd));
949+ reexports.add(decode( source.slice(reexportStart, reexportEnd) ));
954950 return true;
955951 default:
956- lastStarExportSpecifier = source.slice(reexportStart, reexportEnd);
952+ lastStarExportSpecifier = decode( source.slice(reexportStart, reexportEnd) );
957953 return true;
958954 }
959955 }
@@ -982,7 +978,7 @@ function tryParseLiteralExports () {
982978 }
983979 ch = source.charCodeAt(pos);
984980 }
985- addExport( source.slice(startPos, endPos));
981+ _exports.add(decode( source.slice(startPos, endPos) ));
986982 }
987983 else if (ch === 46/*.*/ && source.startsWith('..', pos + 1)) {
988984 pos += 3;
@@ -996,21 +992,20 @@ function tryParseLiteralExports () {
996992 ch = commentWhitespace();
997993 }
998994 else if (ch === 39/*'*/ || ch === 34/*"*/) {
999- const startPos = ++pos;
1000- if (identifier() && source.charCodeAt(pos) === ch) {
1001- const endPos = pos++;
995+ const startPos = pos;
996+ stringLiteral(ch);
997+ const endPos = ++pos;
998+ ch = commentWhitespace();
999+ if (ch === 58/*:*/) {
1000+ pos++;
10021001 ch = commentWhitespace();
1003- if (ch === 58/*:*/) {
1004- pos++;
1005- ch = commentWhitespace();
1006- // nothing more complex than identifier expressions for now
1007- if (!identifier()) {
1008- pos = revertPos;
1009- return;
1010- }
1011- ch = source.charCodeAt(pos);
1012- addExport(source.slice(startPos, endPos));
1002+ // nothing more complex than identifier expressions for now
1003+ if (!identifier()) {
1004+ pos = revertPos;
1005+ return;
10131006 }
1007+ ch = source.charCodeAt(pos);
1008+ _exports.add(decode(source.slice(startPos, endPos)));
10141009 }
10151010 }
10161011 else {
@@ -1248,26 +1243,10 @@ function lineComment () {
12481243 }
12491244}
12501245
1251- function singleQuoteString () {
1252- while (pos++ < end) {
1253- let ch = source.charCodeAt(pos);
1254- if (ch === 39/*'*/)
1255- return;
1256- if (ch === 92/*\*/) {
1257- ch = source.charCodeAt(++pos);
1258- if (ch === 13/*\r*/ && source.charCodeAt(pos + 1) === 10/*\n*/)
1259- pos++;
1260- }
1261- else if (isBr(ch))
1262- break;
1263- }
1264- throw new Error('Unterminated string.');
1265- }
1266-
1267- function doubleQuoteString () {
1246+ function stringLiteral (quote) {
12681247 while (pos++ < end) {
12691248 let ch = source.charCodeAt(pos);
1270- if (ch === 34/*"*/ )
1249+ if (ch === quote )
12711250 return;
12721251 if (ch === 92/*\*/) {
12731252 ch = source.charCodeAt(++pos);
0 commit comments