swagger-api / swagger-api/swagger-parser

InlineModelResolver.uniqueName throws StringIndexOutOfBoundsException for titles starting with a separator (camelCaseFlattenNaming)

Open Beginner friendly
#2,386 0 comments 0 reactions 0 assignees View on GitHub

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 prefers uniqueName(title) whenever title != 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.java lines 444-452: unconditional substring(0, 1) on each split token; no empty-token guard.
  • Java String.split semantics retain leading empty strings (only trailing empties are removed).
  • resolveModelName() line 422: title wins over the fallback key whenever non-null, so user-controlled titles flow directly into the vulnerable code.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.