{"record":{"id":"79af6e1aa85a150c","repo":"NationalSecurityAgency/ghidra","slug":"bad-characters-in-proposed-function-tag","errorCode":null,"errorMessage":"Bad characters in proposed function tag","messagePattern":"Bad characters in proposed function tag","errorType":"validation","errorClass":"LSHException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java","lineNumber":2227,"sourceCode":"\t/**\n\t * Returns a list of all function tags in the database.\n\t * \n\t * @return list of function tags\n\t */\n\tpublic List<String> getFunctionTags() {\n\t\treturn info.functionTags;\n\t}\n\n\t/**\n\t * Entry point for the InstallTagRequest command\n\t * @param query the install query to execute\n\t * @throws LSHException if the function tag already exists or is not valid\n\t * @throws SQLException if there is an error issuing the query\n\t */\n\tprivate void fdbInstallTag(InstallTagRequest query) throws LSHException, SQLException {\n\t\tResponseInfo response = query.installresponse;\n\t\tif (!CategoryRecord.enforceTypeCharacters(query.tag_name)) {\n\t\t\tthrow new LSHException(\"Bad characters in proposed function tag\");\n\t\t}\n\t\t// Check for existing tag\n\t\tif (info.functionTags != null) {\n\t\t\tif (info.functionTags.contains(query.tag_name)) {\n\t\t\t\tthrow new LSHException(\"Function tag already exists\");\n\t\t\t}\n\t\t}\n\t\tif (info.functionTags == null) {\n\t\t\tinfo.functionTags = new ArrayList<>();\n\t\t}\n\t\t// There are only 32-bits of space in the function record reserved for storing the presence of tags\n\t\tif (info.functionTags.size() >= FunctionTagBSimFilterType.MAX_TAG_COUNT) {\n\t\t\tthrow new LSHException(\n\t\t\t\t\"Cannot allocate new function tag: \" + query.tag_name + \" - Column space is full\");\n\t\t}\n\t\tinfo.functionTags.add(query.tag_name);\n\t\tkeyValueTable.writeFunctionTags(info);\n\t\tresponse.info = info;","sourceCodeStart":2209,"sourceCodeEnd":2245,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java#L2209-L2245","documentation":"Thrown by fdbInstallTag when query.tag_name fails CategoryRecord.enforceTypeCharacters. Function tag names become bitmask column identifiers, so they must contain only letters, digits, space, '.', '_', ':', '/', '(', ')'. Null or empty names also fail.","triggerScenarios":"Issuing an InstallTagRequest with a tag_name containing disallowed characters or that is null/empty.","commonSituations":"Importing tags from external systems with punctuation; user-entered tag names with hyphens or special symbols; programmatic tag generation producing reserved characters.","solutions":["Validate tag_name with CategoryRecord.enforceTypeCharacters before submitting.","Sanitize by replacing disallowed characters with allowed alternatives.","Reject null/empty tag names early."],"exampleFix":"// before\nreq.tag_name = \"my@tag\";\n// after\nif (!CategoryRecord.enforceTypeCharacters(req.tag_name)) {\n    req.tag_name = req.tag_name.replaceAll(\"[^\\\\w. :/()]\", \"_\");\n}","handlingStrategy":"validation","validationCode":"if (!CategoryRecord.enforceTypeCharacters(req.tag_name)) {\n    throw new IllegalArgumentException(\"Invalid tag name: \" + req.tag_name);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate tag names with enforceTypeCharacters at the data-entry point.","Prefer underscore over hyphen in machine-generated tag names."],"tags":["bsim","validation","input-sanitization"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}