{"record":{"id":"a457e78901ee66b8","repo":"OtterMind/Chat2DB","slug":"invalid-mysql-what-value","errorCode":null,"errorMessage":"Invalid MySQL {what}: {value}","messagePattern":"Invalid MySQL (.+?): (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"chat2db-community-server/chat2db-community-plugins/chat2db-community-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlSqlGuards.java","lineNumber":42,"sourceCode":"    private static final String DEFINER_SINGLE_QUOTED_PART = \"'(?:''|[^'\\\\\\\\])+'\";\n    private static final String DEFINER_BACKTICK_QUOTED_PART = \"`(?:``|[^`\\\\\\\\])+`\";\n    private static final String DEFINER_QUOTED_PART = \"(?:\" + DEFINER_SINGLE_QUOTED_PART + \"|\"\n            + DEFINER_BACKTICK_QUOTED_PART + \")\";\n    private static final Pattern DEFINER_PATTERN = Pattern.compile(\n            \"^([A-Za-z0-9_$]+|\" + DEFINER_QUOTED_PART + \")@([A-Za-z0-9_.%:$-]+|\" + DEFINER_QUOTED_PART + \")$\");\n    private static final Pattern COLUMN_TYPE_PATTERN = Pattern.compile(\n            \"^[A-Za-z][A-Za-z0-9_]*(?:\\\\s*\\\\(\\\\s*\\\\d+(?:\\\\s*,\\\\s*\\\\d+)?\\\\s*\\\\))?(?:\\\\s+[A-Za-z][A-Za-z0-9_]*)*$\");\n\n    private MysqlSqlGuards() {\n    }\n\n    /**\n     * Validate a strict MySQL name token (ENGINE / CHARACTER SET / COLLATE style positions where\n     * escaping is impossible by design).\n     */\n    public static String requireMysqlName(String value, String what) {\n        if (value == null || !MYSQL_NAME_PATTERN.matcher(value).matches()) {\n            throw new IllegalArgumentException(\"Invalid MySQL \" + what + \": \" + value);\n        }\n        return value;\n    }\n\n    /**\n     * Validate a raw DEFAULT literal for numeric-ish columns (positions where quoting would change\n     * semantics). Accepts decimal/scientific numbers, hex and bit literals, TRUE/FALSE.\n     */\n    public static String requireNumericDefault(String value) {\n        if (value == null || !NUMERIC_DEFAULT_PATTERN.matcher(value.trim()).matches()) {\n            throw new IllegalArgumentException(\"Invalid MySQL default value: \" + value);\n        }\n        return value;\n    }\n\n    /**\n     * Validate content of a b'...' bit literal.\n     */","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-plugins/chat2db-community-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlSqlGuards.java#L24-L60","documentation":"Thrown by MysqlSqlGuards.requireMysqlName when a value bound into a non-escapable DDL position (ENGINE, CHARACTER SET, COLLATE-style names) fails ^[A-Za-z0-9_]+$. In these positions MySQL does not allow backtick-quoting, so the value is interpolated raw; the guard prevents SQL injection and syntax errors by allowing only plain identifier characters. Null is also rejected.","triggerScenarios":"Calling requireMysqlName(value, what) (directly or via a DDL builder that emits ENGINE=/CHARACTER SET=/COLLATE=) with a value containing a dash, dot, space, or any non-[A-Za-z0-9_] character, or null.","commonSituations":"A user picks a charset/collation whose name contains an unexpected character; a value is copied from external text with trailing whitespace; an attacker-controlled or untrusted name reaches the builder; 'utf8mb4_0900_ai_ci' style collation names are actually fine (underscore allowed) but a hyphenated or localized name is not.","solutions":["Trim the value and confirm it matches ^[A-Za-z0-9_]+$ before passing it to the builder.","Source charset/engine/collation names from a fixed allowlist (e.g. the server's supported list) rather than free text.","If a hyphen or dot legitimately appears, it is not a valid token for this position; reject it upstream.","Never pass user-typed raw strings into ENGINE=/CHARACTER SET=/COLLATE= without allowlist validation."],"exampleFix":"// before\nString collation = request.getCollation();\nMysqlSqlGuards.requireMysqlName(collation, \"collation\");\n\n// after\nString collation = StringUtils.trimToNull(request.getCollation());\nif (collation == null || !collation.matches(\"^[A-Za-z0-9_]+$\")) {\n    throw new IllegalArgumentException(\"Invalid MySQL collation: \" + collation);\n}\nMysqlSqlGuards.requireMysqlName(collation, \"collation\");","handlingStrategy":"validation","validationCode":"String v = StringUtils.trimToNull(value);\nif (v == null || !v.matches(\"^[A-Za-z0-9_]+$\")) {\n    throw new IllegalArgumentException(\"Invalid MySQL \" + what + \": \" + value);\n}\nMysqlSqlGuards.requireMysqlName(v, what);","typeGuard":"static boolean isValidMysqlName(String value) {\n    return value != null && value.matches(\"^[A-Za-z0-9_]+$\");\n}","tryCatchPattern":null,"preventionTips":["Source ENGINE/CHARACTER SET/COLLATE names from a server allowlist, not free text.","Trim whitespace from copy-pasted names.","Never pass untrusted strings into non-escapable DDL positions.","Reject hyphenated or dotted names upstream; they are invalid tokens here."],"tags":["mysql","validation","injection-guard","ddl"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}