Skip to content
Browse files

Properly handle overly long output buffer. Add tests.

  • Loading branch information...
1 parent ca7ea5c commit a8ce9f7477357d076718228424108d8ad3881527 Alexander Taggart committed Oct 10, 2011
Showing with 28 additions and 15 deletions.
  1. +17 −15 src/main/clojure/clojure/data/codec/base64.clj
  2. +11 −0 src/test/clojure/clojure/data/codec/test_base64.clj
View
32 src/main/clojure/clojure/data/codec/base64.clj
@@ -1,6 +1,7 @@
(ns clojure.data.codec.base64)
(set! *unchecked-math* true)
+(set! *warn-on-reflection* true)
(def ^:private ^"[B" enc-bytes
(byte-array
@@ -21,7 +22,8 @@
[^bytes input ^long offset ^long length ^bytes output]
(let [tail-len (rem length 3)
loop-lim (- (+ offset length) tail-len)
- end (dec (+ offset length))]
+ in-end (dec (+ offset length))
+ out-end (dec (enc-length length))]
(loop [i offset j 0]
(when (< i loop-lim)
(let [x (long (aget input i)) ; can only bind long/double prims, and no widening conversion
@@ -55,49 +57,49 @@
0 output
1 (do
(aset output
- (- (alength output) 4)
+ (- out-end 3)
(aget enc-bytes
- (-> (aget input end)
+ (-> (aget input in-end)
int
(bit-shift-right 2)
(bit-and 0x3F))))
(aset output
- (- (alength output) 3)
+ (- out-end 2)
(aget enc-bytes
- (-> (aget input end)
+ (-> (aget input in-end)
int
(bit-and 0x3)
(bit-shift-left 4))))
- (aset output (- (alength output) 2) (byte 61))
- (aset output (dec (alength output)) (byte 61))
+ (aset output (dec out-end) (byte 61))
+ (aset output out-end (byte 61))
output)
2 (do
(aset output
- (- (alength output) 4)
+ (- out-end 3)
(aget enc-bytes
- (-> (aget input (dec end))
+ (-> (aget input (dec in-end))
int
(bit-shift-right 2)
(bit-and 0x3F))))
(aset output
- (- (alength output) 3)
+ (- out-end 2)
(aget enc-bytes
- (-> (aget input (dec end))
+ (-> (aget input (dec in-end))
int
(bit-and 0x3)
(bit-shift-left 4)
- (bit-or (-> (aget input end)
+ (bit-or (-> (aget input in-end)
int
(bit-shift-right 4)
(bit-and 0xF))))))
(aset output
- (- (alength output) 2)
+ (dec out-end)
(aget enc-bytes
- (-> (aget input end)
+ (-> (aget input in-end)
int
(bit-and 0xF)
(bit-shift-left 2))))
- (aset output (dec (alength output)) (byte 61))
+ (aset output out-end (byte 61))
nil))))
(defn encode
View
11 src/test/clojure/clojure/data/codec/test_base64.clj
@@ -3,6 +3,8 @@
(:use clojure.test
clojure.data.codec.base64))
+(set! *warn-on-reflection* true)
+
(defn rand-bytes [n]
(->> #(byte (- (rand-int 256) 128))
repeatedly
@@ -26,3 +28,12 @@
_ (System/arraycopy input off input2 0 len)
a2 (Base64/encodeBase64 input2)]
(= (into [] a1) (into [] a2)))))))
+
+(deftest buffer-correctness
+ (doseq [n (range 1 100)]
+ (doseq [excess-buf-len (range 1 10)]
+ (is (let [input (rand-bytes n)
+ output (byte-array (+ (enc-length n) excess-buf-len))
+ _ (encode! input 0 n output)
+ a2 (Base64/encodeBase64 input)]
+ (= (into [] (take (enc-length n) output)) (into [] a2)))))))

0 comments on commit a8ce9f7

Please sign in to comment.
Something went wrong with that request. Please try again.