Skip to content

Off-by-one in 1.x urlencoded parameterCount breaks parsing arrays #715

@krzysdz

Description

@krzysdz

Discovered in expressjs/express#7135.

parameterCount has an off-by-one bug (returns 0 for "a=x", 1 for "a=x&b=y", ...). This in turn causes an array like "a[0]=1&a[1]=2&...&a[199]=200" to be parsed by qs with arrayLimit: 199.
This used to work, because arrayLimit: 199 would allow the index to be at most 199. qs@6.14.2 changed arrayLimit behaviour to instead restrict the array length (ljharb/qs#540 (comment), ljharb/qs@cfc108f, 6.14.2 changelog).

2.x uses a slightly different function and returns the real number of parameters.

More context on the differences: #652 (comment)

Environment information

Version: 1.20.4

Platform: Microsoft Windows NT 10.0.19045.0 x64

Node.js version: 25.8.2

Any other relevant information: When using public API, the problem can be observed only with qs >=6.14.2

What steps will reproduce the bug?

  1. Try parsing a large (>100 elements) array using extended urlencoded parser

Alternatively:

  1. Run npm test, the following test will fail:
    it('should parse array index notation with large array', function (done) {
    var str = 'f[0]=0'
    for (var i = 1; i < 500; i++) {
    str += '&f[' + i + ']=' + i.toString(16)
    }
    request(this.server)
    .post('/')
    .set('Content-Type', 'application/x-www-form-urlencoded')
    .send(str)
    .expect(function (res) {
    var obj = JSON.parse(res.text)
    assert.strictEqual(Object.keys(obj).length, 1)
    assert.strictEqual(Array.isArray(obj.f), true)
    assert.strictEqual(obj.f.length, 500)
    })
    .expect(200, done)
    })

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions