[Ecls-list] ECL 10.3.1 bug in reading and writing unsigned-byte sequences on io-streams

Ram Krishnan kriyative at gmail.com
Wed Mar 10 17:01:01 UTC 2010


Two separate bugs in ECL 10.3.1 (and 9.12.3 also), in reading and
writing sequences of element-type '(unsigned-byte 8) from a non-zero
offset.

1. READ-SEQUENCE

When calling READ-SEQUENCE on a file stream, with a START offset the
value returned is not the "the index of the first element of sequence
that was not updated, which might be less than end because the end of
file was reached." per the ANSI spec.

Here's how to reproduce (Note, this destructively writes a file called
"/tmp/eclb8test.bin"):

;; setup
(with-open-file (out "/tmp/eclb8test.bin"
                     :direction :output
                     :element-type '(unsigned-byte 8)
                     :if-exists :supersede)
  (dotimes (i 128)
    (write-byte i out)))

(with-open-file (in "/tmp/eclb8test.bin"
                    :direction :input
                    :element-type '(unsigned-byte 8))
  (let ((buf (make-array 256 :element-type '(unsigned-byte 8))))
    (format t "~&;; last read position is: ~d, should be: ~d"
            (read-sequence buf in :start 8)
            (+ 8 128))))

which should generate:

;; last read position is: 128, should be: 136


2. WRITE-SEQUENCE

When calling WRITE-SEQUENCE on a file stream with a START offset, the
function writes values from a far greater offset than specified.

To reproduce:

;; setup
(with-open-file (out "/tmp/eclb8test.bin"
                    :direction :output
                    :element-type '(unsigned-byte 8)
                    :if-exists :supersede)
  (let ((buf (make-array 128 :element-type '(unsigned-byte 8))))
    (dotimes (i 128) (setf (aref buf i) i))
    (write-sequence buf out :start 8)))

(with-open-file (in "/tmp/eclb8test.bin"
                    :direction :input
                    :element-type '(unsigned-byte 8))
  (let ((buf (make-array 128 :element-type '(unsigned-byte 8))))
    (read-sequence buf in)
    (format t "~&;; vector is: ~s, should be: ~s"
            (subseq buf 0 10)
            #(8 9 10 11 12 13 14 15 16 17))))

which should generate:

;; vector is: #(64 65 66 67 68 69 70 71 72 73), should be: #(8 9 10 11
;; 12 13 14 15 16 17)

The fix is in the functions io_file_read_vector() and
io_file_write_vector() in src/c/file.d, as attached herewith.

Cheers,

-ram
-------------- next part --------------
Index: src/c/file.d
===================================================================
RCS file: /cvsroot/ecls/ecl/src/c/file.d,v
retrieving revision 1.194
diff -u -r1.194 file.d
--- src/c/file.d	1 Mar 2010 17:48:32 -0000	1.194
+++ src/c/file.d	10 Mar 2010 16:27:58 -0000
@@ -2782,7 +2782,7 @@
 	if (t == aet_b8 || t == aet_i8) {
 		if (strm->stream.byte_size == 8) {
 			void *aux = data->vector.self.bc + start;
-			return strm->stream.ops->read_byte8(strm, aux, end-start);
+			return start + strm->stream.ops->read_byte8(strm, aux, end-start);
 		}
 	} else if (t == aet_fix || t == aet_index) {
 		if (strm->stream.byte_size == sizeof(cl_fixnum)*8) {
@@ -2803,7 +2803,7 @@
 		return start;
 	if (t == aet_b8 || t == aet_i8) {
 		if (strm->stream.byte_size == 8) {
-			void *aux = data->vector.self.fix + start;
+			void *aux = data->vector.self.bc + start;
 			return strm->stream.ops->write_byte8(strm, aux, end-start);
 		}
 	} else if (t == aet_fix || t == aet_index) {


More information about the ecl-devel mailing list