{"record":{"id":"27fe5258c5936cc1","repo":"windmill-labs/windmill","slug":"snprintf-is-not-supported-27fe52","errorCode":null,"errorMessage":"snprintf is not supported","messagePattern":"snprintf is not supported","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-java/src/wasm_libc.rs","lineNumber":201,"sourceCode":"#[no_mangle]\npub unsafe extern \"C\" fn vsnprintf(\n    _buf: *mut c_char,\n    _size: usize,\n    _format: *const c_char,\n    _args: ...\n) -> c_int {\n    panic!(\"vsnprintf is not supported\");\n}\n\n#[no_mangle]\npub extern \"C\" fn clock_gettime(ptr: usize, new_size: usize) {\n    panic!(\"clock_gettime is not supported\");\n}\n\n// int snprintf( char* restrict buffer, size_t bufsz, const char* restrict format, ... );\n#[no_mangle]\npub extern \"C\" fn snprintf() {\n    panic!(\"snprintf is not supported\");\n}\n\n#[no_mangle]\npub extern \"C\" fn __assert_fail(_: *const i32, _: *const i32, _: *const i32, _: *const i32) {\n    panic!(\"oh no\");\n}\n","sourceCodeStart":183,"sourceCodeEnd":208,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-java/src/wasm_libc.rs#L183-L208","documentation":"The windmill-parser-java WASM module (a tree-sitter Java parser compiled to wasm32) ships a hand-written libc shim in wasm_libc.rs. snprintf is deliberately stubbed to panic! because the in-WASM C code has no stdio; the stub exists only so the module links. When the parser's C code calls snprintf at runtime, the stub panics with \"snprintf is not supported\", aborting the parse.","triggerScenarios":"The compiled tree-sitter scanner/parser code calls snprintf() at runtime — typically from a custom scanner.c that formats diagnostic strings or token text. Any grammar whose C runtime or scanner invokes snprintf triggers this stub immediately.","commonSituations":"Parsing a Java source file whose tree-sitter-java scanner path calls snprintf; running the parser inside the WASM sandbox (no real libc); upgrading tree-sitter or the grammar to a version whose generated C uses snprintf when the older version did not.","solutions":["Implement snprintf in wasm_libc.rs instead of panicking — parse the format string minimally (or return the number of chars that would be written and leave the buffer untouched) so the caller proceeds.","Check the tree-sitter-java version and downgrade to one whose generated C/scanner does not call snprintf.","If you control the grammar, patch scanner.c to avoid snprintf (e.g. copy strings directly with memcpy/strcpy, which the shim supports or can trivially implement).","Report the grammar/scanner combination upstream so the Windmill parser WASM build gets a working shim implementation."],"exampleFix":"// before (wasm_libc.rs)\n#[no_mangle]\npub extern \"C\" fn snprintf() {\n    panic!(\"snprintf is not supported\");\n}\n\n// after — minimal no-op that lets callers continue\n#[no_mangle]\npub unsafe extern \"C\" fn snprintf(\n    buf: *mut c_char,\n    _bufsz: usize,\n    _format: *const c_char,\n    _args: ...\n) -> c_int {\n    if !buf.is_null() {\n        *buf = 0; // empty string\n    }\n    0\n}","handlingStrategy":"try-catch","validationCode":"// Nothing caller-side can pre-check the C internals, but you can isolate the blast radius:\n// parse untrusted documents in a fresh parser instance / worker so a panic\ndoes not poison subsequent parses.\nfunction safeParse(parser, doc) {\n  if (typeof doc !== 'string' || doc.length === 0) return null; // skip empty/invalid input\n  return doc; // proceed, but expect the call below to throw on snprintf paths\n}","typeGuard":"function isParsableInput(doc) {\n  return typeof doc === 'string' && doc.length > 0;\n}","tryCatchPattern":"let tree;\ntry {\n  tree = parser.parse(doc);\n} catch (e) {\n  if (String(e).includes('snprintf is not supported')) {\n    // grammar's scanner needs an unsupported libc symbol: recreate parser\n    parser = new Parser(); // discard possibly-corrupted state\n    // fall back to a different parser version or mark doc unparseable\n  } else {\n    throw e;\n  }\n}","preventionTips":["Pin the tree-sitter grammar version tested against the WASM shim set; test upgrades before deploying.","Run each parse of untrusted input in a fresh parser instance so panics don't corrupt shared state.","Fuzz representative Java documents after any grammar or wasm_libc.rs change to catch stub-hitting code paths early.","Prefer implementing the missing libc symbol in the shim over deleting the call path in the grammar."],"tags":["wasm","libc","tree-sitter","unsupported-function"],"backgroundTag":"wasm-libc-stub-panic","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}