Skip to content

Commit 3524552

Browse files
committed
check for proper kwFlag, kwOptimize and source values in compile()
1 parent 4cf9e55 commit 3524552

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

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

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
161161
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
162162
import com.oracle.graal.python.nodes.util.CannotCastException;
163+
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
163164
import com.oracle.graal.python.nodes.util.CastToJavaLongExactNode;
164165
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
165166
import com.oracle.graal.python.runtime.PythonContext;
@@ -740,6 +741,28 @@ protected boolean shouldStripLeadingWhitespace() {
740741
@GenerateNodeFactory
741742
@TypeSystemReference(PythonArithmeticTypes.class)
742743
public abstract static class CompileNode extends PythonBuiltinNode {
744+
745+
// code.h
746+
private static final int CO_NESTED = 0x0010;
747+
private static final int CO_FUTURE_DIVISION = 0x20000;
748+
private static final int CO_FUTURE_ABSOLUTE_IMPORT = 0x40000;
749+
private static final int CO_FUTURE_WITH_STATEMENT = 0x80000;
750+
private static final int CO_FUTURE_PRINT_FUNCTION = 0x100000;
751+
private static final int CO_FUTURE_UNICODE_LITERALS = 0x200000;
752+
753+
private static final int CO_FUTURE_BARRY_AS_BDFL = 0x400000;
754+
private static final int CO_FUTURE_GENERATOR_STOP = 0x800000;
755+
private static final int CO_FUTURE_ANNOTATIONS = 0x1000000;
756+
757+
// compile.h
758+
private static final int PyCF_MASK = CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | CO_FUTURE_UNICODE_LITERALS |
759+
CO_FUTURE_BARRY_AS_BDFL | CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS;
760+
private static final int PyCF_MASK_OBSOLETE = CO_NESTED;
761+
762+
private static final int PyCF_DONT_IMPLY_DEDENT = 0x0200;
763+
private static final int PyCF_ONLY_AST = 0x0400;
764+
private static final int PyCF_TYPE_COMMENTS = 0x1000;
765+
743766
/**
744767
* Decides wether this node should attempt to map the filename to a URI for the benefit of
745768
* Truffle tooling
@@ -762,7 +785,7 @@ public CompileNode() {
762785
@SuppressWarnings("unused")
763786
@Specialization
764787
@TruffleBoundary
765-
PCode compile(String expression, String filename, String mode, Object kwFlags, Object kwDontInherit, Object kwOptimize) {
788+
PCode compile(String expression, String filename, String mode, int kwFlags, Object kwDontInherit, int kwOptimize) {
766789
String code = expression;
767790
PythonContext context = getContext();
768791
ParserMode pm;
@@ -800,6 +823,7 @@ PCode compile(String expression, String filename, String mode, Object kwFlags, O
800823
@Specialization(limit = "3")
801824
PCode generic(VirtualFrame frame, Object wSource, Object wFilename, Object wMode, Object kwFlags, Object kwDontInherit, Object kwOptimize,
802825
@Cached CastToJavaStringNode castStr,
826+
@Cached CastToJavaIntExactNode castInt,
803827
@Cached CodecsModuleBuiltins.HandleDecodingErrorNode handleDecodingErrorNode,
804828
@CachedLibrary("wSource") InteropLibrary interopLib,
805829
@CachedLibrary(limit = "4") PythonObjectLibrary lib) {
@@ -813,8 +837,33 @@ PCode generic(VirtualFrame frame, Object wSource, Object wFilename, Object wMode
813837
} catch (CannotCastException e) {
814838
throw raise(TypeError, ErrorMessages.ARG_S_MUST_BE_S_NOT_P, "compile()", "mode", "str", wMode);
815839
}
840+
int flags = 0;
841+
if (kwFlags != PNone.NO_VALUE) {
842+
try {
843+
flags = castInt.execute(kwFlags);
844+
} catch (CannotCastException e) {
845+
throw raise(TypeError, ErrorMessages.INTEGER_REQUIRED_GOT, kwFlags);
846+
}
847+
if ((flags & ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST | PyCF_TYPE_COMMENTS)) > 0) {
848+
throw raise(ValueError, "compile(): unrecognised flags");
849+
}
850+
}
851+
int optimize = 0;
852+
if (kwOptimize != PNone.NO_VALUE) {
853+
try {
854+
optimize = castInt.execute(kwOptimize);
855+
} catch (CannotCastException e) {
856+
throw raise(TypeError, ErrorMessages.INTEGER_REQUIRED_GOT, kwFlags);
857+
}
858+
if (optimize < -1 || optimize > 2) {
859+
throw raise(TypeError, "compile(): invalid optimize value", kwOptimize);
860+
}
861+
}
816862
String source = sourceAsString(wSource, filename, interopLib, lib, handleDecodingErrorNode);
817-
return compile(source, filename, mode, kwFlags, kwDontInherit, kwOptimize);
863+
if (source.indexOf(0) > -1) {
864+
throw raise(ValueError, "source code string cannot contain null bytes");
865+
}
866+
return compile(source, filename, mode, flags, kwDontInherit, optimize);
818867
}
819868

820869
// modeled after _Py_SourceAsString

0 commit comments

Comments
 (0)