@@ -5380,24 +5380,31 @@ Reduction JSCallReducer::ReduceArrayPrototypePop(Node* node) {
5380
5380
}
5381
5381
5382
5382
// Compute the new {length}.
5383
- length = graph ()->NewNode (simplified ()->NumberSubtract (), length,
5384
- jsgraph ()->OneConstant ());
5383
+ Node* new_length = graph ()->NewNode (simplified ()->NumberSubtract (),
5384
+ length, jsgraph ()->OneConstant ());
5385
+
5386
+ // This extra check exists solely to break an exploitation technique
5387
+ // that abuses typer mismatches.
5388
+ new_length = efalse = graph ()->NewNode (
5389
+ simplified ()->CheckBounds (p.feedback (),
5390
+ CheckBoundsFlag::kAbortOnOutOfBounds ),
5391
+ new_length, length, efalse, if_false);
5385
5392
5386
5393
// Store the new {length} to the {receiver}.
5387
5394
efalse = graph ()->NewNode (
5388
5395
simplified ()->StoreField (AccessBuilder::ForJSArrayLength (kind)),
5389
- receiver, length , efalse, if_false);
5396
+ receiver, new_length , efalse, if_false);
5390
5397
5391
5398
// Load the last entry from the {elements}.
5392
5399
vfalse = efalse = graph ()->NewNode (
5393
5400
simplified ()->LoadElement (AccessBuilder::ForFixedArrayElement (kind)),
5394
- elements, length , efalse, if_false);
5401
+ elements, new_length , efalse, if_false);
5395
5402
5396
5403
// Store a hole to the element we just removed from the {receiver}.
5397
5404
efalse = graph ()->NewNode (
5398
5405
simplified ()->StoreElement (
5399
5406
AccessBuilder::ForFixedArrayElement (GetHoleyElementsKind (kind))),
5400
- elements, length , jsgraph ()->TheHoleConstant (), efalse, if_false);
5407
+ elements, new_length , jsgraph ()->TheHoleConstant (), efalse, if_false);
5401
5408
}
5402
5409
5403
5410
control = graph ()->NewNode (common ()->Merge (2 ), if_true, if_false);
@@ -5573,19 +5580,27 @@ Reduction JSCallReducer::ReduceArrayPrototypeShift(Node* node) {
5573
5580
}
5574
5581
5575
5582
// Compute the new {length}.
5576
- length = graph ()->NewNode (simplified ()->NumberSubtract (), length,
5577
- jsgraph ()->OneConstant ());
5583
+ Node* new_length = graph ()->NewNode (simplified ()->NumberSubtract (),
5584
+ length, jsgraph ()->OneConstant ());
5585
+
5586
+ // This extra check exists solely to break an exploitation technique
5587
+ // that abuses typer mismatches.
5588
+ new_length = etrue1 = graph ()->NewNode (
5589
+ simplified ()->CheckBounds (p.feedback (),
5590
+ CheckBoundsFlag::kAbortOnOutOfBounds ),
5591
+ new_length, length, etrue1, if_true1);
5578
5592
5579
5593
// Store the new {length} to the {receiver}.
5580
5594
etrue1 = graph ()->NewNode (
5581
5595
simplified ()->StoreField (AccessBuilder::ForJSArrayLength (kind)),
5582
- receiver, length , etrue1, if_true1);
5596
+ receiver, new_length , etrue1, if_true1);
5583
5597
5584
5598
// Store a hole to the element we just removed from the {receiver}.
5585
5599
etrue1 = graph ()->NewNode (
5586
5600
simplified ()->StoreElement (AccessBuilder::ForFixedArrayElement (
5587
5601
GetHoleyElementsKind (kind))),
5588
- elements, length, jsgraph ()->TheHoleConstant (), etrue1, if_true1);
5602
+ elements, new_length, jsgraph ()->TheHoleConstant (), etrue1,
5603
+ if_true1);
5589
5604
}
5590
5605
5591
5606
Node* if_false1 = graph ()->NewNode (common ()->IfFalse (), branch1);
0 commit comments