quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

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 }