fuzz_module_export.c (3046B)
1 // Copyright 2025 Google LLC 2 // Fuzz target for QuickJS ES6 module parsing 3 4 #include "quickjs.h" 5 #include <stdint.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <stdio.h> 9 10 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 11 if (size < 1) return 0; 12 13 JSRuntime* rt = JS_NewRuntime(); 14 if (!rt) return 0; 15 16 JSContext* ctx = JS_NewContext(rt); 17 if (!ctx) { 18 JS_FreeRuntime(rt); 19 return 0; 20 } 21 22 char* input = malloc(size + 1); 23 if (!input) { 24 JS_FreeContext(ctx); 25 JS_FreeRuntime(rt); 26 return 0; 27 } 28 memcpy(input, data, size); 29 input[size] = '\0'; 30 31 const char* export_patterns[] = { 32 "export default %s;", 33 "export const x = %s;", 34 "export let x = %s;", 35 "export var x = %s;", 36 "export function f() { %s }", 37 "export class C { %s }", 38 "export { %s };", 39 "export * from '%s';", 40 "export { %s } from 'module';", 41 "export { default as x } from '%s';", 42 }; 43 44 int pattern_idx = data[0] % (sizeof(export_patterns) / sizeof(export_patterns[0])); 45 46 char script[8192]; 47 snprintf(script, sizeof(script), export_patterns[pattern_idx], input); 48 49 JSValue result = JS_Eval(ctx, script, strlen(script), "<input>", 50 JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY); 51 52 if (!JS_IsException(result)) { 53 JS_FreeValue(ctx, result); 54 } else { 55 JS_GetException(ctx); 56 } 57 58 JSValue result2 = JS_Eval(ctx, input, size, "<input>", JS_EVAL_FLAG_COMPILE_ONLY); 59 if (!JS_IsException(result2)) { 60 JS_FreeValue(ctx, result2); 61 } else { 62 JS_GetException(ctx); 63 } 64 65 const char* import_patterns[] = { 66 "import '%s';", 67 "import x from '%s';", 68 "import * as x from '%s';", 69 "import { x } from '%s';", 70 "import { x as y } from '%s';", 71 "import x, { y } from '%s';", 72 "import x, * as y from '%s';", 73 }; 74 75 int import_idx = (data[0] >> 4) % (sizeof(import_patterns) / sizeof(import_patterns[0])); 76 char import_script[8192]; 77 char* sanitized = malloc(size + 1); 78 if (sanitized) { 79 size_t j = 0; 80 for (size_t i = 0; i < size && j < size; i++) { 81 if (data[i] != '\'' && data[i] != '"' && data[i] != '\n' && data[i] != '\r') { 82 sanitized[j++] = data[i]; 83 } 84 } 85 sanitized[j] = '\0'; 86 87 snprintf(import_script, sizeof(import_script), import_patterns[import_idx], sanitized); 88 89 JSValue import_result = JS_Eval(ctx, import_script, strlen(import_script), "<input>", 90 JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY); 91 if (!JS_IsException(import_result)) { 92 JS_FreeValue(ctx, import_result); 93 } else { 94 JS_GetException(ctx); 95 } 96 97 free(sanitized); 98 } 99 100 free(input); 101 JS_FreeContext(ctx); 102 JS_FreeRuntime(rt); 103 104 return 0; 105 }