{"record":{"id":"5ae4867c234b0ca7","repo":"oracle/graal","slug":"malformed-locale-s","errorCode":null,"errorMessage":"malformed locale: %s","messagePattern":"malformed locale: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/python/PythonLocaleData.java","lineNumber":86,"sourceCode":"\npublic final class PythonLocaleData {\n\n    private static final int CACHE_SIZE = 16;\n    private static final LRUCache<CacheKey, PythonLocaleData> CACHED_LOCALE_DATA = new LRUCache<>(CACHE_SIZE);\n\n    private static final CodePointSet WORD_CHARS = UNICODE.getProperty(\"Alphabetic\").union(UNICODE.getProperty(\"gc=digit\")).union(CodePointSet.create('_'));\n\n    private final CodePointSet wordChars;\n    private final CodePointSet nonWordChars;\n    private final byte[] caseFolding;\n\n    public static PythonLocaleData getLocaleData(String locale) {\n        if (locale.equals(\"C\")) {\n            return createCachedLocaleData(false, Charset.forName(\"US-ASCII\"));\n        } else {\n            int dot = locale.indexOf('.');\n            if (dot == -1) {\n                throw new IllegalArgumentException(\"malformed locale: \" + locale);\n            }\n            String language = locale.substring(0, dot);\n            String encoding = locale.substring(dot + 1);\n            try {\n                return createCachedLocaleData(language.startsWith(\"tr_\"), Charset.forName(encoding));\n            } catch (UnsupportedCharsetException | IllegalCharsetNameException e) {\n                throw new IllegalArgumentException(\"unsupported locale: \" + locale);\n            }\n        }\n    }\n\n    public CodePointSet getWordCharacters() {\n        return wordChars;\n    }\n\n    public CodePointSet getNonWordCharacters() {\n        return nonWordChars;\n    }","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/python/PythonLocaleData.java#L68-L104","documentation":"Thrown by PythonLocaleData.getLocaleData when a locale string other than 'C' contains no '.' separator. The method expects the C-library form '<language>_<region>.<encoding>' (e.g. 'tr_TR.UTF-8'); without a dot it cannot split language from encoding and throws IllegalArgumentException('malformed locale: ...') before any charset lookup.","triggerScenarios":"Calling the Python-flavor regex locale support (locale-dependent \\\\w, \\\\b, case folding) with a string like 'en', 'tr_TR', or 'POSIX' — anything that is not exactly 'C' and has no '.' character. locale.indexOf('.') returns -1 and the exception is thrown.","commonSituations":"Forwarding Python's locale.getlocale()/os.environ['LC_CTYPE'] output that lacks an encoding part; passing IETF-style tags ('en-US', 'tr') or bare language names ('Turkish') instead of glibc-style names; default-locale code paths in GraalVM Python guest applications.","solutions":["Pass a fully-qualified glibc-style locale including the encoding: 'en_US.UTF-8', 'tr_TR.ISO-8859-9', etc.","Use 'C' (the special-cased POSIX locale with US-ASCII word characters) when no locale-specific behavior is needed","Normalize locale strings at the call site: if the string has no '.', append '.UTF-8' (or map known bare tags to full names) before calling getLocaleData"],"exampleFix":"// before\nPythonLocaleData.getLocaleData(\"tr_TR\"); // no encoding part\n\n// after\nPythonLocaleData.getLocaleData(\"tr_TR.UTF-8\");","handlingStrategy":"validation","validationCode":"boolean isValidPythonLocale(String locale) {\n    return locale.equals(\"C\") || (locale.indexOf('.') > 0 && locale.indexOf('.') < locale.length() - 1);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass glibc-style '<lang>_<REGION>.<encoding>' strings (or 'C') to Python locale handling","Normalize locale identifiers at your system boundary: bare language tags get '.UTF-8' appended"],"tags":["regex","python-flavor","locale","input-validation"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}