Skip to content

Commit 099943b

Browse files
Vary compiler flags in fuzz_pycompile (python#145236)
* Vary compiler flags in fuzz_pycompile * Drop `PyCF_SOURCE_IS_UTF8`
1 parent 0b65c88 commit 099943b

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

Modules/_xxtestfuzz/fuzzer.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -517,8 +517,8 @@ static int fuzz_pycompile(const char* data, size_t size) {
517517
return 0;
518518
}
519519

520-
// Need 2 bytes for parameter selection
521-
if (size < 2) {
520+
// Need 3 bytes for parameter selection
521+
if (size < 3) {
522522
return 0;
523523
}
524524

@@ -530,25 +530,39 @@ static int fuzz_pycompile(const char* data, size_t size) {
530530
unsigned char optimize_idx = (unsigned char) data[1];
531531
int optimize = optimize_vals[optimize_idx % NUM_OPTIMIZE_VALS];
532532

533+
// Use third byte to determine compiler flags to use.
534+
unsigned char flags_byte = (unsigned char) data[2];
535+
PyCompilerFlags flags = _PyCompilerFlags_INIT;
536+
if (flags_byte & 0x01) {
537+
flags.cf_flags |= PyCF_DONT_IMPLY_DEDENT;
538+
}
539+
if (flags_byte & 0x02) {
540+
flags.cf_flags |= PyCF_ONLY_AST;
541+
}
542+
if (flags_byte & 0x04) {
543+
flags.cf_flags |= PyCF_IGNORE_COOKIE;
544+
}
545+
if (flags_byte & 0x08) {
546+
flags.cf_flags |= PyCF_TYPE_COMMENTS;
547+
}
548+
if (flags_byte & 0x10) {
549+
flags.cf_flags |= PyCF_ALLOW_TOP_LEVEL_AWAIT;
550+
}
551+
if (flags_byte & 0x20) {
552+
flags.cf_flags |= PyCF_ALLOW_INCOMPLETE_INPUT;
553+
}
554+
if (flags_byte & 0x40) {
555+
flags.cf_flags |= PyCF_OPTIMIZED_AST;
556+
}
557+
533558
char pycompile_scratch[MAX_PYCOMPILE_TEST_SIZE];
534559

535560
// Create a NUL-terminated C string from the remaining input
536-
memcpy(pycompile_scratch, data + 2, size - 2);
561+
memcpy(pycompile_scratch, data + 3, size - 3);
537562
// Put a NUL terminator just after the copied data. (Space was reserved already.)
538-
pycompile_scratch[size - 2] = '\0';
539-
540-
// XXX: instead of always using NULL for the `flags` value to
541-
// `Py_CompileStringExFlags`, there are many flags that conditionally
542-
// change parser behavior:
543-
//
544-
// #define PyCF_TYPE_COMMENTS 0x1000
545-
// #define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000
546-
// #define PyCF_ONLY_AST 0x0400
547-
//
548-
// It would be good to test various combinations of these, too.
549-
PyCompilerFlags *flags = NULL;
550-
551-
PyObject *result = Py_CompileStringExFlags(pycompile_scratch, "<fuzz input>", start, flags, optimize);
563+
pycompile_scratch[size - 3] = '\0';
564+
565+
PyObject *result = Py_CompileStringExFlags(pycompile_scratch, "<fuzz input>", start, &flags, optimize);
552566
if (result == NULL) {
553567
/* Compilation failed, most likely from a syntax error. If it was a
554568
SystemError we abort. There's no non-bug reason to raise a

0 commit comments

Comments
 (0)