Skip to content

Commit 9f87c8b

Browse files
authored
Merge pull request #4 from ajberkley/ajb/handle-bad-array-element-types
Handle bad array element-types
2 parents a6e18a3 + d6940e1 commit 9f87c8b

File tree

6 files changed

+25
-16
lines changed

6 files changed

+25
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,4 @@ See [benchmarking.md](benchmarking.md).
302302
- [ ] Speed up cl-binary-store on ABCL and ECL so it is less than 10x slower than on SBCL
303303
- [ ] Handle specialized multi-dimensional array data on non-SBCL faster. See babel for all the variants on with-array-data
304304
- [ ] Faster standard-object serialization / deserialization using direct slot location accessors
305-
- [ ] Handle ECL does not like array element type nil (like what happens when you have a zero size array) with invalid-data condition
305+

src/array.lisp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
(in-package :cl-binary-store)
22

3+
(defun is-type-specifier-p (type-specifier)
4+
"Returns true if TYPE-SPECIFIER is a valid type specifier."
5+
(or #+sbcl (sb-ext:valid-type-specifier-p type-specifier)
6+
#+ccl (ccl:type-specifier-p type-specifier)
7+
#+ecl (c::valid-type-specifier type-specifier)))
8+
39
(defun restore-array (storage restore-object)
410
(declare (type function restore-object) (optimize (speed 3) (safety 1)))
511
(let* ((has-fill-pointer (funcall restore-object))
@@ -9,9 +15,15 @@
915
(dimensions (loop repeat array-rank
1016
collect (restore-tagged-unsigned-fixnum storage)))
1117
(displaced (funcall restore-object))
12-
(array-total-size (if dimensions (reduce #'* dimensions) 0)))
18+
(array-total-size (if dimensions (reduce #'* dimensions) 0))
19+
(element-type (funcall restore-object)))
1320
(unless (and (typep array-total-size 'fixnum) (>= array-total-size 0))
1421
(unexpected-data "Array total size is too large"))
22+
#+ecl
23+
(unless element-type
24+
(unexpected-data "ECL does not support empty arrays with nil element type"))
25+
(unless (is-type-specifier-p element-type)
26+
(unexpected-data "Invalid array element-type"))
1527
(check-if-too-much-data (read-storage-max-to-read storage) array-total-size)
1628
(labels ((check-fill-pointer (dimensions)
1729
(when has-fill-pointer
@@ -21,8 +33,7 @@
2133
(unexpected-data "fill-pointer > vector length")))
2234
(values)))
2335
(if displaced
24-
(let ((element-type (funcall restore-object))
25-
(offset (restore-tagged-unsigned-fixnum storage))
36+
(let ((offset (restore-tagged-unsigned-fixnum storage))
2637
(displaced-to (funcall restore-object)))
2738
(unless (typep displaced-to 'array)
2839
(unexpected-data "displaced to a non array?!"))
@@ -37,9 +48,8 @@
3748
(progn
3849
(when has-fill-pointer (check-fill-pointer dimensions))
3950
(let ((array
40-
(let* ((element-type (funcall restore-object)))
41-
(make-array dimensions :element-type element-type :adjustable adjustable
42-
:fill-pointer fill-pointer))))
51+
(make-array dimensions :element-type element-type :adjustable adjustable
52+
:fill-pointer fill-pointer)))
4353
;; We need to make our array first in case any of the array elements refer to it!
4454
;; If we are ever referred to, then there will already be a fixup in place for
4555
;; our array handled by `restore-new-reference-indicator'.

src/cl-binary-store.lisp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,10 @@
213213
(define-condition invalid-input-data (simple-error)
214214
())
215215

216-
(defun unexpected-data (expected &optional (data nil data-provided-p))
216+
(defun unexpected-data (message &optional (data nil data-provided-p))
217217
(error 'invalid-input-data
218-
:format-control "Expected ~A~A"
219-
:format-arguments (list expected
218+
:format-control "~A~A"
219+
:format-arguments (list message
220220
(if data-provided-p
221221
;; be careful not to provide anything
222222
;; that cannot be printed trivially here!

src/numbers.lisp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,9 @@
329329
(#.+fixnum-code+
330330
(let ((fixnum (restore-fixnum storage)))
331331
(unless (<= 0 fixnum (- most-positive-fixnum +interior-coded-max-integer+ 1))
332-
(unexpected-data "unsigned fixnum/interior" fixnum))
332+
(unexpected-data "expected unsigned fixnum/interior" fixnum))
333333
(truly-the fixnum fixnum)))
334-
(otherwise (unexpected-data "tag for unsigned fixnum" tag)))
334+
(otherwise (unexpected-data "expected tag for unsigned fixnum" tag)))
335335
+interior-coded-max-integer+ 1)))))
336336

337337
(declaim (ftype (function (read-storage)
@@ -349,7 +349,7 @@
349349
(#.+ub16-code+ (restore-ub16 storage))
350350
(#.+ub32-code+ (restore-ub32 storage))
351351
(#.+fixnum-code+ (restore-fixnum storage))
352-
(otherwise (unexpected-data "tag for unsigned fixnum" tag))))))
352+
(otherwise (unexpected-data "expected tag for unsigned fixnum" tag))))))
353353

354354
(declaim (ftype (function (read-storage)
355355
#+sbcl (values fixnum &optional)
@@ -367,7 +367,7 @@
367367
(#.+sb8-code+ (restore-sb8 storage))
368368
(#.+sb16-code+ (restore-sb16 storage))
369369
(#.+sb32-code+ (restore-sb32 storage))
370-
(otherwise (unexpected-data "tag for fixnum" tag))))))
370+
(otherwise (unexpected-data "expected tag for fixnum" tag))))))
371371

372372
(declaim (inline store-tagged-unsigned-integer))
373373

src/user.lisp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
(vector
192192
(restore-from-vector place)))
193193
(babel:character-decoding-error (e)
194-
(unexpected-data "UTF-8 data" e)))))
194+
(unexpected-data "Expected UTF-8 data" e)))))
195195

196196
(defun store (place data &key (track-references *track-references*)
197197
(support-shared-list-structures *support-shared-list-structures*)

test/cl-binary-store-tests.lisp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,6 @@
721721
(invalid-input-data ()))))
722722

723723
(define-test other-fuzzing-tests
724-
#-ecl
725724
(finish
726725
(handler-case
727726
(restore #(24 53 197 0 44 60 123 20))

0 commit comments

Comments
 (0)