Commit a8aa4b4e authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan] Fix Clusterfuzz-found bugs

Smi::LexicographicCompare: signed integer overflow on negation.
Drive-by improvement: reduce number of branches.

RegExpQuantifier: signed integer overflow on multiplication.

DateCache::DaylightSavingsOffsetInMs: signed integer overflow
on addition.

Bug: v8:3770,chromium:923466,chromium:923642,chromium:923626
Change-Id: If7d995a13893d1315449ee0bab8b5f2553e170f5
Reviewed-on: https://chromium-review.googlesource.com/c/1436229Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59143}
parent cf330da4
...@@ -284,14 +284,13 @@ int DateCache::GetLocalOffsetFromOS(int64_t time_ms, bool is_utc) { ...@@ -284,14 +284,13 @@ int DateCache::GetLocalOffsetFromOS(int64_t time_ms, bool is_utc) {
void DateCache::ExtendTheAfterSegment(int time_sec, int offset_ms) { void DateCache::ExtendTheAfterSegment(int time_sec, int offset_ms) {
if (after_->offset_ms == offset_ms && if (after_->offset_ms == offset_ms &&
after_->start_sec <= after_->start_sec - kDefaultDSTDeltaInSec <= time_sec &&
base::AddWithWraparound(time_sec, kDefaultDSTDeltaInSec) &&
time_sec <= after_->end_sec) { time_sec <= after_->end_sec) {
// Extend the after_ segment. // Extend the after_ segment.
after_->start_sec = time_sec; after_->start_sec = time_sec;
} else { } else {
// The after_ segment is either invalid or starts too late. // The after_ segment is either invalid or starts too late.
if (after_->start_sec <= after_->end_sec) { if (!InvalidSegment(after_)) {
// If the after_ segment is valid, replace it with a new segment. // If the after_ segment is valid, replace it with a new segment.
after_ = LeastRecentlyUsedDST(before_); after_ = LeastRecentlyUsedDST(before_);
} }
...@@ -346,7 +345,7 @@ int DateCache::DaylightSavingsOffsetInMs(int64_t time_ms) { ...@@ -346,7 +345,7 @@ int DateCache::DaylightSavingsOffsetInMs(int64_t time_ms) {
return before_->offset_ms; return before_->offset_ms;
} }
if (time_sec > before_->end_sec + kDefaultDSTDeltaInSec) { if (time_sec - kDefaultDSTDeltaInSec > before_->end_sec) {
// If the before_ segment ends too early, then just // If the before_ segment ends too early, then just
// query for the offset of the time_sec // query for the offset of the time_sec
int offset_ms = GetDaylightSavingsOffsetFromOS(time_sec); int offset_ms = GetDaylightSavingsOffsetFromOS(time_sec);
...@@ -365,8 +364,11 @@ int DateCache::DaylightSavingsOffsetInMs(int64_t time_ms) { ...@@ -365,8 +364,11 @@ int DateCache::DaylightSavingsOffsetInMs(int64_t time_ms) {
// Check if after_ segment is invalid or starts too late. // Check if after_ segment is invalid or starts too late.
// Note that start_sec of invalid segments is kMaxEpochTimeInSec. // Note that start_sec of invalid segments is kMaxEpochTimeInSec.
if (before_->end_sec + kDefaultDSTDeltaInSec <= after_->start_sec) { int new_after_start_sec =
int new_after_start_sec = before_->end_sec + kDefaultDSTDeltaInSec; before_->end_sec < kMaxEpochTimeInSec - kDefaultDSTDeltaInSec
? before_->end_sec + kDefaultDSTDeltaInSec
: kMaxEpochTimeInSec;
if (new_after_start_sec <= after_->start_sec) {
int new_offset_ms = GetDaylightSavingsOffsetFromOS(new_after_start_sec); int new_offset_ms = GetDaylightSavingsOffsetFromOS(new_after_start_sec);
ExtendTheAfterSegment(new_after_start_sec, new_offset_ms); ExtendTheAfterSegment(new_after_start_sec, new_offset_ms);
} else { } else {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "src/ast/ast.h" #include "src/ast/ast.h"
#include "src/ast/scopes.h" #include "src/ast/scopes.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/base/overflowing-math.h"
#include "src/base/utils/random-number-generator.h" #include "src/base/utils/random-number-generator.h"
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
#include "src/builtins/builtins.h" #include "src/builtins/builtins.h"
...@@ -19144,11 +19145,15 @@ Address Smi::LexicographicCompare(Isolate* isolate, Smi x, Smi y) { ...@@ -19144,11 +19145,15 @@ Address Smi::LexicographicCompare(Isolate* isolate, Smi x, Smi y) {
// architectures using 32-bit Smis. // architectures using 32-bit Smis.
uint32_t x_scaled = x_value; uint32_t x_scaled = x_value;
uint32_t y_scaled = y_value; uint32_t y_scaled = y_value;
if (x_value < 0 || y_value < 0) { if (x_value < 0) {
if (y_value >= 0) return Smi::FromInt(-1).ptr(); if (y_value >= 0) {
if (x_value >= 0) return Smi::FromInt(1).ptr(); return Smi::FromInt(-1).ptr();
x_scaled = -x_value; } else {
y_scaled = -y_value; y_scaled = base::NegateWithWraparound(y_value);
}
x_scaled = base::NegateWithWraparound(x_value);
} else if (y_value < 0) {
return Smi::FromInt(1).ptr();
} }
// clang-format off // clang-format off
......
...@@ -412,8 +412,12 @@ class RegExpQuantifier final : public RegExpTree { ...@@ -412,8 +412,12 @@ class RegExpQuantifier final : public RegExpTree {
: body_(body), : body_(body),
min_(min), min_(min),
max_(max), max_(max),
min_match_(min * body->min_match()),
quantifier_type_(type) { quantifier_type_(type) {
if (min > 0 && body->min_match() > kInfinity / min) {
min_match_ = kInfinity;
} else {
min_match_ = min * body->min_match();
}
if (max > 0 && body->max_match() > kInfinity / max) { if (max > 0 && body->max_match() > kInfinity / max) {
max_match_ = kInfinity; max_match_ = kInfinity;
} else { } else {
......
// Copyright 2019 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.
// crbug.com/923466
__v_5 = [ -1073741825, -2147483648];
__v_5.sort();
// crbug.com/923642
new RegExp("(abcd){2148473648,}", "");
// crbug.com/923626
new Date(2146399200000).toString();
new Date(2146940400000).toString();
new Date(2147481600000).toString();
new Date(2148022800000).toString();
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