Fix nullptr-with-nonzero-offset bugs found by UBSan.
Change-Id: Ic94c887b3ba4211bec5f7eb096f06fe5bca53b70
Reviewed-on: https://code-review.googlesource.com/c/re2/+/48852
Reviewed-by: Paul Wankadia <junyer@google.com>
diff --git a/re2/bitstate.cc b/re2/bitstate.cc
index 5cbc070..f15c1e4 100644
--- a/re2/bitstate.cc
+++ b/re2/bitstate.cc
@@ -342,6 +342,10 @@
cap_[0] = p;
if (TrySearch(prog_->start(), p)) // Match must be leftmost; done.
return true;
+ // Avoid invoking undefined behavior (arithmetic on a null pointer)
+ // by simply not continuing the loop.
+ if (p == NULL)
+ break;
}
return false;
}
diff --git a/re2/nfa.cc b/re2/nfa.cc
index 3889f11..77fb5fb 100644
--- a/re2/nfa.cc
+++ b/re2/nfa.cc
@@ -382,10 +382,15 @@
break;
case kInstMatch: {
- // Avoid invoking undefined behavior when p happens
- // to be null - and p-1 would be meaningless anyway.
- if (p == NULL)
+ // Avoid invoking undefined behavior (arithmetic on a null pointer)
+ // by storing p instead of p-1. (What would the latter even mean?!)
+ // This complements the special case in NFA::Search().
+ if (p == NULL) {
+ CopyCapture(match_, t->capture);
+ match_[1] = p;
+ matched_ = true;
break;
+ }
if (endmatch_ && p-1 != etext_)
break;
@@ -593,6 +598,18 @@
fprintf(stderr, "dead\n");
break;
}
+
+ // Avoid invoking undefined behavior (arithmetic on a null pointer)
+ // by simply not continuing the loop.
+ // This complements the special case in NFA::Step().
+ if (p == NULL) {
+ (void)Step(runq, nextq, p < etext_ ? p[0] & 0xFF : -1, context, p);
+ DCHECK_EQ(runq->size(), 0);
+ using std::swap;
+ swap(nextq, runq);
+ nextq->clear();
+ break;
+ }
}
for (Threadq::iterator i = runq->begin(); i != runq->end(); ++i)
diff --git a/re2/testing/backtrack.cc b/re2/testing/backtrack.cc
index 6cde42d..1e888da 100644
--- a/re2/testing/backtrack.cc
+++ b/re2/testing/backtrack.cc
@@ -148,6 +148,10 @@
cap_[0] = p;
if (Visit(prog_->start(), p)) // Match must be leftmost; done.
return true;
+ // Avoid invoking undefined behavior (arithmetic on a null pointer)
+ // by simply not continuing the loop.
+ if (p == NULL)
+ break;
}
return false;
}