Skip to content

Commit fa886ac

Browse files
committed
Ensure incoming TruffleStrings are encoded as UTF-16.
1 parent c8c8aae commit fa886ac

File tree

23 files changed

+141
-151
lines changed

23 files changed

+141
-151
lines changed

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/FunctionPrototypeBuiltins.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.oracle.truffle.api.dsl.Cached.Exclusive;
4848
import com.oracle.truffle.api.dsl.Cached.Shared;
4949
import com.oracle.truffle.api.dsl.Idempotent;
50+
import com.oracle.truffle.api.dsl.ImportStatic;
5051
import com.oracle.truffle.api.dsl.NeverDefault;
5152
import com.oracle.truffle.api.dsl.Specialization;
5253
import com.oracle.truffle.api.interop.InteropLibrary;
@@ -361,6 +362,7 @@ protected static JSDynamicObject bindError(Object thisObj, Object thisArg, Objec
361362
}
362363
}
363364

365+
@ImportStatic(JSConfig.class)
364366
public abstract static class JSFunctionToStringNode extends JSBuiltinNode {
365367

366368
public JSFunctionToStringNode(JSContext context, JSBuiltin builtin) {
@@ -395,28 +397,29 @@ private static TruffleString getNameIntl(TruffleString name) {
395397
@SuppressWarnings("unused")
396398
@Specialization(guards = {"isES2019OrLater()", "!isJSFunction(fnObj)", "isCallable.executeBoolean(fnObj)"}, limit = "1")
397399
protected TruffleString toStringCallable(Object fnObj,
398-
@Cached @Shared("isCallable") IsCallableNode isCallable,
399-
@CachedLibrary("fnObj") InteropLibrary interop) {
400-
if (interop.hasExecutableName(fnObj)) {
401-
try {
402-
Object name = interop.getExecutableName(fnObj);
403-
return getNameIntl(InteropLibrary.getUncached().asTruffleString(name));
404-
} catch (UnsupportedMessageException e) {
400+
@Cached @Shared IsCallableNode isCallable,
401+
@CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
402+
@CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interopStr,
403+
@Cached TruffleString.SwitchEncodingNode switchEncoding) {
404+
try {
405+
Object name = null;
406+
if (interop.hasExecutableName(fnObj)) {
407+
name = interop.getExecutableName(fnObj);
408+
} else if (interop.isMetaObject(fnObj)) {
409+
name = interop.getMetaSimpleName(fnObj);
405410
}
406-
} else if (interop.isMetaObject(fnObj)) {
407-
try {
408-
Object name = interop.getMetaSimpleName(fnObj);
409-
return getNameIntl(InteropLibrary.getUncached().asTruffleString(name));
410-
} catch (UnsupportedMessageException e) {
411+
if (name != null) {
412+
return getNameIntl(Strings.interopAsTruffleString(name, interopStr, switchEncoding));
411413
}
414+
} catch (UnsupportedMessageException e) {
412415
}
413416
return Strings.FUNCTION_NATIVE_CODE;
414417
}
415418

416419
@SuppressWarnings("unused")
417420
@Specialization(guards = {"isES2019OrLater()", "!isCallable.executeBoolean(fnObj)"}, limit = "1")
418421
protected TruffleString toStringNotCallable(Object fnObj,
419-
@Cached @Shared("isCallable") IsCallableNode isCallable) {
422+
@Cached @Shared IsCallableNode isCallable) {
420423
throw Errors.createTypeErrorNotAFunction(fnObj);
421424
}
422425

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/GlobalBuiltins.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,21 +1243,20 @@ public JSGlobalIndirectEvalNode(JSContext context, JSBuiltin builtin) {
12431243
}
12441244

12451245
@Specialization
1246-
protected Object indirectEvalString(TruffleString source) {
1246+
protected Object indirectEvalString(TruffleString source,
1247+
@Cached @Shared TruffleString.ToJavaStringNode toJavaString) {
12471248
JSRealm realm = getRealm();
1248-
return parseIndirectEval(realm, Strings.toJavaString(source)).runEval(callNode, realm);
1249+
return parseIndirectEval(realm, Strings.toJavaString(toJavaString, source)).runEval(callNode, realm);
12491250
}
12501251

12511252
@InliningCutoff
12521253
@Specialization(guards = "isForeignObject(source)", limit = "3")
12531254
protected Object indirectEvalForeignObject(Object source,
1254-
@CachedLibrary("source") InteropLibrary interop) {
1255+
@CachedLibrary("source") InteropLibrary interop,
1256+
@Cached TruffleString.SwitchEncodingNode switchEncoding,
1257+
@Cached @Shared TruffleString.ToJavaStringNode toJavaString) {
12551258
if (interop.isString(source)) {
1256-
try {
1257-
return indirectEvalString(interop.asTruffleString(source));
1258-
} catch (UnsupportedMessageException ex) {
1259-
throw Errors.createTypeErrorInteropException(source, ex, "asString", this);
1260-
}
1259+
return indirectEvalString(Strings.interopAsTruffleString(source, interop, switchEncoding), toJavaString);
12611260
} else {
12621261
return source;
12631262
}
@@ -1311,7 +1310,7 @@ protected BigInt indirectEvalBigInt(BigInt source) {
13111310
return source;
13121311
}
13131312

1314-
@Specialization(guards = "isJSDynamicObject(object)")
1313+
@Specialization
13151314
public JSDynamicObject indirectEvalJSType(JSDynamicObject object) {
13161315
return object;
13171316
}
@@ -1715,7 +1714,7 @@ private void doImport(Object globalContextBindings) {
17151714
Object hashKey = membersInterop.readArrayElement(members, i);
17161715
InteropLibrary keyInterop = InteropLibrary.getUncached(hashKey);
17171716
if (keyInterop.isString(hashKey)) {
1718-
TruffleString stringKey = keyInterop.asTruffleString(hashKey);
1717+
TruffleString stringKey = Strings.interopAsTruffleString(hashKey, keyInterop);
17191718
Object value = DynamicObjectLibrary.getUncached().getOrDefault(globalObject, stringKey, Undefined.instance);
17201719
if ((value == Undefined.instance || value instanceof ScriptEngineGlobalScopeBindingsPropertyProxy &&
17211720
((ScriptEngineGlobalScopeBindingsPropertyProxy) value).get(globalObject) == Undefined.instance) &&

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/JavaBuiltins.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,11 @@ abstract static class JavaTypeNameNode extends JSBuiltinNode {
301301
}
302302

303303
@Specialization(guards = "isJavaInteropClass(type, typeInterop)")
304-
protected TruffleString typeNameJavaInteropClass(Object type,
304+
protected Object typeNameJavaInteropClass(Object type,
305305
@CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary typeInterop,
306-
@CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary stringInterop) {
306+
@Cached ImportValueNode importValue) {
307307
try {
308-
return stringInterop.asTruffleString(typeInterop.getMetaQualifiedName(type));
308+
return importValue.executeWithTarget(typeInterop.getMetaQualifiedName(type));
309309
} catch (UnsupportedMessageException e) {
310310
throw Errors.createTypeErrorInteropException(type, e, "Java.typeName", this);
311311
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/PolyglotBuiltins.java

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ abstract static class PolyglotExportNode extends JSBuiltinNode {
233233

234234
@Specialization
235235
protected Object doString(TruffleString identifier, Object value,
236-
@Shared("interop") @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop) {
236+
@Shared @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop) {
237237
Object polyglotBindings;
238238
try {
239239
polyglotBindings = getRealm().getEnv().getPolyglotBindings();
@@ -247,14 +247,10 @@ protected Object doString(TruffleString identifier, Object value,
247247
@InliningCutoff
248248
@Specialization(guards = {"!isString(identifier)"})
249249
protected Object doMaybeUnbox(TruffleObject identifier, Object value,
250-
@Shared("interop") @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop) {
250+
@Shared @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
251+
@Cached TruffleString.SwitchEncodingNode switchEncoding) {
251252
if (interop.isString(identifier)) {
252-
TruffleString unboxed;
253-
try {
254-
unboxed = interop.asTruffleString(identifier);
255-
} catch (UnsupportedMessageException e) {
256-
throw Errors.createTypeErrorUnboxException(identifier, e, this);
257-
}
253+
TruffleString unboxed = Strings.interopAsTruffleString(identifier, interop, switchEncoding);
258254
return doString(unboxed, value, interop);
259255
}
260256
return doInvalid(identifier, value);
@@ -275,16 +271,17 @@ abstract static class PolyglotImportNode extends JSBuiltinNode {
275271

276272
@Specialization
277273
protected Object doString(TruffleString identifier,
278-
@Shared("interop") @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
279-
@Shared("importValue") @Cached ImportValueNode importValueNode) {
274+
@Shared @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
275+
@Shared @Cached ImportValueNode importValueNode,
276+
@Shared @Cached TruffleString.ToJavaStringNode toJavaStringNode) {
280277
Object polyglotBindings;
281278
try {
282279
polyglotBindings = getRealm().getEnv().getPolyglotBindings();
283280
} catch (SecurityException e) {
284281
throw Errors.createErrorFromException(e);
285282
}
286283
try {
287-
return importValueNode.executeWithTarget(interop.readMember(polyglotBindings, Strings.toJavaString(identifier)));
284+
return importValueNode.executeWithTarget(interop.readMember(polyglotBindings, Strings.toJavaString(toJavaStringNode, identifier)));
288285
} catch (UnknownIdentifierException e) {
289286
return Undefined.instance;
290287
} catch (UnsupportedMessageException e) {
@@ -295,16 +292,13 @@ protected Object doString(TruffleString identifier,
295292
@InliningCutoff
296293
@Specialization(guards = {"!isString(identifier)"})
297294
protected Object doMaybeUnbox(TruffleObject identifier,
298-
@Shared("interop") @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
299-
@Shared("importValue") @Cached ImportValueNode importValueNode) {
295+
@Shared @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
296+
@Shared @Cached ImportValueNode importValueNode,
297+
@Shared @Cached TruffleString.ToJavaStringNode toJavaStringNode,
298+
@Cached TruffleString.SwitchEncodingNode switchEncoding) {
300299
if (interop.isString(identifier)) {
301-
TruffleString unboxed;
302-
try {
303-
unboxed = interop.asTruffleString(identifier);
304-
} catch (UnsupportedMessageException e) {
305-
throw Errors.createTypeErrorUnboxException(identifier, e, this);
306-
}
307-
return doString(unboxed, interop, importValueNode);
300+
TruffleString unboxed = Strings.interopAsTruffleString(identifier, interop, switchEncoding);
301+
return doString(unboxed, interop, importValueNode, toJavaStringNode);
308302
}
309303
return doInvalid(identifier);
310304
}
@@ -450,10 +444,11 @@ protected Object arrayElement(TruffleObject obj, Number index,
450444
protected Object unsupportedKey(TruffleObject obj, Object key,
451445
@Shared("importValue") @Cached ImportValueNode foreignConvert,
452446
@Shared("interop") @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
453-
@Exclusive @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary keyInterop) {
447+
@Exclusive @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary keyInterop,
448+
@Cached TruffleString.SwitchEncodingNode switchEncoding) {
454449
try {
455450
if (keyInterop.isString(key)) {
456-
return member(obj, keyInterop.asTruffleString(key), foreignConvert, interop);
451+
return member(obj, Strings.interopAsTruffleString(key, keyInterop, switchEncoding), foreignConvert, interop);
457452
} else if (keyInterop.fitsInInt(key)) {
458453
return arrayElement(obj, keyInterop.asInt(key), foreignConvert, interop);
459454
}
@@ -530,10 +525,11 @@ protected Object unsupportedKey(TruffleObject obj, Object key, Object value,
530525
@Shared("exportValue") @Cached ExportValueNode exportValue,
531526
@Shared("interop") @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
532527
@Exclusive @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary keyInterop,
533-
@Shared("toJavaString") @Cached TruffleString.ToJavaStringNode toJavaStringNode) {
528+
@Shared("toJavaString") @Cached TruffleString.ToJavaStringNode toJavaStringNode,
529+
@Cached TruffleString.SwitchEncodingNode switchEncoding) {
534530
try {
535531
if (keyInterop.isString(key)) {
536-
return member(obj, keyInterop.asTruffleString(key), value, exportValue, interop, toJavaStringNode);
532+
return member(obj, Strings.interopAsTruffleString(key, keyInterop, switchEncoding), value, exportValue, interop, toJavaStringNode);
537533
} else if (keyInterop.fitsInInt(key)) {
538534
return arrayElement(obj, keyInterop.asInt(key), value, exportValue, interop);
539535
}
@@ -603,10 +599,11 @@ protected boolean arrayElement(TruffleObject obj, Number index,
603599
protected Object unsupportedKey(TruffleObject obj, Object key,
604600
@Shared("interop") @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary interop,
605601
@Exclusive @CachedLibrary(limit = "InteropLibraryLimit") InteropLibrary keyInterop,
606-
@Shared("toJavaString") @Cached TruffleString.ToJavaStringNode toJavaStringNode) {
602+
@Shared("toJavaString") @Cached TruffleString.ToJavaStringNode toJavaStringNode,
603+
@Cached TruffleString.SwitchEncodingNode switchEncoding) {
607604
try {
608605
if (keyInterop.isString(key)) {
609-
return member(obj, keyInterop.asTruffleString(key), interop, toJavaStringNode);
606+
return member(obj, Strings.interopAsTruffleString(key, keyInterop, switchEncoding), interop, toJavaStringNode);
610607
} else if (keyInterop.fitsInInt(key)) {
611608
return arrayElementInt(obj, keyInterop.asInt(key), interop);
612609
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/StringPrototypeBuiltins.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@
6262
import com.oracle.truffle.api.dsl.NeverDefault;
6363
import com.oracle.truffle.api.dsl.Specialization;
6464
import com.oracle.truffle.api.interop.InteropLibrary;
65-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
6665
import com.oracle.truffle.api.library.CachedLibrary;
6766
import com.oracle.truffle.api.nodes.Node;
6867
import com.oracle.truffle.api.profiles.BranchProfile;
@@ -1890,13 +1889,10 @@ protected TruffleString toStringString(JSDynamicObject thisStr) {
18901889
@InliningCutoff
18911890
@Specialization(guards = "isForeignObject(thisObj)", limit = "InteropLibraryLimit")
18921891
protected TruffleString toStringForeignObject(Object thisObj,
1893-
@CachedLibrary("thisObj") InteropLibrary interop) {
1892+
@CachedLibrary("thisObj") InteropLibrary interop,
1893+
@Cached TruffleString.SwitchEncodingNode switchEncoding) {
18941894
if (interop.isString(thisObj)) {
1895-
try {
1896-
return interop.asTruffleString(thisObj);
1897-
} catch (UnsupportedMessageException ex) {
1898-
throw Errors.createTypeErrorUnboxException(thisObj, ex, this);
1899-
}
1895+
return Strings.interopAsTruffleString(thisObj, interop, switchEncoding);
19001896
}
19011897
return toStringOther(thisObj);
19021898
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/helper/JSONStringifyStringNode.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -335,8 +335,7 @@ private void serializeForeignObjectProperties(TruffleStringBuilder sb, JSONData
335335
boolean isFirst = true;
336336
for (long i = 0; i < size; i++) {
337337
Object key = keysInterop.readArrayElement(keysObj, i);
338-
assert InteropLibrary.getUncached().isString(key);
339-
TruffleString stringKey = key instanceof TruffleString ? (TruffleString) key : InteropLibrary.getUncached().asTruffleString(key);
338+
TruffleString stringKey = Strings.interopAsTruffleString(key);
340339
if (!objInterop.isMemberReadable(obj, Strings.toJavaString(stringKey))) {
341340
continue;
342341
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/wasm/WebAssemblyModuleFunctionBuiltins.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -44,7 +44,6 @@
4444
import com.oracle.truffle.api.dsl.Specialization;
4545
import com.oracle.truffle.api.interop.InteropException;
4646
import com.oracle.truffle.api.interop.InteropLibrary;
47-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
4847
import com.oracle.truffle.api.strings.TruffleString;
4948
import com.oracle.truffle.js.builtins.JSBuiltinsContainer;
5049
import com.oracle.truffle.js.builtins.wasm.WebAssemblyModuleFunctionBuiltinsFactory.WebAssemblyModuleCustomSectionsNodeGen;
@@ -263,10 +262,10 @@ protected Object customSectionsOfOther(@SuppressWarnings("unused") Object other,
263262

264263
}
265264

266-
private static TruffleString asTString(Object string) throws UnsupportedMessageException {
265+
private static TruffleString asTString(Object string) {
267266
if (string instanceof String) {
268267
return Strings.fromJavaString((String) string);
269268
}
270-
return InteropLibrary.getUncached(string).asTruffleString(string);
269+
return Strings.interopAsTruffleString(string);
271270
}
272271
}

0 commit comments

Comments
 (0)