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

Node6 incompatibilities with querystrings #571

Open
cmidkiff87 opened this issue Jun 19, 2020 · 6 comments
Open

Node6 incompatibilities with querystrings #571

cmidkiff87 opened this issue Jun 19, 2020 · 6 comments

Comments

@cmidkiff87
Copy link

cmidkiff87 commented Jun 19, 2020

Node 6 changed the querystring.parse to return an object whose __proto__ property no longer points back to Object. This was done to allow for more esoteric query string names, such as https://example.com/route?__proto__=some-value, which would conflict with the native js object properties.

However, this causes js-data to error when calling hasOwnProperty() if you pass it the querystring object.

This is especially problematic when using js-data-http as it automatically sends the requests with the url's query strings in the format js-data expects.

It can be fixed by using

Object.prototype.hasOwnProperty(query, propKey);

in place of

query.hasOwnProperty(propKey);

The libraries involved are

  • api:
    • node 5.11.1 // yikes
    • node 6.17.1
    • js-data 3.0.8
    • koa 1.7.0
  • webapp
    • js-data 3.0.0-rc.4
    • js-data-http 3.0.0-rc.2

It can also be fixed externally by shimming the hasOwnProperty() function onto the querystring

exports.jsData = function() {
  // koa 1.x middleware
  return function*(next) {
    this.jsData = {};

    // `this.query` is the result of the `querystring.parse()` function
    this.jsData.query = this.query; 
    
    function hasOwnPropertyShim(key) {
      // `this` === `this.jsData.query`
      return Object.hasOwnProperty.call(this, key);
    }

    // make the prop unenumerable, or it will get included in the sql query
    Object.defineProperty(this.jsData.query, 'hasOwnProperty', {
      value: hasOwnPropertyShim,
      enumerable: false,
    });

    // ...
  }
}

However, that solution isn't super intuitive without some digging

@zuzusik
Copy link
Contributor

zuzusik commented Jul 13, 2020

Node 6 has been out of support for quite a time now. Is it also reproducible in newer versions of Node?

@cmidkiff87
Copy link
Author

Yes, I can't remember exactly which versions I've tried it with, but the latest (14.x) docs state that

The object returned by the querystring.parse() method does not prototypically inherit from the JavaScript Object. This means that typical Object methods such as obj.toString(), obj.hasOwnProperty(), and others are not defined and will not work.

Of course, this is only an issue when passing the parsed querystring object directly to js-data (as we have), and is "fixable" by shimming the object with the required functions.

@crobinson42
Copy link
Member

crobinson42 commented Jul 13, 2020 via email

@cmidkiff87
Copy link
Author

Then perhaps there should be a note about this somewhere in the documentation, rather than updating js-data?

(since this is probably more of an issue for upgrading legacy projects than it is for new projects)

@crobinson42
Copy link
Member

crobinson42 commented Jul 13, 2020 via email

@zuzusik
Copy link
Contributor

zuzusik commented Jul 13, 2020 via email

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

No branches or pull requests

3 participants