Skip to content

[TT-12238] Javascript regex issue on OAS API#7904

Merged
radkrawczyk merged 10 commits intomasterfrom
TT-12238-javascript-regex-issue-on-oas-api-v2
Mar 23, 2026
Merged

[TT-12238] Javascript regex issue on OAS API#7904
radkrawczyk merged 10 commits intomasterfrom
TT-12238-javascript-regex-issue-on-oas-api-v2

Conversation

@MaciekMis
Copy link
Copy Markdown
Contributor

@MaciekMis MaciekMis commented Mar 18, 2026

Description

Related Issue

Motivation and Context

How This Has Been Tested

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring or add test (improvements in base code or adds test coverage to functionality)

Checklist

  • I ensured that the documentation is up to date
  • I explained why this PR updates go.mod in detail with reasoning why it's required
  • I would like a code coverage CI quality gate exception and have explained why

Ticket Details

TT-12238
Status In Code Review
Summary Javascript regex issue on OAS API

Generated at: 2026-03-20 14:48:59

@probelabs
Copy link
Copy Markdown
Contributor

probelabs bot commented Mar 18, 2026

This PR addresses an issue with Javascript-style Unicode regex patterns in OpenAPI Specification (OAS) APIs. The previous implementation performed a raw byte replacement on the entire JSON definition, which was brittle and could lead to data corruption. This has been replaced with a robust Visitor pattern that safely traverses the parsed OAS object model, ensuring transformations are applied correctly and only to the pattern fields within the API schema.

Files Changed Analysis

The changes reflect a clear refactoring of functionality from a generic utility package to a more specialized, schema-aware package:

  • Added: pkg/schema/visitor.go and pkg/schema/visitor_test.go. These new files introduce a Visitor design pattern to safely traverse the parsed OAS object model and apply transformations directly to schema pattern fields. The implementation includes comprehensive testing.
  • Removed: lib/apidef/utils.go and lib/apidef/utils_test.go. These files contained the previous, unsafe implementation that performed regex pattern modifications on raw byte slices.
  • Modified: gateway/api.go and gateway/mw_oas_validate_request.go. These files were updated to use the new schema.Visitor for processing OAS definitions and formatting validation error messages, replacing calls to the deprecated utility functions.

Architecture & Impact Assessment

  • What this PR accomplishes: It fixes a bug where Unicode escape sequences (\uXXXX) in OAS regex patterns were not correctly translated for Go's RE2 regex engine. It replaces an unsafe, global string replacement method with a structured, type-safe approach that specifically targets schema pattern fields.

  • Key technical changes introduced:

    1. Visitor Pattern: A new Visitor in the pkg/schema package safely traverses the entire OAS document structure, including nested schemas, combiners (allOf, anyOf, oneOf), and circular references.
    2. Targeted Schema Manipulation: The transformation logic now operates on the parsed openapi3.Schema object, modifying only the .Pattern field, which prevents unintended side effects.
    3. Code Centralization: All logic for handling OAS schema regex transformations is now centralized in the new pkg/schema package.
  • Affected system components:

    • OAS API Management (gateway/api.go): The endpoints for creating (POST) and retrieving (GET) OAS API definitions are affected. The system now correctly translates regex patterns between the user-provided ECMAScript format and the internal RE2 format.
    • OAS Request Validation Middleware (gateway/mw_oas_validate_request.go): This middleware is updated to use the correctly transformed patterns for validation and to ensure that any validation errors are displayed to the user with the original, correct regex format.
  • Process Flow Comparison:

graph TD
    subgraph "Old Implementation (Unsafe)"
        A[POST /apis/oas] --> B{Read Raw JSON Body};
        B --> C{Replace `\\uXXXX` in entire byte slice};
        C --> D{Parse Modified JSON};
    end

    subgraph "New Implementation (Robust)"
        E[POST /apis/oas] --> F{Read Raw JSON Body};
        F --> G{Parse JSON into OAS Struct};
        G --> H{Use Visitor to traverse OAS struct};
        H --> I{Modify only `pattern` fields};
    end

    style C fill:#f9f,stroke:#333,stroke-width:2px
    style I fill:#9cf,stroke:#333,stroke-width:2px
