Skip to content

Escape */ sequences in generated JSDoc to prevent comment injection#1611

Merged
smorimoto merged 1 commit intomainfrom
escape-jsdoc-comment-injection
Feb 8, 2026
Merged

Escape */ sequences in generated JSDoc to prevent comment injection#1611
smorimoto merged 1 commit intomainfrom
escape-jsdoc-comment-injection

Conversation

@smorimoto
Copy link
Collaborator

@smorimoto smorimoto commented Feb 8, 2026

Problem

OpenAPI specification fields (descriptions, titles, examples, patterns, etc.) are untrusted input that may contain */ sequences. When these values are embedded into JSDoc block comments in generated TypeScript output, a */ sequence prematurely closes the comment block, producing syntactically invalid TypeScript. This affects any spec with response types or schema annotations containing */.

Solution

Add a centralized escapeJSDocContent() method to SchemaFormatters that replaces */ with *\/ in any value destined for JSDoc output. The method handles undefined (returns "") and coerces non-string values via String(), since OpenAPI fields like minimum, maximum, and default can be numbers, booleans, or objects.

The escape is applied consistently across all JSDoc-emitting code paths:

  • schema-formatters.tsescapeJSDocContent() is called within formatDescription() and on enum field descriptions during formatting
  • code-gen-process.tsescapeJSDocContent is exposed as a template utility alongside formatDescription
  • data-contract-jsdoc.ejs — All @format, @min, @max, @pattern, @example, @default, and other annotation values are escaped; title is routed through formatDescription for consistency
  • object-field-jsdoc.ejs — Same treatment for object field annotations
  • route-docs.ejs — Route documentation tags, response status codes, type signatures, and descriptions are escaped
  • api.ejs — Top-level API metadata (@title, @version, @license, @baseUrl, @contact, etc.) is escaped

A dedicated test suite (tests/spec/issue-1321/) validates that */ in descriptions, enum values, examples, and patterns produces valid output.

Verification

  • bun run test passes, including snapshot updates for tests/spec/responses/ (the existing inline response type comments now use *\/ instead of the previous ad-hoc \* / *\ escaping)
  • New test in tests/spec/issue-1321/ covers a schema with */ in descriptions, enum descriptions, examples, and patterns

Closes #1321
Closes #672
Closes #704
Supersedes #1368


Note

Medium Risk
Touches core code generation formatting/templates, which can subtly change emitted TypeScript comments and snapshot outputs across many users, though the change is narrowly scoped to JSDoc escaping.

Overview
Prevents JSDoc comment injection/broken generated TypeScript by escaping */ sequences coming from untrusted OpenAPI fields.

Adds SchemaFormatters.escapeJSDocContent() and wires it through the codegen/template utilities, then updates all JSDoc-emitting templates (schema/field docs, route docs, and top-level API metadata, plus enum value descriptions) to consistently escape annotation values (e.g., @example, @pattern, response types/status, tags, routes).

Adds a new regression spec (tests/spec/issue-1321) with snapshots and updates existing response snapshots to reflect the new escaping behavior.

Written by Cursor Bugbot for commit 7f25d28. This will update automatically on new commits. Configure here.

@changeset-bot
Copy link

changeset-bot bot commented Feb 8, 2026

🦋 Changeset detected

Latest commit: 7f25d28

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
swagger-typescript-api Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@smorimoto smorimoto added the bug Something isn't working label Feb 8, 2026
OpenAPI spec fields (descriptions, titles, examples, patterns, etc.) are
untrusted input that may contain `*/` sequences. When embedded in JSDoc
block comments, these sequences prematurely close the comment, producing
invalid TypeScript output.

Add `escapeJSDocContent()` to SchemaFormatters that replaces `*/` with
`*\/` and expose it as a template utility. Apply escaping consistently
across all JSDoc-emitting templates (data-contract-jsdoc, object-field-jsdoc,
route-docs, api) and enum field descriptions.

Closes #1321
@smorimoto smorimoto force-pushed the escape-jsdoc-comment-injection branch from a1c92bd to 7f25d28 Compare February 8, 2026 18:37
@smorimoto smorimoto merged commit 92a2d46 into main Feb 8, 2026
13 checks passed
@smorimoto smorimoto deleted the escape-jsdoc-comment-injection branch February 8, 2026 18:51
@github-actions github-actions bot mentioned this pull request Feb 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

1 participant