swagger-api / swagger-api/swagger-parser
InlineModelResolver.uniqueName throws StringIndexOutOfBoundsException for titles starting with a separator (camelCaseFlattenNaming)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 867
- Forks
- 560
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 7
Description
Summary
InlineModelResolver.uniqueName() crashes with an uncaught StringIndexOutOfBoundsException when camelCaseFlattenNaming is enabled and the input key (a schema title, or a derived fallback name) is empty or starts with one of the separator characters (-, _, |, whitespace). The first token produced by key.split(...) is then the empty string, and substring(0, 1) is called on it unconditionally.
Static-analysis finding against current master; not executed here.
Location
- File:
modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java - Function:
uniqueName(String key), lines ~441-455; specifically:
for (int i = 0; i < key.split("[-|\\s|_]").length; i++) {
uniqueKey = key.split("[-|\\s|_]")[i];
uniqueKey = uniqueKey.substring(0, 1).toUpperCase() + uniqueKey.substring(1); // <-- throws
- Reached from
resolveModelName(title, key)(~line 418), which prefersuniqueName(title)whenevertitle != null.
Problem
Java's split() removes trailing empty strings but keeps leading ones. For any key whose first character is a separator - e.g. " foo", "-foo", "_foo" - or for the empty string "" (split result [""]), element 0 of the split array is "". The loop body then executes "".substring(0, 1), which throws StringIndexOutOfBoundsException: begin 1, end 0, length 0. There is no guard for empty tokens anywhere in the loop.
Because resolveModelName() passes the schema's free-form title straight into uniqueName(), any inline schema whose title begins with such a character (or is "") triggers this when flattening runs with camel-case naming enabled.
Trigger / Reproduction
Static analysis only; not run here. Trigger conditions per the code paths above:
ParseOptions options = new ParseOptions();
options.setResolve(true);
options.setFlatten(true);
options.setCamelCaseFlattenNaming(true);
new OpenAPIV3Parser().readContents(spec, null, options);
with an inline schema whose title starts with a separator or is empty, e.g.:
paths:
/things:
post:
requestBody:
content:
application/json:
schema:
type: object
title: " my model" # or "-", "_x", ""
properties:
name: { type: string }
" my model".split("[-|\s|_]") yields ["", "my", "model"]; iteration 0 calls "".substring(0, 1) and throws.
Note that "" as title also crashes here, which overlaps with the empty-title report in #2118 - but #2118 describes the degenerate empty component name outcome (default options), not this exception path with camelCaseFlattenNaming=true.
Expected Behavior
A malformed/unusual title should degrade gracefully: skip empty tokens (or fall back to the provided fallback key / a synthesized name like inline_object) instead of throwing an unhandled runtime exception out of flatten().
Actual Behavior
StringIndexOutOfBoundsException propagates from InlineModelResolver.flatten(); parsing aborts even though the document itself is valid.
Impact
Library consumers using the documented flatten + camelCaseFlattenNaming combination get a hard failure on valid documents containing titles with leading separators/spaces (free-form strings users legitimately control, e.g. " LED status"). Since OpenAPIV3Parser catches and logs exceptions in some paths (catch (Exception e) around resolving), the failure can also surface merely as a silently un-flattened/partially processed API instead of clean output, depending on call site.
Suggested Direction
Inside the loop, skip empty tokens before calling substring (e.g. if (uniqueKey.isEmpty()) continue;), and after concatenation fall back to a non-empty default name if the sanitized result is blank. That fixes both the exception and the adjacent blank-name outcome from #2118 for the camel-case path.
Evidence
InlineModelResolver.javalines 444-452: unconditionalsubstring(0, 1)on each split token; no empty-token guard.- Java
String.splitsemantics retain leading empty strings (only trailing empties are removed). resolveModelName()line 422:titlewins over the fallback key whenever non-null, so user-controlled titles flow directly into the vulnerable code.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java at uniqueName(String key), then trace its caller resolveModelName(title, key). Reproduce through OpenAPIV3Parser with flattening and camelCaseFlattenNaming enabled using a title beginning with a separator or an empty title; done means valid input no longer throws and produces a non-empty model name.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100