Skip to content

⚡ improvements#23

Open
techouse wants to merge 30 commits intomainfrom
chore/improvements
Open

⚡ improvements#23
techouse wants to merge 30 commits intomainfrom
chore/improvements

Conversation

@techouse
Copy link
Owner

@techouse techouse commented Feb 15, 2026

This pull request introduces several improvements and fixes to the Swift and Objective-C bridging layers for query string encoding and decoding. The most significant changes are improved normalization and validation of options, enhanced handling of list limits and overflow cases during decoding, and the addition of a deep iterative fallback for encoding very deeply nested structures. The update also ensures charset handling is consistent and robust, and upgrades a package dependency for Linux builds.

Decoding Improvements:

  • Added normalization for charset, parameter limits, and depth in DecodeOptionsObjC, ensuring only supported charsets are used and limits are enforced with sensible minimums. [1] [2]
  • Enhanced list value parsing to handle overflow: when the list limit is exceeded and exceptions are not thrown, the first occurrence now falls back to an indexed-object representation, matching behavior in qs@6.14.2. [1] [2] [3] [4]

Encoding Improvements:

  • Added normalization for charset in EncodeOptionsObjC, defaulting to .utf8 if an unsupported charset is provided. [1] [2]
  • Introduced an iterative fallback encoder for deeply nested structures (depth ≥ 512) to avoid stack overflows, with a fast eligibility check to ensure it only applies in safe cases. [1] [2]
  • Refactored value description functions to respect charset when converting Data to String, ensuring correct encoding in all cases. [1] [2] [3] [4]

General Code Quality:

  • Minor style and formatting fixes in Objective-C bridge methods for consistency. [1] [2]

Dependency Update:

  • Updated the ReerKit package version for Linux builds from 1.2.2 to 1.2.5 in both Package.swift and Package@swift-5.10.swift. [1] [2]

Summary by CodeRabbit

  • New Features

    • Strong-to-strong map support on Linux.
    • Iterative deep-encoding fallback for very deep structures.
  • Bug Fixes

    • Avoids stack overflows and improves resilience for deep/conflicting inputs.
    • Non-throwing fallback for comma-separated list overflows with correct element decoding.
    • Sanitizes Obj‑C bridge options (dot handling, charset, limits).
  • Chores

    • Linux ReerKit updated to 1.2.5.
    • Pinned comparison tool to 6.14.2.

@techouse techouse self-assigned this Feb 15, 2026
@techouse techouse added the enhancement New feature or request label Feb 15, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Bumps a Linux‑only dependency, normalizes Obj‑C bridge option values (charset, dot handling, limits), implements non‑throwing comma‑list overflow fallback and overflow decoding, adds iterative depth‑bounded encoding fallback and iterative dictionary merge to avoid recursion, adds strong‑to‑strong NSMapTable for Linux, and expands tests.

Changes

Cohort / File(s) Summary
Package & Tools
Package.swift, Package@swift-5.10.swift, Tools/QsSwiftComparison/js/package.json
Linux ReerKit constraint updated (1.2.2 → 1.2.5) and JS qs pinned to 6.14.2.
Objective‑C Bridge Normalization
Sources/QsObjC/Models/DecodeOptionsObjC.swift, Sources/QsObjC/Models/EncodeOptionsObjC.swift
Sanitizes/normalizes allowDots/decodeDotInKeys, charset, parameterLimit, and depth before constructing Swift options.
ObjC Bridge Formatting
Sources/QsObjC/QsBridge+DecodeConvenience.swift
Formatting-only brace reflow; no behavioral change.
Decoder: Comma-list & Overflow Handling
Sources/QsSwift/Internal/Decoder+ParseList.swift, Sources/QsSwift/Internal/Decoder+ParseQuery.swift, Sources/QsSwift/Internal/Decoder+ParseObject.swift
Adds isFirstOccurrence tracking, effectiveListLength, non-throwing overflow fallback to indexed maps, overflow-element decoding helpers, and numeric-entity handling that preserves overflow shape.
Encoder: Iterative Deep Fallback
Sources/QsSwift/Internal/Encoder.swift
Adds stack-based iterative deep encoding fallback with cycle detection, charset-aware scalar/data description, and an iterative traversal to avoid recursion.
Iterative Dictionary Merge
Sources/QsSwift/Internal/Utils+Merge.swift
Replaces recursive dictionary merge with an iterative stack/frame-based merge (mergeDictionariesIterative, mergeValues) to prevent recursion overflow and centralize overflow/index propagation.
NSMapTable (Linux) strong storage
Sources/QsSwift/Internal/NSMapTable+Linux.swift
Adds strong-to-strong storage mode, StrongEntry, strongToStrongObjects() constructor, and branching in set/object access for strong vs weak storage.
Minor utils & formatting
Sources/QsSwift/Internal/Utils.swift, Sources/QsSwift/Models/DecodeOptions.swift, Sources/QsSwift/Models/EncodeOptions.swift, Sources/QsSwift/Qs+Encode.swift
Small pattern-match and typealias/formatting adjustments; no semantic changes.
Tests — ObjC & Swift (large additions)
Tests/QsObjCTests/*, Tests/QsSwiftTests/*
Many new and extended tests: non-throwing comma overflow fallback, overflow element decoding/custom decoders, encode:false Data behavior, deep-merge/stack-safety, iterative encoder fallback, NSMapTable Linux semantics, and numerous edge-case encoder/decoder scenarios.
Test formatting / small edits
Tests/QsObjCTests/ObjCBridgeTests.swift, Tests/QsObjCTests/ObjCExampleTests.swift, Tests/QsObjCTests/ObjCModelCoverageTests.swift, Tests/QsSwiftTests/Fixtures/*
Trailing commas, whitespace/formatting tweaks, and added ObjC sanitization tests.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Encoder
    participant IterativeEncoder
    participant Stack

    Client->>Encoder: encode(input, options, depth)
    alt depth >= iterativeFallbackDepth and canUseIterativeDeepFallback
        Encoder->>IterativeEncoder: encodeIterativeDeepFallback(root, charset, options)
        IterativeEncoder->>Stack: push(root task)
        loop traverse tasks
            IterativeEncoder->>Stack: pop(task)
            alt container node
                IterativeEncoder->>IterativeEncoder: containerIdentity() -> detect cycle
                IterativeEncoder->>Stack: push(leave task)
                IterativeEncoder->>Stack: push(child tasks)
            else scalar/leaf
                IterativeEncoder->>IterativeEncoder: describe(value, charset)
                IterativeEncoder->>Stack: append result to parent
            end
        end
        IterativeEncoder-->>Encoder: composed result
    else
        Encoder->>Encoder: use recursive encoding path
    end
    Encoder-->>Client: return encoded output
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

linux, test

Poem

🐰 Iterative hops through data deep and wide,
I tidy charsets and dots with a twitch of pride.
When commas overflow, I map each bit true,
Strong maps on Linux hold keys like new.
Encode and merge — I nibble bugs in two.

🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title ':zap: improvements' is vague and generic, using a non-descriptive emoji and the word 'improvements' which conveys no meaningful information about what was actually changed. Replace with a specific, descriptive title that summarizes the main change, such as 'Add iterative encoder fallback for deep nesting and normalize decode/encode options' or similar.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description provides comprehensive details about the changes, organized by category (Decoding, Encoding, General, Dependencies) with clear explanations and references. However, it does not follow the repository's pull request template structure, which requires sections for Type of change, How Has This Been Tested, and Checklist items.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/improvements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@techouse techouse requested a review from Copilot February 15, 2026 16:49
@techouse
Copy link
Owner Author

@codex review

@codecov
Copy link

codecov bot commented Feb 15, 2026

Codecov Report

❌ Patch coverage is 99.02200% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.63%. Comparing base (1c57584) to head (7eaf870).

Files with missing lines Patch % Lines
Sources/QsSwift/Internal/Utils.swift 93.54% 2 Missing ⚠️
Sources/QsSwift/Internal/Decoder+ParseQuery.swift 98.48% 1 Missing ⚠️
Sources/QsSwift/Internal/Encoder.swift 99.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #23      +/-   ##
==========================================
+ Coverage   93.37%   95.63%   +2.25%     
==========================================
  Files          54       54              
  Lines        2823     3158     +335     
==========================================
+ Hits         2636     3020     +384     
+ Misses        187      138      -49     
Flag Coverage Δ
macos-15 95.63% <99.02%> (+2.25%) ⬆️
macos-26 95.56% <99.02%> (+2.22%) ⬆️
swift 95.63% <99.02%> (+2.25%) ⬆️
swift-6.1 95.63% <99.02%> (+2.25%) ⬆️
swift-6.2 95.56% <99.02%> (+2.22%) ⬆️
xcode-16.3 95.63% <99.02%> (+2.25%) ⬆️
xcode-26 95.56% <99.02%> (+2.22%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@Sources/QsSwift/Internal/Decoder`+ParseList.swift:
- Around line 26-31: The call in parseObjectValue is relying on parseListValue's
default isFirstOccurrence=true which can wrongly trigger the overflow-map
branch; update the call in the parseObjectValue function to pass the actual
isFirstOccurrence boolean from its scope into parseListValue(_:, options:,
currentListLength:, isFirstOccurrence:) so that parseListValue receives the
correct occurrence flag rather than the default.

In `@Sources/QsSwift/Internal/Encoder.swift`:
- Around line 470-495: The swiftlint:disable:next function_parameter_count
comment only applies to canUseIterativeDeepFallback, leaving
encodeIterativeDeepFallback still triggering the rule; fix by either moving the
swiftlint suppression so it applies to both declarations (e.g., place a single
swiftlint:disable function_parameter_count before the
canUseIterativeDeepFallback declaration and re-enable after
encodeIterativeDeepFallback) or reduce parameters by introducing a parameter
object (e.g., a config/Options struct used by encodeIterativeDeepFallback and
canUseIterativeDeepFallback) and update calls to use that struct; reference the
functions canUseIterativeDeepFallback and encodeIterativeDeepFallback when
making the change.
🧹 Nitpick comments (7)
Sources/QsObjC/QsBridge+DecodeConvenience.swift (1)

35-35: Inconsistent brace placement style within the file.

Lines 35 and 62 now place the opening brace at the end of the function signature, while similar functions at lines 77-79 and 89-93 still place it on a new line. Consider aligning the brace placement style across all functions in this file for consistency.

🔧 Option to align with lines 77-79, 89-93 style
-        public static func decodeOrNil(_ input: Any?, options: DecodeOptionsObjC?) -> NSDictionary? {
+        public static func decodeOrNil(_ input: Any?, options: DecodeOptionsObjC?)
+            -> NSDictionary?
+        {
-        public static func decodeOrEmpty(_ input: Any?, options: DecodeOptionsObjC?) -> NSDictionary {
+        public static func decodeOrEmpty(_ input: Any?, options: DecodeOptionsObjC?)
+            -> NSDictionary
+        {

Also applies to: 62-62

Sources/QsSwift/Internal/Decoder+ParseQuery.swift (1)

135-142: Consider extracting the overflow-aware length computation into a small helper.

The currentLen closure computes list length from three different representations ([Any], [Any?], overflow map). Since this pattern of "get virtual array length" might be reused elsewhere (e.g., in Utils.combine or other merge logic), a tiny static helper like Utils.effectiveListLength(_:) could reduce duplication and make the intent clearer.

Sources/QsObjC/Models/DecodeOptionsObjC.swift (1)

129-136: Normalization logic looks good overall; normalizedDecodeDotInKeys is tautological.

Line 130: decodeDotInKeys && normalizedAllowDots is always equivalent to just decodeDotInKeys, because whenever decodeDotInKeys is true, normalizedAllowDots (line 129) is also true. The && guard is therefore redundant. This is harmless but slightly misleading.

Sources/QsSwift/Internal/NSMapTable+Linux.swift (1)

54-61: Silent no-op when key doesn't conform to NSObject in weak mode.

Lines 55 and 71: if the key can't be cast to NSObject, the method silently returns (no insertion, no error). This matches the previous behavior but is worth documenting, as it could silently drop entries on Linux if non-NSObject keys are used.

Sources/QsSwift/Internal/Utils+Merge.swift (1)

355-355: SwiftLint: remove explicit = nil initialization.

Static analysis flags implicit_optional_initialization — optional variables are implicitly nil.

Proposed fix
-        var completed: [AnyHashable: Any]? = nil
+        var completed: [AnyHashable: Any]?
Sources/QsSwift/Internal/Encoder.swift (1)

67-92: Iterative fallback gate looks solid; key-ordering diverges from the recursive path for dictionaries.

When encoder != nil, the recursive path at depth > 0 partitions dictionary keys (primitives before containers) and sorts each half. The iterative fallback iterates keys in arbitrary/insertion order regardless. At depth ≥ 512 with a non-nil encoder, the output order could differ from what the recursive path would produce for the same subtree.

This is unlikely to matter in practice (queries that deep are extreme edge cases, and canUseIterativeDeepFallback is already very conservative), but worth noting if strict ordering parity with the recursive path is a goal.

Tests/QsSwiftTests/EncodeTests.swift (1)

3815-3849: 250K-element array in encoder_iterativeFallback_largeAcyclic_noFalseCycle may slow CI.

The test allocates 250_001 empty arrays to verify no false-positive cycle detection. While correct, this could be slow on resource-constrained CI runners. Consider whether a smaller count (e.g., 10K–50K) would still exercise the hash-set growth path adequately.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces several robustness and compatibility improvements to the QsSwift query string encoder/decoder library. The changes focus on handling deeply nested structures without stack overflow, maintaining parity with the upstream JavaScript qs library (version 6.14.2), and ensuring proper charset validation and Data encoding.

Changes:

  • Added iterative fallback encoding/merging to prevent stack overflow with deeply nested structures (depth >= 512)
  • Implemented qs@6.14.2 parity for comma list overflow behavior, falling back to indexed-object representation on first occurrence
  • Enhanced options validation in Objective-C bridge layers to normalize charset values and enforce minimum limits
  • Fixed Data encoding to respect charset parameter instead of using debug string representation
  • Updated dependencies (ReerKit 1.2.2 → 1.2.5, qs 6.14.1 → 6.14.2)
  • Various code style improvements (trailing commas, line breaks, pattern matching consistency)

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Package.swift Updated ReerKit dependency to 1.2.5 for Linux builds
Package@swift-5.10.swift Updated ReerKit dependency to 1.2.5 for Swift 5.10 compatibility
Tools/QsSwiftComparison/js/package.json Updated qs reference library to 6.14.2
Tools/QsSwiftComparison/js/package-lock.json Updated qs package lock with new version and integrity hash
Sources/QsSwift/Internal/Encoder.swift Added iterative deep fallback encoder, fixed Data charset handling in describe functions
Sources/QsSwift/Internal/Decoder+ParseList.swift Added overflow fallback logic for comma lists on first occurrence
Sources/QsSwift/Internal/Decoder+ParseQuery.swift Enhanced currentListLength calculation to include overflow maps, added isFirstOccurrence tracking
Sources/QsSwift/Internal/Utils+Merge.swift Replaced recursive dictionary merge with iterative stack-based implementation
Sources/QsSwift/Internal/Utils.swift Updated case pattern matching style for consistency
Sources/QsSwift/Internal/NSMapTable+Linux.swift Added strongToStrongObjects support with enum-based storage mode dispatch
Sources/QsSwift/Models/DecodeOptions.swift Reformatted typealias for better readability
Sources/QsSwift/Models/EncodeOptions.swift Reformatted typealias for better readability
Sources/QsSwift/Qs+Encode.swift Minor line break formatting for better readability
Sources/QsObjC/Models/DecodeOptionsObjC.swift Added normalization for charset, parameterLimit, depth, and dot-key handling
Sources/QsObjC/Models/EncodeOptionsObjC.swift Added charset normalization to default invalid values to utf8
Sources/QsObjC/QsBridge+DecodeConvenience.swift Formatting cleanup for function signatures
Tests/QsSwiftTests/DecodeTests.swift Added tests for comma overflow fallback and deep merge scenarios
Tests/QsSwiftTests/EncodeTests.swift Added tests for Data encoding, deep nesting, iterative fallback branches, and strictNullHandling
Tests/QsSwiftTests/UtilsTests.swift Added deep merge test, minor formatting fixes (spacing, trailing commas)
Tests/QsSwiftTests/Fixtures/DummyEnum.swift Removed trailing blank line
Tests/QsObjCTests/ObjCModelCoverageTests.swift Added sanitization tests, formatting improvements
Tests/QsObjCTests/ObjCExampleTests.swift Whitespace cleanup
Tests/QsObjCTests/ObjCEncodeTests.swift Added test for Data encoding with encode=false
Tests/QsObjCTests/ObjCDecodeTests.swift Added tests for comma overflow fallback behavior
Tests/QsObjCTests/ObjCBridgeTests.swift Formatting improvements (trailing commas, line breaks)
Files not reviewed (1)
  • Tools/QsSwiftComparison/js/package-lock.json: Language not supported

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 776961a94e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@techouse techouse requested a review from Copilot February 15, 2026 19:29
@techouse
Copy link
Owner Author

@codex review

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 26 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • Tools/QsSwiftComparison/js/package-lock.json: Language not supported

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 06df6aefd0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@Tests/QsSwiftTests/EncodeTests.swift`:
- Around line 4068-4108: The test
encoder_iterativeFallback_preservesDictionaryOrderingParity uses a plain
[String: Any] fixture (data) but performs an order-sensitive equality check
between recursiveParts and fallbackParts; replace data with an OrderedDictionary
preserving insertion order or change the final assertion to an order-insensitive
comparison (e.g., compare sets or sorted arrays) so the parity check does not
depend on unspecified Dictionary ordering; update references in encodeParts,
recursiveParts, and fallbackParts accordingly to keep the test deterministic.

@techouse
Copy link
Owner Author

@codex review

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 26 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • Tools/QsSwiftComparison/js/package-lock.json: Language not supported

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@Sources/QsSwift/Internal/Utils`+Merge.swift:
- Around line 357-362: When assigning a nested merge result into a parent frame
(inside the while loop that pops stack frames and uses frame.pendingKey,
frame.target and completed), also update the parent overflow max if the parent
is an overflow target: detect when frame.target supports overflowMax (the
overflow dict type/property) and when childResult is either an overflow dict
(has its own overflowMax) or a plain dict with integer-string keys; compute the
child's max index (use child.overflowMax if present, otherwise parse integer
keys and take max) and set frame.target.overflowMax =
max(frame.target.overflowMax, childMax) before clearing frame.pendingKey and
completed so the parent’s stored max stays current when nested dictionaries are
merged.

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
Sources/QsSwift/Internal/Encoder.swift (1)

758-765: Remove unnecessary Array allocation in UTF-8 decoding.

String(decoding: Array(data), as: UTF8.self) creates an unnecessary copy in a hot path. Data is a Collection<UInt8> and can be passed directly to the initializer.

♻️ Suggested change
-            return String(decoding: Array(data), as: UTF8.self)
+            return String(decoding: data, as: UTF8.self)

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 26 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • Tools/QsSwiftComparison/js/package-lock.json: Language not supported

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@Sources/QsSwift/Internal/Decoder`+ParseQuery.swift:
- Around line 287-299: The function overflowElementsAsArray currently allocates
an array of size maxIndex+1 based on comma-split indices which can be huge;
modify overflowElementsAsArray to guard against unbounded allocation by checking
the computed size against the parser's listLimit (or a sensible threshold) and
if maxIndex+1 exceeds that limit, avoid allocating the large array and instead
return the original sparse overflow map (or an empty/safe fallback) so
parseListValue can continue using the overflow form; reference
overflowElementsAsArray, Utils.intIndex, Utils.isOverflowKey and ensure the
check uses the same listLimit used by parseListValue so you cap or bypass
allocation when maxIndex+1 > listLimit.
🧹 Nitpick comments (4)
Sources/QsSwift/Internal/Encoder.swift (1)

757-767: Address SwiftLint optional_data_string_conversion warning on line 764.

The use of String(decoding:as:) here is intentional — it's the non-failable initializer that replaces malformed sequences with U+FFFD, keeping the payload visible. The failable String(bytes:encoding:) is already used on line 759. Consider adding an inline disable to silence the lint warning and document the intent:

Proposed fix
         if charset == .utf8 {
             // Keep payload visible for malformed UTF-8 instead of collapsing to empty.
+            // swiftlint:disable:next optional_data_string_conversion
             return String(decoding: data, as: UTF8.self)
         }
Tests/QsSwiftTests/EncodeTests.swift (2)

4989-4993: Force-unwrap in custom encoder closure could crash if contract changes.

Line 4992 force-unwraps value! after checking value == nil on Line 4991. In a test this is low-risk, but the == nil check on Any? can behave unexpectedly with Optional<Optional<…>> (double-wrapped optionals). A safer pattern is guard let v = value else { ... }.

🔧 Safer unwrap
-            if value == nil { return "null_token" }
-            return "v_\(String(describing: value!))"
+            guard let v = value else { return "null_token" }
+            return "v_\(String(describing: v))"

4831-4864: Large acyclic input test allocates 250 001 empty arrays — verify this doesn't slow CI.

Array(repeating: [Any](), count: 250_001) is intentionally large to test false-cycle detection, but this may cause noticeable test-suite slowdowns on constrained CI runners. Consider adding a comment noting the intentional size, or reducing to a still-large-but-cheaper count if the threshold being tested allows it.

Tests/QsObjCTests/ObjCConvenienceTests.swift (1)

111-121: !Thread.isMainThread assertion could be flaky in edge cases.

Line 115 asserts !Thread.isMainThread, but DispatchQueue.global().async doesn't guarantee off-main execution in all runtime configurations (e.g., if the main thread happens to service the global queue). This is extremely unlikely in practice but worth noting. The decodeAsyncOnMain test's Thread.isMainThread assertion is safe because it explicitly dispatches to DispatchQueue.main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant