Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

check the arguments number of URLSearchParams #1390

Merged
merged 4 commits into from
Dec 24, 2018

Conversation

justjavac
Copy link
Contributor

URLSearchParams did not check the number of arguments passed, thereby causing some bugs.

When we use TypeScript, the tsc compiler will do parameter checking for us, but many times we write code in JavaScript.

let s = new URLSearchParams()
s.append()

// before
s.toString() === "undefined=undefined"

// after fix
// TypeError: URLSearchParams.append requires at least 2 arguments, but only 0 present

In addition, the first argument should be converted to string type

let s = new URLSearchParams()

// the `String` wrapper
s.set(new String("foo"), "bar")

// When calling `toString`, the keys and values are converted to strings
s.toString() === "foo=bar"

// but...

// before
s.has('foo') === false
s.get('foo') === null

// after fix
s.has('foo') === true
s.get('foo') === "bar"

@justjavac
Copy link
Contributor Author

another question: should the private field params in URLSearchParams be moved outside the class, inside the module?

The private fields/methods in TypeScript will only be checked by the compiler and then compiled into a normal js field.

in js file:

// @ts-nocheck
s.set('foo', 'bar')
console.log(s.params)

will output [ [ "foo", "bar" ] ].

js/url_search_params.ts Outdated Show resolved Hide resolved
@ry
Copy link
Member

ry commented Dec 23, 2018

BTW does this match browser behavior?

@justjavac
Copy link
Contributor Author

yes, I tested in 3 browsers and Node.

let s = new URLSearchParams()
s.append()

// Firefox 66.0(a1)
// TypeError: URLSearchParams.append requires at least 2 arguments, but only 0 were passed

// Chrome 73.0.3649.0
// TypeError: Failed to execute 'append' on 'URLSearchParams': 2 arguments required, but only 0 present.

// Edge 17.17134
// 参数是必选项 
// Edge uses localized messages. I don't have English version of the browser, can only translate the general meaning: "Parameter is Required".

// Node 10.13.0
// TypeError [ERR_MISSING_ARGS]: The "name" and "value" arguments must be specified

// --------------------------

s.set(new String("foo"), "bar")

// Firefox, Chrome, Edge, Node
s.toString()    // "foo=bar"
s.has("foo")    // true
s.get("foo")    // "bar"

In the current implementation of deno, we use TypeScript‘s private field params, and Node.js uses Symbol. Although Symbol can create a unique key to prevent external direct access to its value, we can still get it through getOwnPropertySymbols:

// Firefox, Chrome, Edge
Object.getOwnPropertySymbols(s)    // []

// Node
Object.getOwnPropertySymbols(s) 
// [ Symbol(query), Symbol(context) ]

const [ query, context ] = Object.getOwnPropertySymbols(s)
for (let k of Object.getOwnPropertySymbols(s)) {
    console.log(k, s[k])
}
s[query]    // [ 'foo', 'bar' ]
s[context]  // null

// Deno
s.params
// [ [ "foo", "bar" ] ]

Node uses a flat array, and Deno uses a two-dimensional array. Node is more graceful, but not compatible with the browser. If Deno wants to be compatible with the browser, then we can only move params outside URLSearchParams, inside the module, until V8 implements private class fields.

Maybe we can not care about private class field params right now(if there is no security risk for access to private field), we should just wait for TypeScript Implement private fields proposal #9950

Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

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

LGTM - thanks!

@ry ry merged commit 7d0e105 into denoland:master Dec 24, 2018
ry added a commit to ry/deno that referenced this pull request Dec 24, 2018
- "cargo build" support (denoland#1369 denoland#1296 denoland#1377 denoland#1379)
- Remove support for extensionless import (denoland#1396)
- Upgrade V8 to 7.2.502.16 (denoland#1403)
- make stdout unbuffered (denoland#1355)
- Implement `Body.formData` for fetch (denoland#1393)
- Improve handling of non-coercable objects in assertEqual (denoland#1385)
- Avoid fetch segfault on empty Uri (denoland#1394)
- Expose deno.inspect (denoland#1378)
- Add illegal header name and value guards (denoland#1375)
- Fix URLSearchParams set() and constructor() (denoland#1368)
- Remove prebuilt v8 support (denoland#1369)
- Enable jumbo build in release. (denoland#1362)
- Add URL implementation (denoland#1359)
- Add console.count and console.time (denoland#1358)
- runtime arg check `URLSearchParams` (denoland#1390)
ry added a commit to ry/deno that referenced this pull request Dec 24, 2018
- "cargo build" support (denoland#1369 denoland#1296 denoland#1377 denoland#1379)
- Remove support for extensionless import (denoland#1396)
- Upgrade V8 to 7.2.502.16 (denoland#1403)
- make stdout unbuffered (denoland#1355)
- Implement `Body.formData` for fetch (denoland#1393)
- Improve handling of non-coercable objects in assertEqual (denoland#1385)
- Avoid fetch segfault on empty Uri (denoland#1394)
- Expose deno.inspect (denoland#1378)
- Add illegal header name and value guards (denoland#1375)
- Fix URLSearchParams set() and constructor() (denoland#1368)
- Remove prebuilt v8 support (denoland#1369)
- Enable jumbo build in release. (denoland#1362)
- Add URL implementation (denoland#1359)
- Add console.count and console.time (denoland#1358)
- runtime arg check `URLSearchParams` (denoland#1390)
ry added a commit that referenced this pull request Dec 24, 2018
- "cargo build" support (#1369 #1296 #1377 #1379)
- Remove support for extensionless import (#1396)
- Upgrade V8 to 7.2.502.16 (#1403)
- make stdout unbuffered (#1355)
- Implement `Body.formData` for fetch (#1393)
- Improve handling of non-coercable objects in assertEqual (#1385)
- Avoid fetch segfault on empty Uri (#1394)
- Expose deno.inspect (#1378)
- Add illegal header name and value guards (#1375)
- Fix URLSearchParams set() and constructor() (#1368)
- Remove prebuilt v8 support (#1369)
- Enable jumbo build in release. (#1362)
- Add URL implementation (#1359)
- Add console.count and console.time (#1358)
- runtime arg check `URLSearchParams` (#1390)
@justjavac justjavac deleted the fix-url-search-params branch December 24, 2018 04:43
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.

None yet

3 participants