--- ray/src/common/readoct.c 1989/04/23 19:38:51 1.5 +++ ray/src/common/readoct.c 1991/10/23 11:53:38 1.14 @@ -1,4 +1,4 @@ -/* Copyright (c) 1986 Regents of the University of California */ +/* Copyright (c) 1991 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -18,14 +18,15 @@ static char SCCSid[] = "$SunId$ LBL"; #include "otypes.h" -double atof(); -double getflt(); -long getint(); -char *getstr(); -OCTREE getfullnode(), gettree(); +extern double atof(); +static double getflt(); +static long getint(); +static char *getstr(); +static OCTREE getfullnode(), gettree(); static char *infn; /* input file name */ static FILE *infp; /* input file stream */ +static int objsize; /* size of stored OBJECT's */ static OBJECT objorig; /* zeroeth object */ static short otypmap[NUMOTYPE+8]; /* object type map */ @@ -37,8 +38,10 @@ int load; CUBE *scene; char *ofn[]; { - char sbuf[128]; + extern int fputs(); + char sbuf[512]; int nf; + OBJECT fnobjects; register int i; if (fname == NULL) { @@ -53,13 +56,12 @@ char *ofn[]; } } /* get header */ - if (load & IO_INFO) - copyheader(infp, stdout); - else - getheader(infp, NULL); + if (checkheader(infp, OCTFMT, load&IO_INFO ? stdout : NULL) < 0) + octerror(USER, "not an octree"); /* check format */ - if (getint(2) != OCTMAGIC) - octerror(USER, "invalid octree format"); + if ((objsize = getint(2)-OCTMAGIC) <= 0 || + objsize > MAXOBJSIZ || objsize > sizeof(long)) + octerror(USER, "incompatible octree format"); /* get boundaries */ if (load & IO_BOUNDS) { for (i = 0; i < 3; i++) @@ -80,6 +82,8 @@ char *ofn[]; } if (load & IO_FILES) ofn[nf] = NULL; + /* get number of objects */ + fnobjects = getint(objsize); if (load & IO_TREE) { /* get the octree */ @@ -94,6 +98,13 @@ char *ofn[]; } while (getobj() != OVOID) ; + } else if (load & IO_SCENE) { /* consistency checks */ + /* check object count */ + if (nobjects != objorig+fnobjects) + octerror(USER, "bad object count; octree stale?"); + /* check for non-surfaces */ + if (nonsurfinset(objorig, fnobjects)) + octerror(USER, "non-surface in set; octree stale?"); } } fclose(infp); @@ -122,12 +133,18 @@ getfullnode() /* get a set, return fullnode */ { OBJECT set[MAXSET+1]; register int i; + register long m; - set[0] = getint(sizeof(OBJECT)); - if (set[0] > MAXSET) + m = getint(objsize); + if (m > MAXSET) octerror(USER, "bad set in getfullnode"); - for (i = 1; i <= set[0]; i++) - set[i] = getint(sizeof(OBJECT)) + objorig; + set[0] = m; + for (i = 1; i <= set[0]; i++) { + m = getint(objsize) + objorig; + if ((OBJECT)m != m) + octerror(USER, "too many objects"); + set[i] = m; + } return(fullnode(set)); } @@ -139,16 +156,18 @@ register int siz; register int c; register long r; - c = getc(infp); - r = c&0x80 ? -1L : 0L; /* sign extend */ - ungetc(c, infp); - while (siz--) { + if ((c = getc(infp)) == EOF) + goto end_file; + r = 0x80&c ? -1<<8|c : c; /* sign extend */ + while (--siz > 0) { if ((c = getc(infp)) == EOF) - octerror(USER, "truncated octree"); + goto end_file; r <<= 8; r |= c; } return(r); +end_file: + octerror(USER, "truncated octree"); } @@ -159,7 +178,7 @@ getflt() /* get a floating point number */ double d; d = (double)getint(4)/0x7fffffff; - return(ldexp(d, getint(1))); + return(ldexp(d, (int)getint(1))); } @@ -194,6 +213,7 @@ getobj() /* get next object */ char sbuf[MAXSTR]; int obj; register int i; + register long m; register OBJREC *objp; i = getint(1); @@ -204,8 +224,12 @@ getobj() /* get next object */ objp = objptr(obj); if ((objp->otype = otypmap[i]) < 0) octerror(USER, "reference to unknown type"); - if ((objp->omod = getint(sizeof(OBJECT))) != OVOID) - objp->omod += objorig; + if ((m = getint(objsize)) != OVOID) { + m += objorig; + if ((OBJECT)m != m) + octerror(USER, "too many objects"); + } + objp->omod = m; objp->oname = savqstr(getstr(sbuf)); if (objp->oargs.nsargs = getint(2)) { objp->oargs.sarg = (char **)bmalloc