pf@csc.ti.com (Paul Fuqua) (06/16/88)
I recently translated compress to Common Lisp to run it on my Lisp
machine (I don't deal with versionless filesystems any more than I have
to). Along the way I discovered a bit of code that is, strictly
speaking, a bug, but which C doesn't catch or seem to care about.
In the function getcode, there is a local variable bp that is a
pointer into the array buf, which is 16 8-bit-bytes long (for 16-bit
compress). There is some hairy code that is used when not on a Vax
(which does most of the work in one instruction). When decompressing,
and the codes are 16 bits, and getcode is grabbing the last code in buf,
*bp starts off pointing at buf[14], is bumped to buf[15] by a *bp++,
then is bumped to buf[16] by another *bp++.
At this point is the following fragment:
/* high order bits. */
code |= (*bp & rmask[bits]) << r_off;
*bp reads the word just off the end of buf, but rmask[bits] is always 0
in this case, so the word is unimportant and everything works.
This bit caused me trouble because Common Lisp bounds-checks array
references (and lispms tend to crash when referencing unallocated
memory). My correction was to check for rmask[bits] == 0 before doing
the above, so bp wouldn't reference off the end. C, of course, doesn't
bounds-check, especially not when using pointers, and this bit of code
has been happily running on countless machines.
Is this a bug or a feature? I have my own opinion.
pf
Paul Fuqua
Texas Instruments Computer Science Center, Dallas, Texas
CSNet: pf@csc.ti.com (ARPA too, sometimes)
UUCP: {smu, texsun, im4u, rice}!ti-csl!pfchris@mimsy.UUCP (Chris Torek) (06/16/88)
In article <51610@ti-csl.CSNET> pf@csc.ti.com (Paul Fuqua) writes: > /* high order bits. */ > code |= (*bp & rmask[bits]) << r_off; > >*bp reads the word just off the end of buf, but rmask[bits] is always 0 >in this case, so the word is unimportant and everything works. > This bit caused me trouble because Common Lisp bounds-checks array >references .... My correction was to check for rmask[bits] == 0 before doing >the above, so bp wouldn't reference off the end. C, of course, doesn't >bounds-check, especially not when using pointers, and this bit of code >has been happily running on countless machines. > Is this a bug or a feature? I have my own opinion. It is a bug, and it is not a `feature of C'; any legal C compiler could produce a runtime error message to the effect of `reference outside of address space'. I would handle this by making the buffer one larger, so that there is always something to read, even if it is not used. For instance, in my `PK' font reading code: if (rowsize < wb) { /* get more row space */ if (row) free(row); /* keep a slop byte */ row = malloc((unsigned) (wb + 1)); if (row == NULL) return (-1); /* ??? */ rowsize = wb; } ... /* * Finally, begin a new byte, or * add to the current byte, with * j more bits. We know j <= 8-b. * (If j==0, we may be writing on * our slop byte, which is why we * keep one around....) */ -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris