X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=odr%2Fber_oid.c;h=905a4821da80484bd79ab6e7e5f98e5ea208974c;hb=8bccad6217bd2ba078106a531a9e73e7f3aae4a9;hp=b2c6d1109c0eb8eb97ce0dbb758a2d39eff3dc01;hpb=6c126e94642b41867fb323ff39fded733757a11e;p=yaz-moved-to-github.git diff --git a/odr/ber_oid.c b/odr/ber_oid.c index b2c6d11..905a482 100644 --- a/odr/ber_oid.c +++ b/odr/ber_oid.c @@ -1,93 +1,113 @@ /* - * Copyright (C) 1994, Index Data I/S - * All rights reserved. + * Copyright (c) 1995-2003, Index Data + * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Log: ber_oid.c,v $ - * Revision 1.2 1995-02-14 20:39:55 quinn - * Fixed bugs in completeBER and (serious one in) ber_oid. - * - * Revision 1.1 1995/02/03 17:04:36 quinn - * Initial revision - * + * $Id: ber_oid.c,v 1.15 2003-03-11 11:03:31 adam Exp $ */ +#if HAVE_CONFIG_H +#include +#endif -#include +#include "odr-priv.h" -int ber_oid(ODR o, Odr_oid *p) +int ber_oidc(ODR o, Odr_oid *p) { - int len; - unsigned char *lenp; + int len, lenp, end; int pos, n, res, id; unsigned char octs[8]; switch (o->direction) { - case ODR_DECODE: - if ((res = ber_declen(o->bp, &len)) < 1) - return 0; - if (len < 0) - return 0; - o->bp += res; - o->left -= res; - if (len == 0) - { - *p = -1; - return 1; - } - p[0] = *o->bp / 40; - if (p[0] > 2) - p[0] = 2; - p[1] = *o->bp - p[0] * 40; - o->bp++; - o->left--; - pos = 2; - len--; - while (len) - { - p[pos] = 0; - do - { - if (!len) - return 0; - p[pos] <<= 7; - p[pos] |= *o->bp & 0X7F; - len--; - o->left--; - } - while (*(o->bp++) & 0X80); - pos++; - } - p[pos] = -1; - return 1; - case ODR_ENCODE: - /* we'll allow ourselves the quiet luxury of only doing encodings - shorter than 127 */ - lenp = o->bp; - o->bp++; - o->left--; - if (p[0] < 0 && p[1] <= 0) - return 0; - p[1] = p[0] * 40 + p[1]; - for (pos = 1; p[pos] >= 0; pos++) - { - id = p[pos]; - n = 0; - do - { - octs[n++] = id & 0X7F; - id >>= 7; - } - while (id); - if (n > o->left) - return 0; - o->left -= n; - while (n--) - *(o->bp++) = octs[n] | ((n > 0) << 7); - } - if (ber_enclen(lenp, (o->bp - lenp) - 1, 1, 1) != 1) - return 0; - return 1; - default: return 0; + case ODR_DECODE: + if ((res = ber_declen(o->bp, &len, odr_max(o))) < 1) + { + odr_seterror(o, OPROTO, 18); + return 0; + } + if (len < 0) + { + odr_seterror(o, OPROTO, 19); + return 0; + } + o->bp += res; + if (len == 0) + { + *p = -1; + return 1; + } + if (len > odr_max(o)) + { + odr_seterror(o, OPROTO, 20); + return 0; + } + p[0] = *o->bp / 40; + if (p[0] > 2) + p[0] = 2; + p[1] = *o->bp - p[0] * 40; + o->bp++; + pos = 2; + len--; + while (len) + { + p[pos] = 0; + do + { + if (!len) + { + odr_seterror(o, OPROTO, 21); + return 0; + } + p[pos] <<= 7; + p[pos] |= *o->bp & 0X7F; + len--; + } + while (*(o->bp++) & 0X80); + pos++; + } + p[pos] = -1; + return 1; + case ODR_ENCODE: + /* we'll allow ourselves the quiet luxury of only doing encodings + shorter than 127 */ + lenp = odr_tell(o); + if (odr_putc(o, 0) < 0) /* dummy */ + return 0; + if (p[0] < 0 && p[1] <= 0) + { + odr_seterror(o, ODATA, 23); + return 0; + } + for (pos = 1; p[pos] >= 0; pos++) + { + id = pos > 1 ? p[pos] : p[0] * 40 + p[1]; + n = 0; + do + { + octs[n++] = id & 0X7F; + id >>= 7; + } + while (id); + while (n--) + { + unsigned char p; + + p = octs[n] | ((n > 0) << 7); + if (odr_putc(o, p) < 0) + return 0; + } + } + end = odr_tell(o); + odr_seek(o, ODR_S_SET, lenp); + if (ber_enclen(o, (end - lenp) - 1, 1, 1) != 1) + { + odr_seterror(o, OOTHER, 52); + return 0; + } + odr_seek(o, ODR_S_END, 0); + return 1; + default: + odr_seterror(o, OOTHER, 22); + return 0; } }