@@ -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