{"record":{"id":"25e240f6fbdfb123","repo":"NationalSecurityAgency/ghidra","slug":"zero-byte-in-sql-string","errorCode":null,"errorMessage":"Zero byte in SQL string","messagePattern":"Zero byte in SQL string","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java","lineNumber":810,"sourceCode":"\t\telse {\n\t\t\tnewArray = new OptionalTable[1];\n\t\t\tnewArray[0] = table;\n\t\t}\n\t\toptionaltables = newArray;\n\t\treturn table;\n\t}\n\n\t/**\n\t * \n\t * @param buf the string builder object\n\t * @param str the string to parse\n\t * @throws SQLException if there is a zero byte in the string\n\t */\n\tpublic static void appendEscapedLiteral(StringBuilder buf, String str) throws SQLException {\n\t\tfor (int i = 0; i < str.length(); ++i) {\n\t\t\tchar ch = str.charAt(i);\n\t\t\tif (ch == '\\0') {\n\t\t\t\tthrow new SQLException(\"Zero byte in SQL string\");\n\t\t\t}\n\t\t\tif (ch == '\\\\' || ch == '\\'') {\n\t\t\t\tbuf.append(ch);\n\t\t\t}\n\t\t\tbuf.append(ch);\n\t\t}\n\t}\n\n\t/**\n\t * Convert a low-level list of function rows into full FunctionDescription objects\n\t * @param simres (optional -- may be null) generate a SimilarityNote for every function\n\t * @param descvec is the list of low-level function rows\n\t * @param vecres (optional -- may be null) vector result producing these functions\n\t * @param res is the DescriptionManager holding the newly generated FunctionDescriptions\n\t * @param srec (optional -- may be null) is a description object of the vector\n\t * @throws SQLException is there is an error querying tables\n\t * @throws LSHException for internal consistency errors\n\t */","sourceCodeStart":792,"sourceCodeEnd":828,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java#L792-L828","documentation":"`appendEscapedLiteral` walks a string char-by-char to build a safe SQL literal (doubling `\\` and `'`). If it hits a NUL byte (`\\0`) it throws SQLException immediately rather than escaping. NUL bytes can truncate strings in C-based drivers and corrupt SQL parsing, so they are rejected outright.","triggerScenarios":"Inserting or querying with a string field (function name, exe name, metadata) that contains an embedded `\\0`. In Ghidra's reverse-engineering context, malformed or obfuscated binaries can yield symbol names carrying null bytes that leak through to the BSim ingest path.","commonSituations":"Importing analysis from corrupted/obfuscated binaries; binary data accidentally placed in a name field; reading non-UTF-8 or non-null-terminated buffers; symbol tables with embedded nulls.","solutions":["Sanitize the offending string -- strip NUL bytes -- before passing it to BSim insert/query APIs.","Identify which field carries the \\0 (exe name vs function name vs metadata) from the call stack.","Fix the upstream importer if it is emitting null bytes into name fields."],"exampleFix":"// before\nString name = rawFunctionName;            // may contain \\0\n// after\nString name = rawFunctionName.replace(\"\\0\", \"\");","handlingStrategy":"validation","validationCode":"// Reject any string carrying NUL before it reaches appendEscapedLiteral / insert.\nstatic String sanitizeForSql(String s) {\n    if (s == null) return s;\n    if (s.indexOf('\\0') >= 0)\n        throw new IllegalArgumentException(\"NUL byte in value\");\n    return s;\n}","typeGuard":"// isSafeForSqlLiteral: true iff the string can be escaped without error.\nstatic boolean isSafeForSqlLiteral(String s) {\n    return s != null && s.indexOf('\\0') < 0;\n}","tryCatchPattern":"try {\n    db.insert(manager);\n} catch (SQLException e) {\n    if (e.getMessage().equals(\"Zero byte in SQL string\")) {\n        // bad input -- sanitize the offending name and retry, or skip the record\n        throw new BadInputException(\"NUL byte in symbol/exe name\", e);\n    }\n    throw e;\n}","preventionTips":["Sanitize every string sourced from binary analysis before DB write.","Strip or reject control characters (NUL especially) in name fields.","Add a pre-flight assertion on name fields during ingest."],"tags":["input-validation","sql","sanitization","bsim","binary-data"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}