Skip to content

Commit 702aa3f

Browse files
Vary compiler flags in fuzz_pycompile
1 parent 7eb00ad commit 702aa3f

1 file changed

Lines changed: 34 additions & 17 deletions

File tree

Modules/_xxtestfuzz/fuzzer.c

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

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

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

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

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

0 commit comments

Comments
 (0)