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:
parent
5d2b1e3cb3
commit
e10f455fbd
1 changed files with 51 additions and 55 deletions
106
firmware/font.c
106
firmware/font.c
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue