Skip to content

regex: model Pattern/Matcher for JBMC's intercepted regex machinery - #40

Open
tautschnig wants to merge 1 commit into
masterfrom
regex-matcher-model
Open

regex: model Pattern/Matcher for JBMC's intercepted regex machinery#40
tautschnig wants to merge 1 commit into
masterfrom
regex-matcher-model

Conversation

@tautschnig

Copy link
Copy Markdown
Collaborator

Pattern now stores its flags and constructs a real Matcher (previously matcher() returned a field-less nondet object, and the constructor ASSUMED the pattern contained no regex metacharacters -- making downstream paths vacuous for any real regex). Pattern.matches delegates to compile(regex).matcher(input).matches().

Matcher carries (pattern, text-as-String) plus two staleness flags with JLS state semantics: cproverImprecise (the region no longer covers the whole input -> every query degrades to a sound nondet) and cproverFindConsumed (a find() advanced the unmodelled match position -> only find() degrades; matches()/lookingAt() are position-independent per the JLS). reset()/ reset(CharSequence) restore precision; usePattern retains the position (find degrades) but keeps the region; region()/find(int) poison their respective flags. matches() delegates to the intercepted String.matches; lookingAt()/find() delegate to the static cproverLookingAt/cproverFind hooks JBMC lowers to its Java-dialect regex solver functions. Non-zero compile flags fall back to nondet (flags change match semantics).

Copilot AI review requested due to automatic review settings July 28, 2026 20:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the java.util.regex model to better align with JBMC’s intercepted regex machinery by making Pattern retain compile flags and by returning a stateful Matcher that can delegate matching operations to JBMC hooks/intercepts.

Changes:

  • Store compile flags in Pattern and return a real Matcher from Pattern.matcher(...).
  • Rework Pattern.matches(...) to delegate through compile(regex).matcher(input).matches().
  • Model Matcher state (pattern, input text, and staleness flags) and implement matches(), lookingAt(), and find() with precision-degrading semantics.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/main/java/java/util/regex/Pattern.java Stores compile flags, returns real Matcher, and rewires Pattern.matches to delegate through the matcher.
src/main/java/java/util/regex/Matcher.java Introduces modeled matcher state and implements core query methods (matches, find, lookingAt) with staleness tracking.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/java/util/regex/Pattern.java
Comment thread src/main/java/java/util/regex/Matcher.java Outdated
Pattern now stores its flags and constructs a real Matcher (previously
matcher() returned a field-less nondet object, and the constructor ASSUMED
the pattern contained no regex metacharacters -- making downstream paths
vacuous for any real regex). Pattern.matches delegates to
compile(regex).matcher(input).matches().

Matcher carries (pattern, text-as-String) plus two staleness flags with JDK
state semantics: cproverImprecise (the region no longer covers the whole
input -> every query degrades to a sound nondet) and cproverFindConsumed
(a find() advanced the unmodelled match position -> only find() degrades;
matches()/lookingAt() are position-independent per the JDK). reset()/
reset(CharSequence) restore precision; usePattern retains the position
(find degrades) but keeps the region; region()/find(int) poison their
respective flags. matches() delegates to the intercepted String.matches;
lookingAt()/find() delegate to the static cproverLookingAt/cproverFind
hooks JBMC lowers to its Java-dialect regex solver functions. Non-zero
compile flags fall back to nondet (flags change match semantics).

Argument-validation exceptions are modelled fail-fast per the real JDK
(all five verified against a real JVM): Pattern.compile(null) and hence
Pattern.matches(null, ...) throw NullPointerException (the real
constructor dereferences the pattern); Pattern.matcher(null) throws
NullPointerException; Matcher.usePattern(null) throws
IllegalArgumentException per its contract; Matcher.reset((CharSequence)
null) throws NullPointerException. The null-FIELD guards inside the query
methods are a separate regime and remain: they cover nondet-generated
Matcher objects from the object factory, whose null fields are legitimate
states (degraded to a sound nondet), not caller errors.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig
tautschnig force-pushed the regex-matcher-model branch from deabf32 to 373e8ac Compare July 28, 2026 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants