{"record":{"id":"5795ec17e04ab60d","repo":"windmill-labs/windmill","slug":"fputc-is-not-supported-5795ec","errorCode":null,"errorMessage":"fputc is not supported","messagePattern":"fputc is not supported","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-ruby/src/wasm_libc.rs","lineNumber":246,"sourceCode":"pub unsafe extern \"C\" fn isprint(c: c_int) -> bool {\n    c >= 32 && c <= 126\n}\n\n/* --------------------------------- stdio.h -------------------------------- */\n\n#[no_mangle]\npub unsafe extern \"C\" fn fprintf(_file: *mut c_void, _format: *const c_void, _args: ...) -> c_int {\n    panic!(\"fprintf is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fputs(_s: *const c_void, _file: *mut c_void) -> c_int {\n    panic!(\"fputs is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fputc(_c: c_int, _file: *mut c_void) -> c_int {\n    panic!(\"fputc is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fdopen(_fd: c_int, _mode: *const c_void) -> *mut c_void {\n    panic!(\"fdopen is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fclose(_file: *mut c_void) -> c_int {\n    panic!(\"fclose is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fwrite(\n    _ptr: *const c_void,\n    _size: usize,\n    _nmemb: usize,\n    _stream: *mut c_void,","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-ruby/src/wasm_libc.rs#L228-L264","documentation":"fputc is stubbed to panic in the Ruby parser WASM libc shim (wasm_libc.rs:246). Single-character output via C fputc cannot work in the sandbox (no real streams), so the shim only exists to satisfy linking of the compiled Ruby parser. A panic here means the interpreter tried to emit one character to a FILE*.","triggerScenarios":"The embedded Ruby parser calls C fputc — commonly from low-level character output routines in error printing or stream writing during parsing.","commonSituations":"Interpreter diagnostics built on character-at-a-time output; parser builds whose printf machinery falls back to fputc; WASM environments without stdio host imports.","solutions":["Implement fputc to buffer/forward characters to console_log in wasm_libc.rs and rebuild the WASM","Disable or redirect the interpreter's output paths (verbose/warning configuration) so fputc is not called","Upgrade windmill-parser-ruby to a build that no longer panics on fputc","Modify the Ruby input that makes the parser emit output"],"exampleFix":"// before\npub unsafe extern \"C\" fn fputc(_c: c_int, _file: *mut c_void) -> c_int {\n    panic!(\"fputc is not supported\");\n}\n// after\npub unsafe extern \"C\" fn fputc(c: c_int, _file: *mut c_void) -> c_int {\n    console_log!(\"{}\", (c as u8) as char);\n    c\n}","handlingStrategy":"try-catch","validationCode":"// No cheap pre-check exists; validate input shape to reduce diagnostic paths:\nif (typeof rubySource !== 'string' || rubySource.length === 0) {\n  throw new TypeError('rubySource must be a non-empty string');\n}","typeGuard":"function isFputcPanic(e) {\n  return e instanceof Error && e.message.includes('fputc is not supported');\n}","tryCatchPattern":"try {\n  const ast = rubyParser.parse(rubySource);\n} catch (e) {\n  if (isFputcPanic(e)) {\n    console.warn('Ruby parser tried char-level output; skipping input');\n    return null;\n  }\n  throw e;\n}","preventionTips":["Buffer fputc output in the shim and forward to console_log on rebuild","Disable guest output paths that write character-by-character","Track which inputs trigger interpreter printing and exclude them from the parser","Pin parser builds tested against your corpus"],"tags":["wasm","rust","libc","stdio","ruby"],"backgroundTag":"wasm-libc-function-not-supported","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"}