Loading

Scope Discovery & Context Expansion

The scope of this change is confined to the handling of OAS API definitions within the gateway, specifically addressing the incompatibility between the regex flavor specified by the OAS standard (ECMAScript) and the RE2 engine used by Go.

  • Impact Boundary: The change affects both the management plane (when APIs are created/updated) and the data plane (during request validation).
  • User Impact: Users defining OAS APIs with regex patterns that include Unicode characters (e.g., "pattern": "^[\u0000-\u017f]*$") will find that they now work as expected, whereas they previously failed.
  • Further Context: The new implementation in pkg/schema/visitor.go is comprehensive, correctly handling nested schemas (properties, items), combiners (allOf, anyOf, oneOf), and circular schema references by tracking visited schemas. This ensures each schema is processed exactly once, representing a significant improvement in robustness over the previous raw text replacement approach.
Metadata
  • Review Effort: 3 / 5
  • Primary Label: bug

Powered by Visor from Probelabs

Last updated: 2026-03-23T07:21:46.865Z | Triggered by: pr_updated | Commit: 69fb5f2

💡 TIP: You can chat with Visor using /visor ask <your question>

@probelabs
Copy link
Copy Markdown
Contributor

probelabs bot commented Mar 18, 2026

✅ Security Check Passed

No security issues found – changes LGTM.

✅ Architecture Check Passed

No architecture issues found – changes LGTM.

✅ Performance Check Passed

No performance issues found – changes LGTM.

✅ Quality Check Passed

No quality issues found – changes LGTM.


Powered by Visor from Probelabs

Last updated: 2026-03-23T07:21:38.667Z | Triggered by: pr_updated | Commit: 69fb5f2

💡 TIP: You can chat with Visor using /visor ask <your question>

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 18, 2026

API Changes

--- prev.txt	2026-03-23 07:20:40.815577638 +0000
+++ current.txt	2026-03-23 07:20:32.814605880 +0000
@@ -13238,13 +13238,6 @@
     the version definition and ensures that required fields have appropriate
     values.
 
-func RestoreUnicodeEscapesInError(err error) error
-    RestoreUnicodeEscapesInError takes an error and applies the
-    RestoreUnicodeEscapesInRegexp transformation to its message. For example,
-    it converts RE2-compatible escapes like `\x{0041}` back to `\u0041`. It
-    returns a new error with the transformed message. If the input error is nil,
-    it returns nil.
-
 func SetAsDefault(versionName string) option.Option[apidef.VersionDefinition]
     SetAsDefault creates an option that marks a specific version as the default.
     This sets the Default field in the VersionDefinition to the specified
@@ -13261,35 +13254,6 @@
 
 TYPES
 
-type DataBytesModifier struct {
-	// Has unexported fields.
-}
-
-func NewDataBytesModifier(data []byte) *DataBytesModifier
-
-func (d *DataBytesModifier) Data(data []byte)
-
-func (d *DataBytesModifier) Reset()
-
-func (d *DataBytesModifier) RestoreUnicodeEscapesFromRE2()
-    RestoreUnicodeEscapesFromRE2 translates RE2-compatible hexadecimal escape
-    sequences (`\x{XXXX}`) back to their original ECMA-262 compliant Unicode
-    escape sequence representation (`\uXXXX`). This function is typically used
-    when exporting an API definition or any other data structure where regex
-    patterns were previously sanitized for internal use with Go's RE2 engine.
-    It ensures that external consumers of the data receive the regex patterns in
-    their original, more widely supported format.
-
-func (d *DataBytesModifier) Result() []byte
-
-func (d *DataBytesModifier) TransformUnicodeEscapesToRE2()
-    TransformUnicodeEscapesToRE2 transforms ECMA-262 compliant Unicode escape
-    sequences (`\uXXXX`) into a format that is compatible with Go's RE2 regex
-    engine (`\x{XXXX}`). This is necessary because RE2 does not support the `\u`
-    escape sequence but does support hexadecimal escapes, which can represent
-    any Unicode code point. The function returns a new byte array with the
-    transformed pattern.
-
 type VersionParameter int
     VersionParameter represents the type of parameter used in API version
     configuration. It defines the possible parameters that can be used when
