Commit 4d53833f authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[regexp] Unconditionally get named capture in GetSubstitution

Prior to this CL we still implemented a HasProperty-GetProperty
sequence when accessing named captures in GetSubstitution. This was
briefly part of the spec (we also threw an exception when the property
was not present), but since late 2017 the GetProperty call has been
unconditional.

See https://tc39.es/ecma262/#sec-getsubstitution.

Bug: v8:10513
Change-Id: Id82c06958b0b0feffc6eede580b99ab8676a0dae
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2195821
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Sathya Gunasekaran  <gsathya@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67733}
parent bdda9953
......@@ -1114,13 +1114,8 @@ MaybeHandle<String> String::GetSubstitution(Isolate* isolate, Match* match,
isolate, capture,
match->GetNamedCapture(capture_name, &capture_state), String);
switch (capture_state) {
case CaptureState::INVALID:
case CaptureState::UNMATCHED:
break;
case CaptureState::MATCHED:
if (capture_state == CaptureState::MATCHED) {
builder.AppendString(capture);
break;
}
continue_from_ix = closing_bracket_ix + 1;
......
......@@ -259,9 +259,9 @@ class String : public TorqueGeneratedString<String, Name> {
virtual Handle<String> GetPrefix() = 0;
virtual Handle<String> GetSuffix() = 0;
// A named capture can be invalid (if it is not specified in the pattern),
// unmatched (specified but not matched in the current string), and matched.
enum CaptureState { INVALID, UNMATCHED, MATCHED };
// A named capture can be unmatched (either not specified in the pattern,
// or specified but unmatched in the current string), or matched.
enum CaptureState { UNMATCHED, MATCHED };
virtual int CaptureCount() = 0;
virtual bool HasNamedCaptures() = 0;
......
......@@ -938,8 +938,8 @@ class MatchInfoBackedMatch : public String::Match {
*capture_name_map_);
if (capture_index == -1) {
*state = INVALID;
return name; // Arbitrary string handle.
*state = UNMATCHED;
return isolate_->factory()->empty_string();
}
DCHECK(1 <= capture_index && capture_index <= CaptureCount());
......@@ -1015,15 +1015,6 @@ class VectorBackedMatch : public String::Match {
CaptureState* state) override {
DCHECK(has_named_captures_);
Maybe<bool> maybe_capture_exists =
JSReceiver::HasProperty(groups_obj_, name);
if (maybe_capture_exists.IsNothing()) return MaybeHandle<String>();
if (!maybe_capture_exists.FromJust()) {
*state = INVALID;
return name; // Arbitrary string handle.
}
Handle<Object> capture_obj;
ASSIGN_RETURN_ON_EXCEPTION(isolate_, capture_obj,
Object::GetProperty(isolate_, groups_obj_, name),
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const access_log = [];
const handler = {
get: function(obj, prop) {
access_log.push(prop);
return prop in obj ? obj[prop] : "z";
}
};
class ProxiedGroupRegExp extends RegExp {
exec(s) {
var result = super.exec(s);
if (result) {
result.groups = new Proxy(result.groups, handler);
}
return result;
}
}
let re = new ProxiedGroupRegExp("(?<x>.)");
assertEquals("a z", "a".replace(re, "$<x> $<y>"));
assertEquals(["x", "y"], access_log);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment