Skip to content

Commit c0f665a

Browse files
borkdudemfikes
authored andcommitted
CLJS-2979: re-seq is relying on undefined behavior of subs
This commit makes re-seq only do a call to subs with defined values. It also optimizes the code. Tests for re-seq regarding CLJS-810 are provided as well.
1 parent 9250a57 commit c0f665a

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

src/main/cljs/cljs/core.cljs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9845,15 +9845,25 @@ reduces them without incurring seq initialization"
98459845
(vec matches))))
98469846
(throw (js/TypeError. "re-find must match against a string."))))
98479847

9848+
(defn- re-seq* [re s]
9849+
(when-some [matches (.exec re s)]
9850+
(let [match-str (aget matches 0)
9851+
match-vals (if (== (.-length matches) 1)
9852+
match-str
9853+
(vec matches))]
9854+
(cons match-vals
9855+
(lazy-seq
9856+
(let [post-idx (+ (.-index matches)
9857+
(max 1 (.-length match-str)))]
9858+
(when (<= post-idx (.-length s))
9859+
(re-seq* re (subs s post-idx)))))))))
9860+
98489861
(defn re-seq
98499862
"Returns a lazy sequence of successive matches of re in s."
98509863
[re s]
9851-
(let [match-data (re-find re s)
9852-
match-idx (.search s re)
9853-
match-str (if (coll? match-data) (first match-data) match-data)
9854-
post-idx (+ match-idx (max 1 (count match-str)))
9855-
post-match (subs s post-idx)]
9856-
(when match-data (lazy-seq (cons match-data (when (<= post-idx (count s)) (re-seq re post-match)))))))
9864+
(if (string? s)
9865+
(re-seq* re s)
9866+
(throw (js/TypeError. "re-seq must match against a string."))))
98579867

98589868
(defn re-pattern
98599869
"Returns an instance of RegExp which has compiled the provided string."

src/test/cljs/cljs/core_test.cljs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,10 @@
957957
(is (every? #(= :failed (try (re-find #"nomatch" %)
958958
(catch js/TypeError _ :failed))) not-strings))
959959
(is (every? #(= :failed (try (re-matches #"nomatch" %)
960+
(catch js/TypeError _ :failed))) not-strings))
961+
(is (every? #(= :failed (try (re-seq #"." %)
962+
(catch js/TypeError _ :failed))) not-strings))
963+
(is (every? #(= :failed (try (re-seq #"nomatch" %)
960964
(catch js/TypeError _ :failed))) not-strings)))))
961965

962966
(deftest test-853

0 commit comments

Comments
 (0)