Skip to content

Use Locale.ROOT for toLowerCase/toUpperCase calls#61

Open
AlexProgrammerDE wants to merge 3 commits intoExlll:masterfrom
AlexProgrammerDE:fix/locale-root-case-conversion
Open

Use Locale.ROOT for toLowerCase/toUpperCase calls#61
AlexProgrammerDE wants to merge 3 commits intoExlll:masterfrom
AlexProgrammerDE:fix/locale-root-case-conversion

Conversation

@AlexProgrammerDE
Copy link

Summary

  • Replaced all bare toLowerCase() and toUpperCase() calls with toLowerCase(Locale.ROOT) / toUpperCase(Locale.ROOT) across Serializers.java, RootSerializer.java, and SerializersTest.java.

Why This Is Needed

Java's String.toLowerCase() and String.toUpperCase() without a Locale argument use Locale.getDefault(), which is derived from the system/JVM locale. This means the same code can produce different results on different machines depending on the OS locale settings.

The most well-known problem is with the Turkish locale (tr_TR), where:

Expression Locale.ENGLISH / Locale.ROOT Locale("tr", "TR")
"INTEGER".toLowerCase() "integer" "ınteger" (dotless ı)
"integer".toUpperCase() "INTEGER" "İNTEGER" (dotted İ)
"I".toLowerCase() "i" "ı"
"i".toUpperCase() "I" "İ"

Concrete impact in this codebase

  • Serializers.java: The error message includes sourceTypeName.toLowerCase() (e.g., turning "Boolean" into "boolean" for the phrase "boolean-to-string coercion"). On a Turkish-locale system, "Boolean" would become "boolean" correctly, but type names containing I (like "BigInteger") would become "bıgınteger" — a garbled error message.

  • RootSerializer.java: Environment variable names are uppercased with toUpperCase(). On a Turkish-locale system, a key containing "i" would be converted to "İ" (with a dot above) instead of "I", causing environment variable lookups to silently fail to match the actual env var.

Examples of real-world breakage

// On a Turkish-locale JVM:
"myAppConfig_item".toUpperCase()
// Expected: "MYAPPCONFIG_ITEM"
// Actual:   "MYAPPCONFIG_İTEM"  ← env var lookup will fail!

"Integer".toLowerCase()
// Expected: "integer"
// Actual:   "ınteger"  ← broken error message

Locale.ROOT is the correct choice here (rather than Locale.ENGLISH) because these are programmatic/technical strings, not user-facing text that needs language-specific rules. Locale.ROOT provides locale-independent behavior, which is exactly what's needed for identifiers, env var names, and type names.

Test plan

  • Verified no remaining bare toLowerCase()/toUpperCase() calls in the codebase
  • Existing tests should continue to pass since behavior is unchanged on non-Turkish locales

🤖 Generated with Claude Code

Fixes locale-sensitive case conversion that can produce unexpected
results on systems with certain default locales (e.g. Turkish locale
where 'I'.toLowerCase() becomes 'ı' instead of 'i').

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 8, 2026 20:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes string case conversions locale-independent by updating toLowerCase()/toUpperCase() calls to use Locale.ROOT, preventing behavior differences under non-English default JVM locales (e.g., Turkish) in serializer error messages and environment variable resolution.

Changes:

  • Updated serializer exception message formatting to use toLowerCase(Locale.ROOT).
  • Updated environment variable key normalization to use toUpperCase(Locale.ROOT).
  • Updated related test helper message formatting to match production behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
configlib-core/src/main/java/de/exlll/configlib/Serializers.java Uses toLowerCase(Locale.ROOT) when building coercion-related exception messages.
configlib-core/src/main/java/de/exlll/configlib/RootSerializer.java Uses toUpperCase(Locale.ROOT) when normalizing env var keys for lookups.
configlib-core/src/test/java/de/exlll/configlib/SerializersTest.java Aligns expected exception message formatting with Locale.ROOT lowercasing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

AlexProgrammerDE and others added 2 commits February 8, 2026 21:26
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…t.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant