Permalink
Browse files

CLJS-426 Fix on subvec inconsitent behavior when using invalid ranges

  • Loading branch information...
roman authored and David Nolen committed Nov 22, 2012
1 parent 6cd177d commit ee25599abb214074cbeefe37b399038d70c6ab89
Showing with 26 additions and 10 deletions.
  1. +14 −5 src/cljs/cljs/core.cljs
  2. +12 −5 test/cljs/cljs/core_test.cljs
View
@@ -3184,7 +3184,7 @@ reduces them without incurring seq initialization"
(pr-str this))
IWithMeta
- (-with-meta [coll meta] (Subvec. meta v start end __hash))
+ (-with-meta [coll meta] (build-subvec meta v start end __hash))
IMeta
(-meta [coll] meta)
@@ -3195,11 +3195,11 @@ reduces them without incurring seq initialization"
(-pop [coll]
(if (== start end)
(throw (js/Error. "Can't pop empty vector"))
- (Subvec. meta v start (dec end) nil)))
+ (build-subvec meta v start (dec end) nil)))
ICollection
(-conj [coll o]
- (Subvec. meta (-assoc-n v end o) start (inc end) nil))
+ (build-subvec meta (-assoc-n v end o) start (inc end) nil))
IEmptyableCollection
(-empty [coll] (with-meta cljs.core.Vector/EMPTY meta))
@@ -3236,7 +3236,7 @@ reduces them without incurring seq initialization"
IAssociative
(-assoc [coll key val]
(let [v-pos (+ start key)]
- (Subvec. meta (-assoc v v-pos val)
+ (build-subvec meta (-assoc v v-pos val)
start (max end (inc v-pos))
nil)))
@@ -3255,6 +3255,15 @@ reduces them without incurring seq initialization"
(-invoke [coll k not-found]
(-lookup coll k not-found)))
+(defn- build-subvec [meta v start end __hash]
+ (let [c (count v)]
+ (when (or (neg? start)
+ (neg? end)
+ (> start c)
+ (> end c))
+ (throw (js/Error. "Index out of bounds")))
+ (Subvec. meta v start end __hash)))
+
(defn subvec
"Returns a persistent vector of the items in vector from
start (inclusive) to end (exclusive). If end is not supplied,
@@ -3264,7 +3273,7 @@ reduces them without incurring seq initialization"
([v start]
(subvec v start (count v)))
([v start end]
- (Subvec. nil v start end nil)))
+ (build-subvec nil v start end nil)))
(defn- tv-ensure-editable [edit node]
(if (identical? edit (.-edit node))
@@ -1007,13 +1007,14 @@
(assert (= 94 (peek stack2))))
;; subvec
- (let [v (vec (range 10))
- s (subvec v 2 8)]
+ (let [v1 (vec (range 10))
+ v2 (vec (range 5))
+ s (subvec v1 2 8)]
(assert (= s
- (-> v
+ (-> v1
(subvec 2)
(subvec 0 6))
- (->> v
+ (->> v1
(drop 2)
(take 6))))
(assert (= 6 (count s)))
@@ -1024,7 +1025,13 @@
(conj s 1)))
(assert (= 27 (reduce + s)))
(assert (= s (vec s))) ; pour into plain vector
- (let [m {:x 1}] (assert (= m (meta (with-meta s m))))))
+ (let [m {:x 1}] (assert (= m (meta (with-meta s m)))))
+ ;; go outside ranges
+ (assert (= :fail (try (subvec v2 0 6) (catch js/Error e :fail))))
+ (assert (= :fail (try (subvec v2 6 10) (catch js/Error e :fail))))
+ (assert (= :fail (try (subvec v2 6 10) (catch js/Error e :fail))))
+ (assert (= :fail (try (subvec v2 3 6) (catch js/Error e :fail))))
+ )
;; TransientVector
(let [v1 (vec (range 15 48))

0 comments on commit ee25599

Please sign in to comment.