NationalSecurityAgency/ghidra · error · IOException
Bad characters in requested category type
Error message
Bad characters in requested category type
What it means
Thrown by InstallCategoryRequest.saveXml when the type_name contains characters not permitted by CategoryRecord.enforceTypeCharacters. The allowed character set is: letters, digits, spaces, periods, underscores, colons, forward slashes, and parentheses. An empty or null type_name also fails. This validation prevents SQL injection and XML corruption when the category type name is used in database queries and XML serialization.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/protocol/InstallCategoryRequest.java:53
public boolean isdatecolumn; // True if name should be treated as new name for date column
public ResponseInfo installresponse;
public InstallCategoryRequest() {
super("installcategory");
type_name = "";
isdatecolumn = false;
}
@Override
public void buildResponseTemplate() {
if (response == null)
response = installresponse = new ResponseInfo();
}
@Override
public void saveXml(Writer fwrite) throws IOException {
if (!CategoryRecord.enforceTypeCharacters(type_name))
throw new IOException("Bad characters in requested category type");
fwrite.append('<').append(name);
if (isdatecolumn)
fwrite.append(" datecolumn=\"true\"");
fwrite.append('>');
fwrite.append(type_name);
fwrite.append("</").append(name).append(">\n");
}
@Override
public void restoreXml(XmlPullParser parser, LSHVectorFactory vectorFactory) throws LSHException {
XmlElement el = parser.start(name);
isdatecolumn = XmlUtilities.parseBoolean(el.getAttribute("datecolumn"));
type_name = parser.end().getText();
}
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Sanitize the type_name to contain only letters, digits, spaces, periods, underscores, colons, slashes, and parentheses before calling saveXml.
- Replace disallowed characters (e.g., hyphens to underscores) as a preprocessing step.
- Validate with CategoryRecord.enforceTypeCharacters(type_name) before serialization and fail early with a clear message.
- If the category name comes from external input, validate it at the boundary before constructing the request.
Example fix
// before
public void saveXml(Writer fwrite) throws IOException {
if (!CategoryRecord.enforceTypeCharacters(type_name))
throw new IOException("Bad characters in requested category type");
...
}
// caller fix — sanitize before sending
// before:
// req.type_name = "my-category; DROP";
// req.saveXml(writer);
// after:
// String sanitized = req.type_name.replaceAll("[^a-zA-Z0-9 ._:()/]", "_");
// if (!CategoryRecord.enforceTypeCharacters(sanitized)) {
// throw new IllegalArgumentException("Invalid category name: " + req.type_name);
// }
// req.type_name = sanitized;
// req.saveXml(writer); Defensive patterns
Strategy: validation
Validate before calling
// Validate the category type name before serialization
public static String sanitizeCategoryType(String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Category type name must not be null or empty");
}
if (!CategoryRecord.enforceTypeCharacters(name)) {
// Replace disallowed characters with underscores
String sanitized = name.replaceAll("[^a-zA-Z0-9 ._:()/]", "_");
if (!CategoryRecord.enforceTypeCharacters(sanitized)) {
throw new IllegalArgumentException(
"Category type name contains invalid characters even after sanitization: " + name);
}
return sanitized;
}
return name;
}
// Usage:
req.type_name = sanitizeCategoryType(userInput);
req.saveXml(writer); Type guard
public static boolean isValidCategoryType(String name) {
return CategoryRecord.enforceTypeCharacters(name);
}
// Allowed characters: letters, digits, space, period, underscore,
// colon, forward slash, parentheses Try / catch
try {
req.saveXml(writer);
} catch (IOException e) {
if (e.getMessage().contains("Bad characters")) {
// Sanitize and retry
req.type_name = req.type_name.replaceAll("[^a-zA-Z0-9 ._:()/]", "_");
req.saveXml(writer);
} else {
throw e;
}
} Prevention
- Always validate type_name with CategoryRecord.enforceTypeCharacters before calling saveXml.
- Sanitize user-supplied category names by replacing disallowed characters with underscores.
- Remember the allowed set: letters, digits, spaces, periods, underscores, colons, slashes, parentheses — no hyphens or special chars.
- Validate at input boundaries (CLI parsing, config loading) rather than at serialization time.
When it happens
Trigger: Calling saveXml on an InstallCategoryRequest whose type_name contains disallowed characters such as hyphens, semicolons, quotes, angle brackets, or any special character. Also triggered by null or empty type_name. The validation runs at serialization time, not at object construction.
Common situations: Using a category name with hyphens (e.g., 'my-category'); including SQL-special characters like quotes or semicolons; passing a category name derived from user input without sanitization; an empty string default if the type_name was never set.
Related errors
- Bad category tag
- Bad characters in proposed category type
- Executable category already exists
- Executable
- Expecting privilege option (admin or user)
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/1d1ee13312b39690.
Report an issue: GitHub.