Skip to content

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

Description

@krishna3554

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions