Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Java Strings And Text

ASecurity

Text in Java as encoded data rather than a universal type: UTF-16 code units versus code points versus graphemes, charsets and why the platform default is not a policy, locale-sensitive case and formatting including the Turkish-I bug, concatenation cost in loops versus single expressions, text blocks, regex compilation and catastrophic backtracking on untrusted input, interning, and injection through SQL, shells, paths and logs. Use when a String stands in for a type or compound key, when tex...

2 stars
0 votes
0 copies
0 views
Added 9/19/2026
developmentrustgojavashellsqlexpressapidatabasesecurityperformance

Works with

api

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add robsonkades/agent-skills --skill java-strings-and-text --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Java Strings And Text?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Java Strings And Text
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-java-strings-and-text/badge)](https://www.skillsdirectory.com/skills/robsonkades-java-strings-and-text)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: java-strings-and-text
description: >
  Text in Java as encoded data rather than a universal type: UTF-16 code units versus code
  points versus graphemes, charsets and why the platform default is not a policy,
  locale-sensitive case and formatting including the Turkish-I bug, concatenation cost in
  loops versus single expressions, text blocks, regex compilation and catastrophic
  backtracking on untrusted input, interning, and injection through SQL, shells, paths and
  logs. Use when a String stands in for a type or compound key, when text is truncated by
  length(), when toLowerCase() or String.format() omits a Locale, when getBytes() omits a
  charset, when a Pattern is compiled in a loop or applied to user input, or when user text
  reaches SQL, a command or a log line. Numeric formatting is java-numeric-types, String
  standing in for a domain type as a smell is java-code-smells, and wire-format throughput
  is serialization-performance.
---

# Java Strings and Text

## Purpose

Treat text as encoded, locale-sensitive, attacker-influenced data with a cost model — because
every one of those four properties has a failure mode that looks like a `String` working
fine. The two most expensive: text that is correct in the developer's locale and encoding and
wrong in production, and text concatenated into something that interprets it (SQL, a shell, a
log line, a path).

## Workflow

Inspect compiler release/toolchains, runtime JDK, locale/provider and boundary encoding before
changing behavior. Java 25 is the authoring baseline; preserve the project's actual target.
Text blocks and `formatted` need Java 15+, records Java 16+, and default charset behavior
changes in Java 18. Unicode segmentation depends on the runtime version. Use supported
alternatives without upgrades or preview; missing protocol/column constraints remain unverified.
Reuse established boundary contracts and adequate implementations. Ask only for missing input,
consumer or runtime facts that would change the recommendation.

1. **Check the consumer contract before introducing a type.** An id, status, currency code,
   compound key or phone number may benefit from a validated type when invariants or mix-ups
   justify it. Retain adequate validated strings and published wire/API encodings.
2. **Pin the encoding at every boundary.** Use the charset required by the protocol or storage
   contract—often UTF-8—on byte/string conversions, readers, writers and HTTP bodies.
3. **Follow the required casing and format.** `Locale.ROOT` suits locale-neutral protocols;
   an explicitly localized import/export or human message may require another locale. Neither
   substitutes for a protocol's ASCII grammar or canonicalization policy.
4. **Choose the composition mechanism by shape**: a single expression → `+`; a loop →
   `StringBuilder`; a collection → `String.join`/`Collectors.joining`; multi-line literal →
   a text block; user-facing formatting → `String.format(locale, …)` or `MessageFormat`
   with the user's locale. `formatted` has no locale overload and uses the process default.
5. **Reuse stable, repeated `Pattern`s**, and check what happens when input is hostile—length
   bound, nesting, backtracking. Dynamic or one-shot expressions do not belong in global state.
6. **Check every place text is embedded into another language.** Bind data values where
   supported; use allowlisted structural choices or context-specific encoding when binding is
   unavailable. Verify the actual downstream grammar, not just the Java string expression.

## Rules

- Consider enums for closed sets (java-enums), validated ids/codes, `java.time` timestamps,
  numeric amount types and `URI`/`Path` when their contracts fit. A type alone does not validate
  meaning or authorize a location. Weigh consumer compatibility and useful invariants against
  wrapper/conversion cost; do not create types merely because text is present.
- Check compound-key ambiguity: `tenant + "#" + id` collides if unconstrained components can
  contain `#`. A record can simplify an internal key; an established separator restriction,
  escaping or length-prefix encoding can be sound. Preserve public encoded keys and verify
  equality/round-trip behavior before changing representation.
- `length()` counts UTF-16 **code units**, not characters. Characters outside the Basic
  Multilingual Plane — emoji, many CJK extensions, some scripts — take two units, so
  `substring(0, 100)` can split a surrogate pair and produce invalid text. Use
  `codePointCount`/`offsetByCodePoints` when the unit is a code point, and `BreakIterator` when
  the unit is what a user perceives as a character (an emoji with a skin-tone modifier is
  several code points and one grapheme).
- Pass or verify the contract's charset. `String.getBytes()` and `new String(byte[])` use
  the default charset; reader/writer overloads may use that default or a specified fixed/inherited
  encoding. Since Java 18 the default charset is UTF-8, while `-Dfile.encoding=COMPAT` selects the
  native encoding; other overrides have unspecified behaviour. Explicit UTF-8 is portable only
  when UTF-8 is actually the boundary contract—legacy files and protocols may require another
  explicit charset.
- Select casing and formatting from the consuming contract. `"TITLE".toLowerCase()` is
  `"tıtle"` in a Turkish locale — the dotless ı — so a
  case-insensitive comparison of a header, a code or an enum name fails on a machine whose
  locale differs from the developer's. Use `Locale.ROOT` when the protocol requires that mapping;
  validate an ASCII-only grammar separately when required.
  `equalsIgnoreCase` is locale-independent simple Unicode comparison, not
  human-language collation or a universal identifier canonicalizer. The same applies to
  `String.format("%.2f", …)`, which emits a comma decimal separator in many locales;
  `String.formatted` also uses the default formatting locale.
- Concatenation in a single expression is fine. Modern `javac` commonly uses
  `StringConcatFactory`; the language specification intentionally leaves the implementation to
  the compiler. Repeated `result += fragment` in a loop can copy an ever-growing prefix and
  become quadratic. Use a locally owned `StringBuilder` in loops, `String.join` or
  `Collectors.joining` for collections.
- Do not micro-optimise concatenation outside loops, and do not replace readable expressions
  with `StringBuilder` chains on a hunch. If string building appears in a profile, that is
  evidence; otherwise it is noise (performance-methodology).
- Reuse a `private static final Pattern` when the same non-trivial expression is matched
  repeatedly. `matches` and regex replacement convenience methods compile their expressions;
  `split` is specified in terms of pattern compilation although implementations may optimize
  simple delimiters. Do not retain data-dependent patterns forever, and measure before building
  a pattern cache—unbounded cardinality merely changes an allocation cost into a leak.
- Review the work bound of a regex applied to untrusted input. Ambiguous nested quantifiers
  (`(a+)+`, `(\w+\s?)*`) can cause excessive backtracking or stack exhaustion; the actual growth
  depends on the pattern, input and implementation. Java's matcher has no per-match timeout.
  Bound the input length, avoid harmful nested
  quantifiers, consider possessive quantifiers or atomic groups only after checking accepted
  inputs and captures remain correct, and prefer a real parser for
  structured input. Where a regex must run on user input, run it with a bounded input size and
  treat a hang as a possible ReDoS requiring pattern/input evidence.
- Never interpolate untrusted text as executable syntax. Use prepared statements for SQL data
  values and allowlist structural choices such as identifiers. Use `ProcessBuilder` with an argument list,
  and a templating engine with contextual escaping. For paths, lexical `normalize`/`startsWith`
  checks do not defeat symlinks or races: resolve against a trusted real base, constrain allowed
  names, and use filesystem-specific secure traversal where the threat model requires it.
  Structured logging preserves field boundaries, but the encoder/sink must still escape control
  characters to prevent log forging (structured-logging).
- Use text blocks when they clarify multi-line literals — SQL, JSON, HTML. Check resulting
  indentation, newlines and escapes against required bytes; they do not make
  embedded user input safe, so parameters still go through the mechanism above. String
  templates were previewed and then withdrawn from the JDK; do not design around them.
- Do not use `String.intern()` as an unmeasured deduplication strategy for unbounded external
  data. It adds shared-table lookup/coordination and couples retention/GC behaviour to the JVM
  implementation. First prove duplicate strings dominate the heap; then compare G1 string
  deduplication, bounded caches with real eviction, or representation changes
  (java-reference-types-and-leaks).
- Define and version a Unicode canonicalization policy before comparing or storing identifiers
  that people type. The same visible
  text can be several code-point sequences (`é` composed or decomposed);
  `Normalizer.normalize(s, NFC)` is a common preservation-oriented policy, but protocols,
  search and security-sensitive identifiers may require case folding, NFKC, script restrictions
  or no normalization. Java and the database must enforce the same rule.
- Byte length and character length are different limits. A `VARCHAR(50)` may mean 50 bytes or
  50 characters depending on the database and collation, so validation written in Java
  characters can pass while the insert fails. Validate against the real constraint.

## References

Deliver the boundary contract (encoding, malformed-input policy, locale and length unit),
the smallest justified change, and checks run on the target. Include malformed bytes,
supplementary/combining text, locale differences and rejected inputs when relevant. Separate
semantic correctness from measured regex/performance claims; report unavailable evidence.

- [Encoding, locale and Unicode](references/encoding-locale-and-unicode.md) — read when text
  crosses a file, socket, database or process boundary, when it is truncated or compared
  case-insensitively, or when a bug appears only for some users' data or on some machines.
- [Building text: concatenation, regex and injection](references/building-text-safely.md) —
  read when composing strings in a loop or a hot path, when writing or reviewing a regex over
  untrusted input, or when text is embedded into SQL, a command, a path, a template or a log.

Attribution

robsonkadesrobsonkades
View sourceMore from robsonkades →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →