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

buffer: fix indexOf for empty searches #13024

Closed
wants to merge 2 commits into from

Conversation

addaleax
Copy link
Member

@addaleax addaleax commented May 14, 2017

Make searches for empty subsequences return 0 for buffer.indexOf()
and buffer.length for buffer.lastIndexOf(), because those
are the indices of the first and last occurrence of an empty
subsequence, respectively.

Make searches for empty subsequences do exactly what String.prototype.indexOf() does.

Fixes: #13023

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

buffer

/cc @nodejs/buffer and because people might to consider this a semver-major change (I would not) @nodejs/ctc

CI: https://ci.nodejs.org/job/node-test-commit/9880/

@nodejs-github-bot nodejs-github-bot added buffer Issues and PRs related to the buffer subsystem. c++ Issues and PRs that require attention from people who are familiar with C++. labels May 14, 2017
@Trott
Copy link
Member

Trott commented May 14, 2017

Q: semver-major?

@Trott
Copy link
Member

Trott commented May 14, 2017

Documentation update to include this info? MDN mentions the behavior in its docs for String.prototype.lastIndexOf() and String.prototype.indexOf() and we should probably follow suit.

assert.strictEqual(b.indexOf('', b.length + 1), -1);
assert.strictEqual(b.indexOf('', Infinity), -1);
assert.strictEqual(b.indexOf(''), 0);
assert.strictEqual(b.indexOf('', 1), 0);
Copy link
Member

Choose a reason for hiding this comment

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

To match the behavior of String.prototype.indexOf(), this should return 1 rather than 0.

assert.strictEqual(b.indexOf('', Infinity), -1);
assert.strictEqual(b.indexOf(''), 0);
assert.strictEqual(b.indexOf('', 1), 0);
assert.strictEqual(b.indexOf('', b.length + 1), 0);
Copy link
Member

Choose a reason for hiding this comment

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

To match the behavior of String.prototype.indexOf(), this should return b.length, not 0.

assert.strictEqual(b.indexOf(''), 0);
assert.strictEqual(b.indexOf('', 1), 0);
assert.strictEqual(b.indexOf('', b.length + 1), 0);
assert.strictEqual(b.indexOf('', Infinity), 0);
Copy link
Member

Choose a reason for hiding this comment

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

To match the behavior of String.prototype.indexOf(), this should return b.length, not 0.

@addaleax addaleax force-pushed the buffer-indexof-emptystring branch 2 times, most recently from ce70e2d to 8bcee3f Compare May 14, 2017 19:38
@addaleax
Copy link
Member Author

@@ -1340,6 +1340,10 @@ console.log(b.indexOf('b', null));
console.log(b.indexOf('b', []));
```

If `value` is an empty string or `Buffer` and `byteOffset` is less
Copy link
Member

Choose a reason for hiding this comment

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

Nit: empty string or empty Buffer would avoid confusion over whether or not the Buffer must be empty.

Might be even simpler to replace is an empty string or Buffer with is empty or has a length of zero?

If value is empty and byteOffset is less

or

If value has a length of zero and byteOffset is less

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea, makes sense. I went with the former because is empty sounds a bid odd to me (like empty/undefined variables?), and has a length of zero doesn’t make sense for integer input (and users can figure that out, but, you know), so I chose the imho explicit version.

@@ -1450,6 +1454,8 @@ console.log(b.lastIndexOf('b', null));
console.log(b.lastIndexOf('b', []));
```

If `value` is an empty string or `Buffer`, `byteOffset` will be returned.
Copy link
Member

Choose a reason for hiding this comment

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

Same as above comment.

Make searches for empty subsequences do exactly what
`String.prototype.indexOf()` does.

Fixes: nodejs#13023
@addaleax addaleax force-pushed the buffer-indexof-emptystring branch from 8bcee3f to bb875a5 Compare May 14, 2017 19:54
Copy link
Member

@Trott Trott left a comment

Choose a reason for hiding this comment

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

LGTM to me if CI is green and doc nits are addressed. Not sure about the semver-ness here, but maybe CITGM run results would help make the case for patch vs. major?

@addaleax
Copy link
Member Author

@refack
Copy link
Contributor

refack commented May 15, 2017

Assuming previous Windows fails was infra. Rerunning: https://ci.nodejs.org/job/node-test-commit-windows-fanned/9084/

// Valid positive offset.
return offset_i64;
} else if (needle_length == 0) {
// Out of buffer bounds, but empty needle: point to end of buffer.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion:
Either ref - http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.indexof
Or state Same semantics as String.prototype.indexof

Copy link
Member Author

Choose a reason for hiding this comment

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

@refack Ack, added comments (at the GetReturnValue() sites)

Copy link
Contributor

Choose a reason for hiding this comment

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

👍
I was feeling it missing here (you explain "what" but not "why")

@addaleax
Copy link
Member Author

Landed in 28ddac2

@addaleax addaleax closed this May 18, 2017
@addaleax addaleax deleted the buffer-indexof-emptystring branch May 18, 2017 21:20
Trott pushed a commit to Trott/io.js that referenced this pull request May 18, 2017
Make searches for empty subsequences do exactly what
`String.prototype.indexOf()` does.

Fixes: nodejs#13023
PR-URL: nodejs#13024
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
Make searches for empty subsequences do exactly what
`String.prototype.indexOf()` does.

Fixes: nodejs#13023
PR-URL: nodejs#13024
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
@jasnell jasnell mentioned this pull request May 28, 2017
@gibfahn gibfahn mentioned this pull request Jun 15, 2017
3 tasks
@MylesBorins
Copy link
Contributor

@addaleax is this applicable for v6.x?

@MylesBorins
Copy link
Contributor

I'm going to opt to not land this on lts as it does change behavior of buffer. While it might be "more correct", I'd rather not pull the rug under people

/cc @addaleax @nodejs/ctc

@addaleax
Copy link
Member Author

I’m okay with that.

@mcollina
Copy link
Member

I'm ok as well.

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. c++ Issues and PRs that require attention from people who are familiar with C++.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

indexOf empty string in buffer should return 0
9 participants