int odr_peektag(ODR o, int *zclass, int *tag, int *cons) { if (o->direction != ODR_DECODE) { odr_seterror(o, OOTHER, 48); return 0; } if (ODR_STACK_NOT_EMPTY(o) && !odr_constructed_more(o)) return 0; if (ber_dectag(o->bp, zclass, tag, cons, odr_max(o)) <= 0) { odr_seterror(o, OREQUIRED, 49); return 0; } return 1; }
int completeBER_n(const unsigned char *buf, int len, int level) { int res, ll, zclass, tag, cons; const unsigned char *b = buf; if (level > 1000) { #if BER_ANY_DEBUG yaz_log(YLOG_LOG, "completeBER lev=%d len=%d", level, len); #endif return -2; } if (len < 2) return 0; if (!buf[0] && !buf[1]) return -2; if ((res = ber_dectag(b, &zclass, &tag, &cons, len)) <= 0) return 0; b += res; len -= res; assert (len >= 0); res = ber_declen(b, &ll, len); if (res == -2) { #if BER_ANY_DEBUG yaz_log(YLOG_LOG, "<<<<<<<<< return1 lev=%d res=%d", level, res); #endif return -1; /* error */ } if (res == -1) { #if BER_ANY_DEBUG yaz_log(YLOG_LOG, "<<<<<<<<< return2 lev=%d res=%d", level, res); #endif return 0; /* incomplete length */ } b += res; len -= res; if (ll >= 0) { /* definite length */ if (len < ll) { #if BER_ANY_DEBUG yaz_log(YLOG_LOG, "<<<<<<<<< return5 lev=%d len=%d ll=%d", level, len, ll); #endif return 0; } return ll + (b-buf); } /* indefinite length */ if (!cons) { /* if primitive, it's an error */ #if BER_ANY_DEBUG yaz_log(YLOG_LOG, "<<<<<<<<< return6 lev=%d ll=%d len=%d res=%d", level, ll, len, res); #endif return -1; /* error */ } /* constructed - cycle through children */ while (len >= 2) { if (b[0] == 0 && b[1] == 0) break; res = completeBER_n(b, len, level+1); if (res <= 0) return res; b += res; len -= res; } if (len < 2) return 0; return (b - buf) + 2; }