Skip to content

Commit ecf9ef5

Browse files
committed
[GR-53542] Make sure we convert unexpected Java types before they reach the Python object space.
PullRequest: graalpython/3298
2 parents 44adb2b + 08668ae commit ecf9ef5

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

graalpython/com.oracle.graal.python.test.integration/src/com/oracle/graal/python/test/integration/interop/JavaInteropTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,28 @@ public void evalInteractiveInInteractiveTerminalThrowsSyntaxError() throws IOExc
161161
fail();
162162
}
163163

164+
@Test
165+
public void importingJavaLangStringConvertsEagerly() {
166+
try (Context c = Context.newBuilder().allowExperimentalOptions(true).allowAllAccess(true).build()) {
167+
c.getPolyglotBindings().putMember("b", "hello world");
168+
c.eval("python", "import polyglot; xyz = polyglot.import_value('b'); assert isinstance(xyz, str)");
169+
// should not fail
170+
}
171+
}
172+
173+
@Test
174+
public void evalWithSyntaxErrorThrows() {
175+
try (Context c = Context.newBuilder().build()) {
176+
c.eval("python", "var d=5/0");
177+
} catch (PolyglotException t) {
178+
assertTrue(t.isSyntaxError());
179+
assertFalse(t.isIncompleteSource());
180+
return;
181+
}
182+
183+
fail();
184+
}
185+
164186
@Test
165187
public void truffleMethodExport() {
166188
String source = "import polyglot\n" +

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
115115
import com.oracle.graal.python.nodes.interop.InteropBehavior;
116116
import com.oracle.graal.python.nodes.interop.InteropBehaviorMethod;
117+
import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
117118
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
118119
import com.oracle.graal.python.nodes.util.CannotCastException;
119120
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
@@ -196,7 +197,8 @@ public void initialize(Python3Core core) {
196197
public abstract static class ImportNode extends PythonBuiltinNode {
197198
@Specialization
198199
@TruffleBoundary
199-
Object importSymbol(TruffleString name) {
200+
Object importSymbol(TruffleString name,
201+
@Cached PForeignToPTypeNode convert) {
200202
Env env = getContext().getEnv();
201203
if (!env.isPolyglotBindingsAccessAllowed()) {
202204
throw PRaiseNode.raiseUncached(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED);
@@ -205,7 +207,7 @@ Object importSymbol(TruffleString name) {
205207
if (object == null) {
206208
return PNone.NONE;
207209
}
208-
return object;
210+
return convert.executeConvert(object);
209211
}
210212
}
211213

@@ -214,7 +216,8 @@ Object importSymbol(TruffleString name) {
214216
abstract static class EvalInteropNode extends PythonBuiltinNode {
215217
@TruffleBoundary
216218
@Specialization
217-
Object evalString(@SuppressWarnings("unused") PNone path, TruffleString tvalue, TruffleString tlangOrMimeType) {
219+
Object evalString(@SuppressWarnings("unused") PNone path, TruffleString tvalue, TruffleString tlangOrMimeType,
220+
@Shared @Cached PForeignToPTypeNode convert) {
218221
Env env = getContext().getEnv();
219222
if (!env.isPolyglotEvalAllowed()) {
220223
throw PRaiseNode.raiseUncached(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED);
@@ -229,7 +232,7 @@ Object evalString(@SuppressWarnings("unused") PNone path, TruffleString tvalue,
229232
if (mimeType) {
230233
newBuilder = newBuilder.mimeType(langOrMimeType);
231234
}
232-
return env.parsePublic(newBuilder.build()).call();
235+
return convert.executeConvert(env.parsePublic(newBuilder.build()).call());
233236
} catch (RuntimeException e) {
234237
throw PRaiseNode.raiseUncached(this, NotImplementedError, e);
235238
}
@@ -244,7 +247,8 @@ private void raiseIfInternal(Env env, String lang) {
244247

245248
@TruffleBoundary
246249
@Specialization
247-
Object evalFile(TruffleString tpath, @SuppressWarnings("unused") PNone string, TruffleString tlangOrMimeType) {
250+
Object evalFile(TruffleString tpath, @SuppressWarnings("unused") PNone string, TruffleString tlangOrMimeType,
251+
@Shared @Cached PForeignToPTypeNode convert) {
248252
Env env = getContext().getEnv();
249253
if (!env.isPolyglotEvalAllowed()) {
250254
throw PRaiseNode.raiseUncached(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED);
@@ -259,7 +263,7 @@ Object evalFile(TruffleString tpath, @SuppressWarnings("unused") PNone string, T
259263
if (mimeType) {
260264
newBuilder = newBuilder.mimeType(langOrMimeType);
261265
}
262-
return getContext().getEnv().parsePublic(newBuilder.name(path).build()).call();
266+
return convert.executeConvert(getContext().getEnv().parsePublic(newBuilder.name(path).build()).call());
263267
} catch (IOException e) {
264268
throw PRaiseNode.raiseUncached(this, OSError, ErrorMessages.S, e);
265269
} catch (RuntimeException e) {
@@ -269,14 +273,15 @@ Object evalFile(TruffleString tpath, @SuppressWarnings("unused") PNone string, T
269273

270274
@TruffleBoundary
271275
@Specialization
272-
Object evalFile(TruffleString tpath, @SuppressWarnings("unused") PNone string, @SuppressWarnings("unused") PNone lang) {
276+
Object evalFile(TruffleString tpath, @SuppressWarnings("unused") PNone string, @SuppressWarnings("unused") PNone lang,
277+
@Shared @Cached PForeignToPTypeNode convert) {
273278
Env env = getContext().getEnv();
274279
if (!env.isPolyglotEvalAllowed()) {
275280
throw PRaiseNode.raiseUncached(this, PythonErrorType.NotImplementedError, ErrorMessages.POLYGLOT_ACCESS_NOT_ALLOWED);
276281
}
277282
try {
278283
String path = tpath.toJavaStringUncached();
279-
return getContext().getEnv().parsePublic(Source.newBuilder(PythonLanguage.ID, env.getPublicTruffleFile(path)).name(path).build()).call();
284+
return convert.executeConvert(getContext().getEnv().parsePublic(Source.newBuilder(PythonLanguage.ID, env.getPublicTruffleFile(path)).name(path).build()).call());
280285
} catch (IOException e) {
281286
throw PRaiseNode.raiseUncached(this, OSError, ErrorMessages.S, e);
282287
} catch (RuntimeException e) {

0 commit comments

Comments
 (0)