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

Converting String-object to Buffer fails to copy data #13652

Closed
mvduin opened this issue Jun 13, 2017 · 11 comments
Closed

Converting String-object to Buffer fails to copy data #13652

mvduin opened this issue Jun 13, 2017 · 11 comments
Labels
buffer Issues and PRs related to the buffer subsystem.

Comments

@mvduin
Copy link

mvduin commented Jun 13, 2017

  • Version: v8.1.0

Creating a buffer from a String object results in a zero-filled buffer (of length equal to the string length in UTF-16 code-units):

> Buffer.from(new String("Hello world"))
<Buffer 00 00 00 00 00 00 00 00 00 00 00>
> Buffer.from(new String("\u{1F4A9}"))
<Buffer 00 00>
@bnoordhuis bnoordhuis added the buffer Issues and PRs related to the buffer subsystem. label Jun 13, 2017
@bnoordhuis
Copy link
Member

bnoordhuis commented Jun 13, 2017

It's because there is no special treatment for string objects, they are interpreted as array-like objects with their elements coerced to numeric values. That is, these are all equal:

Buffer.from(new String('x'));
Buffer.from({ length: 1, [0]: 'x' });
Buffer.from({ length: 1, [0]: +'x' });  // +'x' -> Nan -> 0

Node has no special treatment for string objects elsewhere either so it's a bit of an open question if we should do it here.

@mvduin
Copy link
Author

mvduin commented Jun 13, 2017

Ah... eww... okay.

I had hoped to use a String subclass to mark certain strings as having some particular semantic value, but somewhere down the road they get converted to buffer in third party code.... oh well, it briefly seemed like a good idea.

With the introduction of things like String subclasses, Symbol.toPrimitive, etc it would definitely have been nice if they had also included an authoritive way code can figure out how it's supposed to treat objects... "are you trying to be an array? a string? a number maybe?"

@benjamingr
Copy link
Member

@mvduin just to be clear - what would you expect the behavior to be in this case noting:

> var s = new String()
> s[Symbol.toPrimitive](); // uncaught type error s[Symbol.toPrimitive] is not a function

?

@mvduin
Copy link
Author

mvduin commented Jun 14, 2017

That's not what I meant, but never mind - you can ignore that bit of my comment.

@jasnell
Copy link
Member

jasnell commented Jun 14, 2017

@mvduin ... the easiest thing to do would be just:

Buffer.from(new String('test').valueOf());
// or
Buffer.from(new String('test').toString());

That would allow you to do the String subclassing.

That said, I can see a case being made to allow Buffer.from() to accept objects that support Symbol.toPrimitive(). Will have to give that one some thought.

@bnoordhuis
Copy link
Member

I think a reasonable case can be made that the current behavior is confusing and possibly insecure in some circumstances. Consider how a string of digits is parsed differently based on whether the value is a primitive string or a string object:

> Buffer.from(String('0123456789')).toString()
'0123456789'

Vs.

> Buffer.from(new String('0123456789')).toString()
'\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t'

You wouldn't write such code directly but if you pass in a variable x without knowing if x is primitive or not, you'll get confusing results.

@mvduin
Copy link
Author

mvduin commented Jun 15, 2017

Exactly, the issue didn't happen directly in my code but in third party code that got my non-primitive strings somewhere down the road and transmitted them over a socket

@joyeecheung
Copy link
Member

joyeecheung commented Jun 16, 2017

@mvduin I think in this case there is a somewhat related symbol, it's Symbol.iterator instead of Symbol.toPrimitive(minus the fact that boxed types doesn't have Symbol.toPrimitive defined, but I got your point), because it does not really make sense to do Buffer.from(new Number(1)).

I think it's an open question how Buffer.from(boxedString) should be interpreted, but if an encoding is passed as the second argument, it makes sense to the convert the first argument to a string value using toString().

@ryzokuken
Copy link
Contributor

Does this still need to stay open?

/cc @jasnell

@ryzokuken
Copy link
Contributor

This seems to be resolved in #13725, but I may be wrong, in which case, please feel free to reopen this.

@mvduin
Copy link
Author

mvduin commented May 21, 2018

Looks good to me, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
buffer Issues and PRs related to the buffer subsystem.
Projects
None yet
Development

No branches or pull requests

6 participants