|
85 | 85 | (18 (values '(unsigned-byte 62) 64))
|
86 | 86 | (19 (values '(unsigned-byte 64) 64))
|
87 | 87 | (otherwise
|
88 |
| - (unexpected-data "encoded element type" encoded-element-type)))) |
| 88 | + (unexpected-data "encoded element type")))) |
89 | 89 |
|
90 | 90 | (defconstant +first-direct-unsigned-integer+ 20)
|
91 | 91 | (defconstant +max-direct-encoded-unsigned-integer+ (- 255 +first-direct-unsigned-integer+))
|
|
95 | 95 | "Returns (values new-array array-bytes)"
|
96 | 96 | (declare (optimize (speed 3) (safety 1)) (type (unsigned-byte 8) encoded-element-type)
|
97 | 97 | (type fixnum num-elts))
|
98 |
| - (unless (<= num-elts (ash most-positive-fixnum -3)) |
99 |
| - (unexpected-data (format nil "num-elts smaller than ~A" (ash most-positive-fixnum -3)) num-elts)) |
| 98 | + (unless (<= num-elts (ash most-positive-fixnum -7)) |
| 99 | + (unexpected-data "num-elts too big")) |
100 | 100 | (let ((num-elts num-elts))
|
101 |
| - (declare (type (unsigned-byte 59) num-elts)) |
102 | 101 | (multiple-value-bind (type actual-bits)
|
103 | 102 | (encoded-element-type-to-type/packing encoded-element-type)
|
104 | 103 | (let ((total-bytes (ceiling (the fixnum
|
|
199 | 198 | (defun restore-simple-base-string (storage)
|
200 | 199 | (declare (optimize (speed 3) (safety 1)))
|
201 | 200 | (let ((num-bytes (restore-tagged-unsigned-fixnum/interior storage)))
|
202 |
| - (unless (and (typep num-bytes 'fixnum) (>= num-bytes 0)) |
203 |
| - (unexpected-data "unsigned fixnum" num-bytes)) |
| 201 | + (unless (>= num-bytes 0) |
| 202 | + (unexpected-data "unexpected negative length for simple-base-string")) |
204 | 203 | (check-if-too-much-data (read-storage-max-to-read storage) num-bytes)
|
205 | 204 | (let ((string (make-string num-bytes :element-type 'base-char)))
|
206 | 205 | (chunked/read storage num-bytes
|
|
417 | 416 | ,@body
|
418 | 417 | (setf (read-storage-offset ,storage) (+ ,original-offset ,reserve-bytes)))))))
|
419 | 418 |
|
| 419 | +(defmacro sap-ref-fixnum (sap offset) |
| 420 | + "This is hideous. On SBCL we have stored the data fixnum encoded, which means shifted up |
| 421 | + by one so we shift it back to generate an 'unencoded' fixnum. We would normally just have |
| 422 | + blitted things back into the array without telling sbcl what we are doing, but in the |
| 423 | + presence of potentially malicious data, we have to make sure that our numbers are fixnums, |
| 424 | + so we shift them back down which makes it impossible for malicious actor to put bogus dat |
| 425 | + in the array sap. On non sbcl we just check to make sure things are fixnums because we |
| 426 | + did not blit the data out" |
| 427 | + #+sbcl |
| 428 | + `(ash (signed-sap-ref-64 ,sap ,offset) -1) |
| 429 | + #-sbcl |
| 430 | + (let ((a (gensym))) |
| 431 | + `(let ((,a (signed-sap-ref-64 ,sap ,offset))) |
| 432 | + (if (typep ,a 'fixnum) |
| 433 | + ,a |
| 434 | + (unexpected-data "non fixnum in fixnum array"))))) |
| 435 | + |
420 | 436 | (defun restore-simple-specialized-vector (storage)
|
421 | 437 | (declare (optimize (speed 3) (safety 1)))
|
422 | 438 | (let ((num-elts (restore-tagged-unsigned-fixnum/interior storage)))
|
|
449 | 465 | (32 (reader 32 t))
|
450 | 466 | (64 (reader 64 t))))))
|
451 | 467 | (t
|
452 |
| - (ecase type |
| 468 | + (case type |
453 | 469 | (bit (reader 1 nil))
|
454 | 470 | (single-float (reader 32 nil sap-ref-single (simple-array single-float (*))))
|
455 | 471 | (double-float (reader 64 nil sap-ref-double (simple-array double-float (*))))
|
456 |
| - (fixnum (reader 64 t signed-sap-ref-64 (simple-array fixnum (*)))))))) |
| 472 | + (fixnum (reader 64 t sap-ref-fixnum (simple-array fixnum (*)))) |
| 473 | + (otherwise (unexpected-data "array of unexpected type")))))) |
457 | 474 | #+sbcl
|
458 | 475 | (with-pinned-objects (sv)
|
459 |
| - (let ((target-sap (vector-sap sv))) |
460 |
| - (chunked/read |
461 |
| - storage num-bytes |
462 |
| - (lambda (source-sap source-sap-offset data-start/bytes data-end-bytes) |
463 |
| - (copy-sap target-sap data-start/bytes source-sap source-sap-offset (the fixnum (- data-end-bytes data-start/bytes))))))) |
| 476 | + (multiple-value-bind (type bits-per-elt) |
| 477 | + (encoded-element-type-to-type/packing encoded-element-info) |
| 478 | + (declare (ignorable bits-per-elt)) |
| 479 | + (cond |
| 480 | + ((eq type 'fixnum) |
| 481 | + ;; We have to be careful here, as just blitting potentially malicious 64 |
| 482 | + ;; bit data into a simple-array fixnum (*) can cause issues. |
| 483 | + ;; Now the problem is that we already "fixnum encoded" the data if it is |
| 484 | + ;; correct, which means that it needs to be un-fixnum-ized |
| 485 | + (reader 64 t sap-ref-fixnum (simple-array fixnum (*)))) |
| 486 | + (t |
| 487 | + (let ((target-sap (vector-sap sv))) |
| 488 | + ;; OK, so we have a problem here --- if the fixnums aren't actually fixnums |
| 489 | + ;; then we end up screwing things up. |
| 490 | + (chunked/read |
| 491 | + storage num-bytes |
| 492 | + (lambda (source-sap source-sap-offset data-start/bytes data-end-bytes) |
| 493 | + (copy-sap target-sap data-start/bytes source-sap source-sap-offset (the fixnum (- data-end-bytes data-start/bytes)))))))))) |
464 | 494 | sv))))
|
465 | 495 |
|
466 | 496 | ;; for ccl ccl::array-data-and-offset would be fine... it's been a stable interface
|
|
511 | 541 | (type-of sa) num-bytes array-dimensions encoded-element-info)
|
512 | 542 | (with-pinned-objects (sa)
|
513 | 543 | (let ((target-sap (array-sap sa)))
|
514 |
| - (chunked/read |
515 |
| - storage num-bytes |
516 |
| - (lambda (source-sap source-sap-offset data-start/bytes data-end-bytes) |
517 |
| - (copy-sap target-sap data-start/bytes source-sap source-sap-offset (- data-end-bytes data-start/bytes)))))) |
| 544 | + (multiple-value-bind (type bits-per-elt) |
| 545 | + (encoded-element-type-to-type/packing encoded-element-info) |
| 546 | + (declare (ignorable bits-per-elt)) |
| 547 | + (cond |
| 548 | + ((eq type 'fixnum) |
| 549 | + ;; We have to be careful here, as just blitting potentially malicious 64 |
| 550 | + ;; bit data into a simple-array fixnum (*) can cause issues. |
| 551 | + (sb-kernel:with-array-data ((sv sa) (start) (end)) |
| 552 | + (declare (ignore start end)) |
| 553 | + (reader 64 t sap-ref-fixnum (simple-array fixnum (*))))) |
| 554 | + (t |
| 555 | + (chunked/read |
| 556 | + storage num-bytes |
| 557 | + (lambda (source-sap source-sap-offset data-start/bytes data-end-bytes) |
| 558 | + (copy-sap target-sap data-start/bytes source-sap source-sap-offset (- data-end-bytes data-start/bytes))))))))) |
518 | 559 | sa)))
|
0 commit comments