@@ -13525,6 +13489,36 @@
 
 func (c CustomPolicyId) Validate() error
 
+# Package: ./pkg/schema
+
+package schema // import "github.com/TykTechnologies/tyk/pkg/schema"
+
+
+FUNCTIONS
+
+func RestoreUnicodeEscapesFromRE2(str string) string
+func RestoreUnicodeEscapesFromRE2Manipulation(schema *openapi3.Schema)
+func RestoreUnicodeEscapesInError(err error) error
+func TransformUnicodeEscapesToRE2Manipulation(schema *openapi3.Schema)
+
+TYPES
+
+type Manipulation func(schema *openapi3.Schema)
+
+type Manipulations []Manipulation
+
+type Visitor struct {
+	// Has unexported fields.
+}
+
+func NewVisitor() *Visitor
+
+func (v *Visitor) AddSchemaManipulation(manipulation Manipulation)
+
+func (v *Visitor) ProcessOAS(doc *oas.OAS)
+
+func (v *Visitor) ProcessSchema(schemaRef *openapi3.SchemaRef)
+
 # Package: ./pkg/validator
 
 package validator // import "github.com/TykTechnologies/tyk/pkg/validator"

@MaciekMis
Copy link
Copy Markdown
Contributor Author

/Visor ask Changes made by Visitor to OAS struct are then assigned to obj variable. Next this obj var is marshalled and returned to the client. Please double check that.

@probelabs
Copy link
Copy Markdown
Contributor

probelabs bot commented Mar 19, 2026


Powered by Visor from Probelabs

Last updated: 2026-03-19T13:20:39.704Z | Triggered by: MaciekMis | Commit: df44fcb

💡 TIP: You can chat with Visor using /visor ask <your question>

Copy link
Copy Markdown
Contributor

@shults shults left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Copy link
Copy Markdown
Collaborator

@pvormste pvormste left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this solution, fantastic!

@github-actions
Copy link
Copy Markdown
Contributor

🚨 Jira Linter Failed

Commit: 69fb5f2
Failed at: 2026-03-23 07:20:00 UTC

The Jira linter failed to validate your PR. Please check the error details below:

🔍 Click to view error details
failed to get Jira issue: failed to fetch Jira issue TT-12238: Issue does not exist or you do not have permission to see it.: request failed. Please analyze the request body for more details. Status code: 404

Next Steps

  • Ensure your branch name contains a valid Jira ticket ID (e.g., ABC-123)
  • Verify your PR title matches the branch's Jira ticket ID
  • Check that the Jira ticket exists and is accessible

This comment will be automatically deleted once the linter passes.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
93.2% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

@radkrawczyk radkrawczyk merged commit ab9e5e1 into master Mar 23, 2026
109 of 120 checks passed
@radkrawczyk radkrawczyk deleted the TT-12238-javascript-regex-issue-on-oas-api-v2 branch March 23, 2026 10:06
@radkrawczyk
Copy link
Copy Markdown
Contributor

/release to release-5.8

@probelabs
Copy link
Copy Markdown
Contributor

probelabs bot commented Apr 13, 2026

⚠️ Cherry-pick encountered conflicts. A draft PR was created: #7994

buger added a commit that referenced this pull request Apr 17, 2026
pkg/schema was introduced on master by PR #7904 and is not available
on release branches. Replace schema.RestoreUnicodeEscapesInError(err)
with plain err to match existing release branch error handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
buger added a commit that referenced this pull request Apr 17, 2026
pkg/schema was introduced on master by PR #7904 and is not available
on release branches. Replace schema.RestoreUnicodeEscapesInError(err)
with plain err to match existing release branch error handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants