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

Editorial: Revert unintentional normative change for String.prototype.substr #2844

Merged
merged 1 commit into from
Sep 21, 2022

Conversation

anba
Copy link
Contributor

@anba anba commented Aug 4, 2022

"a".substr(0, Infinity) should return "a", but #2007 incorrectly changed the result to be "".

If we change substr's algorithm to be more similar to String.prototype.substring and String.prototype.slice, we can easily fix this issue:

  1. min(intStart, size) guarantees that intStart is now in [0, size].
  2. Clamping intLength guarantees it's also in [0, size].

With these two changes, intEnd = min(intStart + intLength, size) is now in range [intStart, size], so we no longer have to check for intStart ≥ intEnd, but instead can directly perform the substring operation.

@ljharb ljharb added normative change Affects behavior required to correctly evaluate some ECMAScript source text spec bug labels Aug 4, 2022
@ljharb ljharb requested review from michaelficarra, syg, bakkot and a team August 4, 2022 07:33
anba added a commit to anba/test262 that referenced this pull request Aug 4, 2022
spec.html Outdated
Comment on lines 47529 to 47531
1. If _intStart_ is -∞, set _intStart_ to 0.
1. Else if _intStart_ < 0, set _intStart_ to max(_size_ + _intStart_, 0).
1. Else, set _intStart_ to min(_intStart_, _size_).
Copy link
Member

Choose a reason for hiding this comment

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

Can't we use clamping here, too?

Suggested change
1. If _intStart_ is -∞, set _intStart_ to 0.
1. Else if _intStart_ < 0, set _intStart_ to max(_size_ + _intStart_, 0).
1. Else, set _intStart_ to min(_intStart_, _size_).
1. If _intStart_ < 0, set _intStart_ to _size_ + _intStart_.
1. Set _intStart_ to the result of clamping _intStart_ between 0 and _size_.

Copy link
Contributor

Choose a reason for hiding this comment

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

That does arithmetic on an infinite value (-∞), which we've tried to avoid. If you restore the first line then the other changes are fine, though I don't think it's any clearer or more elegant, personally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And in addition to the -∞ issue, the current PR matches how String.prototype.slice is specified. If we should decide to use clamping, we should also update String.prototype.slice accordingly.

Copy link
Member

Choose a reason for hiding this comment

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

I still think the clamping is more clear, but @bakkot is right, we should leave the guard in for infinity. We can update String.prototype.slice in a separate PR if you want.

Copy link
Contributor

Choose a reason for hiding this comment

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

@michaelficarra If you approve this as-is I will submit a following changing both; no need to drag this PR out further.

@bakkot bakkot added the ready to merge Editors believe this PR needs no further reviews, and is ready to land. label Sep 21, 2022
….substr (tc39#2844)

`"a".substr(0, Infinity)` should return `"a"`, but tc39#2007 incorrectly changed the result to be `""`.

If we change `substr`'s algorithm to be more similar to
`String.prototype.substring` and `String.prototype.slice`, we can easily
fix this issue:

1. `min(intStart, size)` guarantees that `intStart` is now in `[0, size]`.
2. Clamping `intLength` guarantees it's also in `[0, size]`.

With these two changes, `intEnd = min(intStart + intLength, size)` is
now in range `[intStart, size]`, so we no longer have to check for
`intStart ≥ intEnd`, but instead can directly perform the `substring`
operation.
@ljharb ljharb merged commit 262e214 into tc39:main Sep 21, 2022
catamorphism pushed a commit to catamorphism/test262 that referenced this pull request Oct 4, 2022
catamorphism pushed a commit to catamorphism/test262 that referenced this pull request Oct 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
normative change Affects behavior required to correctly evaluate some ECMAScript source text ready to merge Editors believe this PR needs no further reviews, and is ready to land. spec bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants