1
0
Fork 0
forked from len0rd/rockbox

Simplify the readshort/readlong/readstr functions - move the bounds checking into the calling function (which allows bounds-checking in chunks) and change the readshort/readlong functions (which now always succeed) to return the value read instead of a result code. Indirectly closes FS #7026

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13143 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dave Chapman 2007-04-13 19:51:19 +00:00
parent 5d2b1e3cb3
commit e10f455fbd

View file

@ -72,16 +72,24 @@ void font_init(void)
memset(&font_ui, 0, sizeof(struct font)); memset(&font_ui, 0, sizeof(struct font));
} }
static int readshort(unsigned short *sp) /* Check if we have x bytes left in the file buffer */
#define HAVEBYTES(x) (fileptr + (x) <= eofptr)
/* Helper functions to read big-endian unaligned short or long from
the file buffer. Bounds-checking must be done in the calling
function.
*/
static short readshort(void)
{ {
unsigned short s; unsigned short s;
s = *fileptr++ & 0xff; s = *fileptr++ & 0xff;
*sp = (*fileptr++ << 8) | s; s |= (*fileptr++ << 8);
return (fileptr <= eofptr); return s;
} }
static long readlong(unsigned long *lp) static long readlong(void)
{ {
unsigned long l; unsigned long l;
@ -89,18 +97,14 @@ static long readlong(unsigned long *lp)
l |= *fileptr++ << 8; l |= *fileptr++ << 8;
l |= ((unsigned long)(*fileptr++)) << 16; l |= ((unsigned long)(*fileptr++)) << 16;
l |= ((unsigned long)(*fileptr++)) << 24; l |= ((unsigned long)(*fileptr++)) << 24;
*lp = l; return l;
return (fileptr <= eofptr);
} }
/* read count bytes*/ /* read count bytes*/
static int readstr(char *buf, int count) static void readstr(char *buf, int count)
{ {
int n = count; while (count--)
while (--n >= 0)
*buf++ = *fileptr++; *buf++ = *fileptr++;
return (fileptr <= eofptr)? count: 0;
} }
void font_reset(void) void font_reset(void)
@ -111,44 +115,30 @@ void font_reset(void)
static struct font* font_load_header(struct font *pf) static struct font* font_load_header(struct font *pf)
{ {
char version[4+1]; char version[4+1];
unsigned short maxwidth, height, ascent, pad;
unsigned long firstchar, defaultchar, size; /* Check we have enough data */
unsigned long nbits; if (!HAVEBYTES(28))
return NULL;
/* read magic and version #*/ /* read magic and version #*/
memset(version, 0, sizeof(version)); memset(version, 0, sizeof(version));
if (readstr(version, 4) != 4) readstr(version, 4);
return NULL;
if (strcmp(version, VERSION) != 0) if (strcmp(version, VERSION) != 0)
return NULL; return NULL;
/* font info*/ /* font info*/
if (!readshort(&maxwidth)) pf->maxwidth = readshort();
return NULL; pf->height = readshort();
pf->maxwidth = maxwidth; pf->ascent = readshort();
if (!readshort(&height)) fileptr += 2; /* Skip padding */
return NULL; pf->firstchar = readlong();
pf->height = height; pf->defaultchar = readlong();
if (!readshort(&ascent)) pf->size = readlong();
return NULL;
pf->ascent = ascent;
if (!readshort(&pad))
return NULL;
if (!readlong(&firstchar))
return NULL;
pf->firstchar = firstchar;
if (!readlong(&defaultchar))
return NULL;
pf->defaultchar = defaultchar;
if (!readlong(&size))
return NULL;
pf->size = size;
/* get variable font data sizes*/ /* get variable font data sizes*/
/* # words of bitmap_t*/ /* # words of bitmap_t*/
if (!readlong(&nbits)) pf->bits_size = readlong();
return NULL;
pf->bits_size = nbits;
return pf; return pf;
} }
@ -157,13 +147,14 @@ struct font* font_load_in_memory(struct font* pf)
{ {
long i, noffset, nwidth; long i, noffset, nwidth;
/* # longs of offset*/ if (!HAVEBYTES(4))
if (!readlong(&noffset))
return NULL; return NULL;
/* # longs of offset*/
noffset = readlong();
/* # bytes of width*/ /* # bytes of width*/
if (!readlong(&nwidth)) nwidth = readlong();
return NULL;
/* variable font data*/ /* variable font data*/
pf->bits = (unsigned char *)fileptr; pf->bits = (unsigned char *)fileptr;
@ -186,24 +177,28 @@ struct font* font_load_in_memory(struct font* pf)
{ {
long_offset = 0; long_offset = 0;
pf->offset = (unsigned short *)fileptr; pf->offset = (unsigned short *)fileptr;
/* Check we have sufficient buffer */
if (!HAVEBYTES(noffset * sizeof(short)))
return NULL;
for (i=0; i<noffset; ++i) for (i=0; i<noffset; ++i)
{ {
unsigned short offset; ((unsigned short*)(pf->offset))[i] = (unsigned short)readshort();
if (!readshort(&offset))
return NULL;
((unsigned short*)(pf->offset))[i] = (unsigned short)offset;
} }
} }
else else
{ {
long_offset = 1; long_offset = 1;
pf->offset = (unsigned short *)fileptr; pf->offset = (unsigned short *)fileptr;
/* Check we have sufficient buffer */
if (!HAVEBYTES(noffset * sizeof(long)))
return NULL;
for (i=0; i<noffset; ++i) for (i=0; i<noffset; ++i)
{ {
unsigned long offset; ((unsigned long*)(pf->offset))[i] = (unsigned long)readlong();
if (!readlong(&offset))
return NULL;
((unsigned long*)(pf->offset))[i] = (unsigned long)offset;
} }
} }
} }
@ -229,13 +224,14 @@ struct font* font_load_cached(struct font* pf)
unsigned long noffset, nwidth; unsigned long noffset, nwidth;
unsigned char* oldfileptr = fileptr; unsigned char* oldfileptr = fileptr;
/* # longs of offset*/ if (!HAVEBYTES(2 * sizeof(long)))
if (!readlong(&noffset))
return NULL; return NULL;
/* # longs of offset*/
noffset = readlong();
/* # bytes of width*/ /* # bytes of width*/
if (!readlong(&nwidth)) nwidth = readlong();
return NULL;
/* We are now at the bitmap data, this is fixed at 36.. */ /* We are now at the bitmap data, this is fixed at 36.. */
pf->bits = NULL; pf->bits = NULL;