Skip to content

Conversation

techouse
Copy link
Contributor

@techouse techouse commented Aug 26, 2025

Problem

qs splits bracket groups with a regex that forbids [] inside a group:

var child = /(\[[^[][^\]]*])/g; // original: /(\[[^[\]]*])/g

This causes keys like search[withbracket[]] to split into "[withbracket]", then "[]", leaving the inner [] detached from the literal segment. Downstream, it can no longer be treated as a single literal key.

Repro

// expected:
qs.parse('search[withbracket[]]=foobar');
// => { search: { 'withbracket[]': 'foobar' } }

// actual (today):
// inner [] is split out, so the key can’t be treated as one literal segment

Fix approach

Backport splitKeyIntoSegments from qs_dart and replace the regex child matcher with a balanced bracket splitter that treats [] inside a bracket group as literal content (only outer [] act as array push). This preserves withbracket[] as a single segment.

Notes

  • Does not change existing semantics for [] at the outermost level (array push).
  • Honors existing options: allowDots, depth, strictDepth, allowPrototypes, etc.

Test snippet

t.test('parses keys with literal [] inside a bracket group (#493)', function (st) {
    // A bracket pair inside a bracket group should be treated literally as part of the key
    st.deepEqual(
        qs.parse('search[withbracket[]]=foobar'),
        { search: { 'withbracket[]': 'foobar' } },
        'treats inner [] literally when inside a bracket group'
    );

    // Single-level variant
    st.deepEqual(
        qs.parse('a[b[]]=c'),
        { a: { 'b[]': 'c' } },
        'keeps "b[]" as a literal key'
    );

    // Nested with an array push on the outer level
    st.deepEqual(
        qs.parse('list[][x[]]=y'),
        { list: [{ 'x[]': 'y' }] },
        'preserves inner [] while still treating outer [] as array push'
    );

    st.end();
});

Fixes #493

@techouse techouse changed the title Fix incorrect parsing of nested params with closing square bracket ] in property name Fix parsing of keys containing literal [] inside bracket groups Aug 27, 2025
@techouse techouse changed the title Fix parsing of keys containing literal [] inside bracket groups Fix parsing of keys containing literal [] inside bracket groups Aug 27, 2025
@techouse
Copy link
Contributor Author

techouse commented Aug 28, 2025

@ljharb, it seems some of the tests fail because the runners are unable to download a specific Node version, i.e.

curl: (56) OpenSSL SSL_read: Connection reset by peer, errno 104
download from https://nodejs.org/dist/v5.3.0/node-v5.3.0-linux-x64.tar.xz failed
grep: /home/runner/.nvm/.cache/bin/node-v5.3.0-linux-x64/node-v5.3.0-linux-x64.tar.xz: No such file or directory
curl: (92) HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
download from https://nodejs.org/dist/v13.13.0/node-v13.13.0-linux-x64.tar.xz failed
grep: /home/runner/.nvm/.cache/bin/node-v13.13.0-linux-x64/node-v13.13.0-linux-x64.tar.xz: No such file or directory

@techouse
Copy link
Contributor Author

@ljharb, have you had a chance to look at this yet? 😊

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.

Incorrect parsing of nested params with closing square bracket ] in property name
1 participant