commit - b5568c0ce46c37f080fe97f45bfb67e9744e8fde
commit + da562f47c891cc2678b984fafdc886764783bf4b
blob - b8bbb7e80784e56ddb6d2899270662ef980b569a
blob + 8cc9cd17b99a35b19a32ef4eb9f1e5f3676ee54c
--- pdf.c
+++ pdf.c
}
/* resolve a parsed object to its final semantic value */
+ static void *INVALID = &INVALID; /* a reserved dummy pointer */
+ // XXX move this back into the function
const HParsedToken *
resolve(struct Env *aux, const HParsedToken *v)
{
- static void *INVALID = &INVALID; /* a reserved dummy pointer */
XREntry *ent = NULL;
Ref *r;
XREntry *ent = NULL;
Ref *r;
-
/* the null object maps to NULL */
- if (v == NULL || v->token_type == TT_Null)
+ if (v == NULL || v == INVALID || v->token_type == TT_Null)
return NULL;
/* other direct objects pass through */
if (ent->obj != NULL)
return resolve_item(aux, ent->obj, offset, p);
- /* parse the object and memoize */
- ent->obj = v; /* break loops */
+ /* parse the object */
switch (ent->type)
{
case XR_FREE:
case XR_INUSE:
if (ent->n.gen != r->gen)
return NULL; /* obj nr reused */
- ent->obj = parse_item(aux, r->nr, r->gen, ent->n.offs, p);
+ v = parse_item(aux, r->nr, r->gen, ent->n.offs, p);
*offset = ent->n.offs;
break;
case XR_OBJSTM:
if (r->gen != 0)
return NULL; /* invalid entry! */
- ent->obj = parse_objstm_item(aux, r->nr, ent->o.stm, ent->o.idx, offset, p);
+ v = parse_objstm_item(aux, r->nr, ent->o.stm, ent->o.idx, offset, p);
break;
default:
/*
return NULL;
}
- return resolve_item(aux, ent->obj, offset, p);
+ /* resolve recursively and memoize */
+ ent->obj = INVALID; /* break loops */
+ if ((v = resolve_item(aux, v, offset, p)) != NULL)
+ ent->obj = v;
+
+ assert(v != INVALID); /* our dummy does not escape */
+ return v;
}