From f9ddca2f19d966e0d64d5bc6de023dbc3764552c Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 21 Sep 2002 14:12:49 +0000 Subject: [PATCH] Logging fixes. --- base/chiark-tcl.h | 23 ++++++++++++++++++++++- base/hook.c | 33 +++++++++++++++++++++------------ crypto/crypto.c | 43 +++++++++++++++++++------------------------ dgram/dgram.c | 10 +++++----- dgram/sockaddr.c | 13 ++++++++----- hbytes/chop.c | 4 +++- hbytes/hbytes.h | 23 ++++++++++++++++++++++- hbytes/hook.c | 33 +++++++++++++++++++++------------ hbytes/ulongs.c | 39 ++++++++++++++++++++++++--------------- 9 files changed, 145 insertions(+), 76 deletions(-) diff --git a/base/chiark-tcl.h b/base/chiark-tcl.h index 0f38890..7b66932 100644 --- a/base/chiark-tcl.h +++ b/base/chiark-tcl.h @@ -55,6 +55,27 @@ * uint VARNAME/VALUE (VARNAME if ul2bitfields; * ulong VARNAME/VALUE VALUE if bitfields2ul) * + * Error codes + * + * HBYTES BLOCKCIPHER CRYPTFAIL CRYPT block cipher mode failed somehow (!) + * HBYTES BLOCKCIPHER CRYPTFAIL MAC HMAC failed somehow (!) + * HBYTES BLOCKCIPHER LENGTH block cipher input has unsuitable length + * HBYTES BLOCKCIPHER PARAMS key or iv not suitable + * HBYTES HMAC PARAMS key, input or output size not suitable + * HBYTES LENGTH OVERRUN block too long + * HBYTES LENGTH RANGE input length or offset is -ve or silly + * HBYTES LENGTH UNDERRUN block too short (or offset too big) + * HBYTES SYNTAX supposed hex block had wrong syntax + * HBYTES VALUE OVERFLOW value to be conv'd to hex too big/long + * SOCKADDR AFUNIX LENGTH path for AF_UNIX socket too long + * SOCKADDR SYNTAX IPV4 bad IPv4 socket address &/or port + * SOCKADDR SYNTAX OTHER bad socket addr, couldn't tell what kind + * ULONG BITCOUNT NEGATIVE -ve bitcount specified where not allowed + * ULONG BITCOUNT OVERRUN attempt to use more than 32 bits + * ULONG BITCOUNT UNDERRUN bitfields add up to less than 32 + * ULONG VALUE NEGATIVE attempt convert -ve integers to ulong + * ULONG VALUE OVERFLOW converted value does not fit in result + * * Refs: HMAC: RFC2104 */ @@ -153,7 +174,7 @@ typedef struct DgramSocket *DgramSockID; /* from hook.c */ -int staticerr(Tcl_Interp *ip, const char *m); +int staticerr(Tcl_Interp *ip, const char *m, const char *ec); int posixerr(Tcl_Interp *ip, int errnoval, const char *m); void objfreeir(Tcl_Obj *o); int get_urandom(Tcl_Interp *ip, Byte *buffer, int l); diff --git a/base/hook.c b/base/hook.c index 61593ab..9372958 100644 --- a/base/hook.c +++ b/base/hook.c @@ -6,8 +6,9 @@ #include "hbytes.h" #include "tables.h" -int staticerr(Tcl_Interp *ip, const char *m) { +int staticerr(Tcl_Interp *ip, const char *m, const char *ec) { Tcl_SetResult(ip, (char*)m, TCL_STATIC); + if (ec) Tcl_SetObjErrorCode(ip, Tcl_NewStringObj(ec,-1)); return TCL_ERROR; } @@ -146,7 +147,7 @@ static int hbytes_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { objfreeir(o); if (l & 1) return staticerr(ip, "hbytes: conversion from hex:" - " odd length in hex"); + " odd length in hex", "HBYTES SYNTAX"); startbytes= bytes= hbytes_arrayspace(OBJ_HBYTES(o), l/2); @@ -158,7 +159,7 @@ static int hbytes_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { if (ep != cbuf+2) { hbytes_free(OBJ_HBYTES(o)); return staticerr(ip, "hbytes: conversion from hex:" - " bad hex digit"); + " bad hex digit", "HBYTES SYNTAX"); } l -= 2; } @@ -213,9 +214,11 @@ int do_hbytes_overwrite(ClientData cd, Tcl_Interp *ip, sub_l= hbytes_len(&sub); if (start < 0) - return staticerr(ip, "hbytes overwrite start -ve"); + return staticerr(ip, "hbytes overwrite start -ve", + "HBYTES LENGTH RANGE"); if (start + sub_l > hbytes_len(v.hb)) - return staticerr(ip, "hbytes overwrite out of range"); + return staticerr(ip, "hbytes overwrite out of range", + "HBYTES LENGTH UNDERRUN"); memcpy(hbytes_data(v.hb) + start, hbytes_data(&sub), sub_l); return TCL_OK; } @@ -239,8 +242,9 @@ int do_hbytes_repeat(ClientData cd, Tcl_Interp *ip, const Byte *sub_d; sub_l= hbytes_len(&sub); - if (count < 0) return staticerr(ip, "hbytes repeat count -ve"); - if (count > INT_MAX/sub_l) return staticerr(ip, "hbytes repeat too long"); + if (count < 0) return staticerr(ip, "hbytes repeat count -ve", + "HBYTES LENGTH RANGE"); + if (count > INT_MAX/sub_l) return staticerr(ip, "hbytes repeat too long", 0); data= hbytes_arrayspace(result, sub_l*count); sub_d= hbytes_data(&sub); @@ -286,8 +290,11 @@ int do_hbytes_range(ClientData cd, Tcl_Interp *ip, int l; l= hbytes_len(&v); - if (start<0 || size<0 || l2) - return staticerr(ip, "hbytes h2ushort input more than 4 hex digits"); + return staticerr(ip, "hbytes h2ushort input more than 4 hex digits", + "HBYTES VALUE OVERFLOW"); data= hbytes_data(&hex); *result= data[l-1] | (l>1 ? data[0]<<8 : 0); @@ -315,7 +323,8 @@ int do_hbytes_ushort2h(ClientData cd, Tcl_Interp *ip, uint16_t us; if (input > 0x0ffff) - return staticerr(ip, "hbytes ushort2h input >2^16"); + return staticerr(ip, "hbytes ushort2h input >2^16", + "HBYTES VALUE OVERFLOW"); us= htons(input); hbytes_array(result,(const Byte*)&us,2); @@ -363,7 +372,7 @@ int get_urandom(Tcl_Interp *ip, Byte *buffer, int l) { return posixerr(ip,errno,"read " URANDOM); } else { assert(feof(urandom)); - return staticerr(ip, URANDOM " gave eof!"); + return staticerr(ip, URANDOM " gave eof!", 0); } } diff --git a/crypto/crypto.c b/crypto/crypto.c index 457dc9e..1fc1f83 100644 --- a/crypto/crypto.c +++ b/crypto/crypto.c @@ -34,7 +34,7 @@ int do_hbytes_pkcs5(ClientData cd, Tcl_Interp *ip, } else { rc= Tcl_GetIntFromObj(ip, block, &blocksize); if (rc) return rc; if (blocksize < 1 || blocksize > 255) - return staticerr(ip, "block size out of pkcs#5 range 1..255"); + return staticerr(ip, "block size out of pkcs#5 range 1..255", 0); } if (meth->pad) { @@ -175,7 +175,8 @@ static int blockcipher_prep(Tcl_Interp *ip, Tcl_Obj *key_obj, CiphKeyValue *key; if (data_len % alg->blocksize) - return staticerr(ip, "block cipher input not whole number of blocks"); + return staticerr(ip, "block cipher input not whole number of blocks", + "HBYTES BLOCKCIPHER LENGTH"); want_bufferslen= alg->blocksize * (mode->buf_blocks + mode->iv_blocks); key= get_key(ip, key_obj, alg, want_bufferslen); if (!key) return TCL_ERROR; @@ -184,8 +185,10 @@ static int blockcipher_prep(Tcl_Interp *ip, Tcl_Obj *key_obj, || !decrypt) ? &key->alpha : &key->beta; sched= *schedp; if (!sched) { - if (key->valuelen < alg->key_min) return staticerr(ip, "key too short"); - if (key->valuelen > alg->key_max) return staticerr(ip, "key too long"); + if (key->valuelen < alg->key_min) + return staticerr(ip, "key too short", "HBYTES BLOCKCIPHER PARAMS"); + if (key->valuelen > alg->key_max) + return staticerr(ip, "key too long", "HBYTES BLOCKCIPHER PARAMS"); sched= TALLOC(alg->schedule_size); (decrypt ? &alg->decrypt : &alg->encrypt)->make_schedule @@ -196,15 +199,16 @@ static int blockcipher_prep(Tcl_Interp *ip, Tcl_Obj *key_obj, want_iv= alg->blocksize * mode->iv_blocks; if (!want_iv) { if (!hbytes_issentinel(iv)) - return staticerr(ip,"iv supplied but mode does not take one"); + return staticerr(ip,"iv supplied but mode does not take one", 0); } else if (hbytes_issentinel(iv)) { - if (decrypt) return staticerr(ip,"must supply iv when decrypting"); + if (decrypt) return staticerr(ip,"must supply iv when decrypting", 0); rc= get_urandom(ip, key->buffers, want_iv); if (rc) return rc; } else { int iv_supplied= hbytes_len(iv); if (iv_supplied > want_iv) - return staticerr(ip, "iv too large for algorithm and mode"); + return staticerr(ip, "iv too large for algorithm and mode", + "HBYTES BLOCKCIPHER PARAMS"); memcpy(key->buffers, hbytes_data(iv), iv_supplied); memset(key->buffers + iv_supplied, 0, want_iv - iv_supplied); } @@ -243,7 +247,7 @@ int do_blockcipherop_e(ClientData cd, Tcl_Interp *ip, int nblocks; if (!mode->encrypt) - return staticerr(ip, "mode does not support encrypt/decrypt"); + return staticerr(ip, "mode does not support encrypt/decrypt", 0); rc= blockcipher_prep(ip,key_obj,&iv,!encrypt, alg,mode, hbytes_len(v.hb), @@ -257,7 +261,7 @@ int do_blockcipherop_e(ClientData cd, Tcl_Interp *ip, (hbytes_data(v.hb), nblocks, ivbuf, buffers, alg, encrypt, sched); if (failure) - return staticerr(ip, failure); + return staticerr(ip, failure, "HBYTES BLOCKCIPHER CRYPTFAIL CRYPT"); hbytes_array(result, ivbuf, iv_lenbytes); @@ -277,7 +281,7 @@ int do_blockcipherop_mac(ClientData cd, Tcl_Interp *ip, int rc; if (!mode->mac) - return staticerr(ip, "mode does not support mac generation"); + return staticerr(ip, "mode does not support mac generation", 0); rc= blockcipher_prep(ip,key_obj,&iv,0, alg,mode, hbytes_len(&msg), @@ -288,19 +292,13 @@ int do_blockcipherop_mac(ClientData cd, Tcl_Interp *ip, failure= mode->mac(hbytes_data(&msg), nblocks, ivbuf, buffers, alg, sched); if (failure) - return staticerr(ip,failure); + return staticerr(ip,failure, "HBYTES BLOCKCIPHER CRYPTFAIL MAC"); hbytes_array(result, buffers, alg->blocksize * mode->mac_blocks); return TCL_OK; } -static void dbuf(const char *m, const Byte *a, int l) { - fprintf(stderr,"dbuf %s l=%d ",m,l); - while (l-->0) fprintf(stderr,"%02x",*a++); - putc('\n',stderr); -} - int do_hbytes_hmac(ClientData cd, Tcl_Interp *ip, const HashAlgInfo *alg, HBytes_Value message, Tcl_Obj *key_obj, Tcl_Obj *maclen_obj, HBytes_Value *result) { @@ -315,7 +313,8 @@ int do_hbytes_hmac(ClientData cd, Tcl_Interp *ip, const HashAlgInfo *alg, if (maclen_obj) { rc= Tcl_GetIntFromObj(ip, maclen_obj, &ml); if (rc) return rc; if (ml<0 || ml>alg->hashsize) - return staticerr(ip, "requested hmac output size out of range"); + return staticerr(ip, "requested hmac output size out of range", + "HBYTES HMAC PARAMS"); } else { ml= alg->hashsize; } @@ -328,23 +327,21 @@ int do_hbytes_hmac(ClientData cd, Tcl_Interp *ip, const HashAlgInfo *alg, assert(!key->beta); if (key->valuelen > alg->blocksize) - return staticerr(ip, "key to hmac longer than hash block size"); + return staticerr(ip, "key to hmac longer than hash block size", + "HBYTES HMAC PARAMS"); -dbuf("start key",key->value,key->valuelen); memcpy(key->buffers, key->value, key->valuelen); memset(key->buffers + key->valuelen, 0, alg->blocksize - key->valuelen); for (i=0; iblocksize; i++) key->buffers[i] ^= 0x36; key->alpha= TALLOC(alg->statesize); alg->init(key->alpha); -dbuf("inner key",key->buffers,alg->blocksize); alg->update(key->alpha, key->buffers, alg->blocksize); key->beta= TALLOC(alg->statesize); alg->init(key->beta); for (i=0; iblocksize; i++) key->buffers[i] ^= (0x5c ^ 0x36); alg->update(key->beta, key->buffers, alg->blocksize); -dbuf("inner key",key->buffers,alg->blocksize); } assert(key->beta); @@ -353,12 +350,10 @@ dbuf("inner key",key->buffers,alg->blocksize); memcpy(key->buffers, key->alpha, alg->statesize); alg->update(key->buffers, hbytes_data(&message), hbytes_len(&message)); alg->final(key->buffers, dest); -dbuf("inner hash",dest,alg->hashsize); memcpy(key->buffers, key->beta, alg->statesize); alg->update(key->buffers, dest, alg->hashsize); alg->final(key->buffers, dest); -dbuf("outer hash",dest,alg->hashsize); hbytes_unappend(result, alg->hashsize - ml); diff --git a/dgram/dgram.c b/dgram/dgram.c index 0dd40aa..e541a3a 100644 --- a/dgram/dgram.c +++ b/dgram/dgram.c @@ -76,7 +76,7 @@ int do_dgram_socket_transmit(ClientData cd, Tcl_Interp *ip, 0, sockaddr_addr(&remote), sockaddr_len(&remote)); if (r==-1) return posixerr(ip,errno,"sendto"); - else if (r!=l) return staticerr(ip,"sendto gave wrong answer"); + else if (r!=l) return staticerr(ip,"sendto gave wrong answer",0); return TCL_OK; } @@ -200,7 +200,7 @@ int pat_sockid(Tcl_Interp *ip, Tcl_Obj *o, DgramSocket **val) { sockix= o->internalRep.longValue; if (sockix >= n_socks || !(sock= socks[sockix])) - return staticerr(ip,"dgram socket not open"); + return staticerr(ip,"dgram socket not open",0); assert(socks[sockix]->ix == sockix); @@ -240,10 +240,10 @@ static int sockid_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { char *ep, *str; str= Tcl_GetStringFromObj(o,0); - if (memcmp(str,"dgramsock",9)) return staticerr(ip,"bad dgram socket id"); + if (memcmp(str,"dgramsock",9)) return staticerr(ip,"bad dgram socket id",0); errno=0; ul=strtoul(str+9,&ep,10); - if (errno || *ep) return staticerr(ip,"bad dgram socket id number"); - if (ul > INT_MAX) return staticerr(ip,"out of range dgram socket id"); + if (errno || *ep) return staticerr(ip,"bad dgram socket id number",0); + if (ul > INT_MAX) return staticerr(ip,"out of range dgram socket id",0); objfreeir(o); o->internalRep.longValue= ul; diff --git a/dgram/sockaddr.c b/dgram/sockaddr.c index a191cac..c5592ea 100644 --- a/dgram/sockaddr.c +++ b/dgram/sockaddr.c @@ -137,7 +137,7 @@ static int sockaddr_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { else { assert(str[0]=='/' && str[1]!='/'); path=str; } if (strlen(str) >= sizeof(s.sun.sun_path)) - return staticerr(ip, "AF_UNIX path too long"); + return staticerr(ip, "AF_UNIX path too long", "SOCKADDR AFUNIX LENGTH"); strcpy(s.sun.sun_path, path); @@ -159,21 +159,24 @@ static int sockaddr_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { } TFREE(copy); - if (!iprv) return staticerr(ip, "bad IPv4 address syntax"); + if (!iprv) + return staticerr(ip, "bad IPv4 address syntax", "SOCKADDR SYNTAX IPV4"); comma++; if (!strcmp(comma,"*")) { s.sin.sin_port= 0; } else { errno=0; port_l=strtoul(comma,&ep,10); - if (errno || *ep) return staticerr(ip, "bad IPv4 port"); - if (port_l > 65535) return staticerr(ip, "IPv4 port out of range"); + if (errno || *ep) + return staticerr(ip, "bad IPv4 port", "SOCKADDR SYNTAX IPV4"); + if (port_l > 65535) + return staticerr(ip, "IPv4 port out of range", "SOCKADDR SYNTAX IPV4"); s.sin.sin_port= htons(port_l); } } else { - return staticerr(ip, "bad socket address syntax"); + return staticerr(ip, "bad socket address syntax", "SOCKADDR SYNTAX OTHER"); } diff --git a/hbytes/chop.c b/hbytes/chop.c index 48eb770..cccd43f 100644 --- a/hbytes/chop.c +++ b/hbytes/chop.c @@ -62,7 +62,9 @@ int do_hbytes_concat(ClientData cd, Tcl_Interp *ip, return TCL_OK; } -static int underrun(Tcl_Interp *ip) { return staticerr(ip,"data underrun"); } +static int underrun(Tcl_Interp *ip) { + return staticerr(ip,"data underrun","HBYTES LENGTH UNDERRUN"); +} int do_hbytes_unprepend(ClientData cd, Tcl_Interp *ip, HBytes_Var v, int preflength, HBytes_Value *result) { diff --git a/hbytes/hbytes.h b/hbytes/hbytes.h index 0f38890..7b66932 100644 --- a/hbytes/hbytes.h +++ b/hbytes/hbytes.h @@ -55,6 +55,27 @@ * uint VARNAME/VALUE (VARNAME if ul2bitfields; * ulong VARNAME/VALUE VALUE if bitfields2ul) * + * Error codes + * + * HBYTES BLOCKCIPHER CRYPTFAIL CRYPT block cipher mode failed somehow (!) + * HBYTES BLOCKCIPHER CRYPTFAIL MAC HMAC failed somehow (!) + * HBYTES BLOCKCIPHER LENGTH block cipher input has unsuitable length + * HBYTES BLOCKCIPHER PARAMS key or iv not suitable + * HBYTES HMAC PARAMS key, input or output size not suitable + * HBYTES LENGTH OVERRUN block too long + * HBYTES LENGTH RANGE input length or offset is -ve or silly + * HBYTES LENGTH UNDERRUN block too short (or offset too big) + * HBYTES SYNTAX supposed hex block had wrong syntax + * HBYTES VALUE OVERFLOW value to be conv'd to hex too big/long + * SOCKADDR AFUNIX LENGTH path for AF_UNIX socket too long + * SOCKADDR SYNTAX IPV4 bad IPv4 socket address &/or port + * SOCKADDR SYNTAX OTHER bad socket addr, couldn't tell what kind + * ULONG BITCOUNT NEGATIVE -ve bitcount specified where not allowed + * ULONG BITCOUNT OVERRUN attempt to use more than 32 bits + * ULONG BITCOUNT UNDERRUN bitfields add up to less than 32 + * ULONG VALUE NEGATIVE attempt convert -ve integers to ulong + * ULONG VALUE OVERFLOW converted value does not fit in result + * * Refs: HMAC: RFC2104 */ @@ -153,7 +174,7 @@ typedef struct DgramSocket *DgramSockID; /* from hook.c */ -int staticerr(Tcl_Interp *ip, const char *m); +int staticerr(Tcl_Interp *ip, const char *m, const char *ec); int posixerr(Tcl_Interp *ip, int errnoval, const char *m); void objfreeir(Tcl_Obj *o); int get_urandom(Tcl_Interp *ip, Byte *buffer, int l); diff --git a/hbytes/hook.c b/hbytes/hook.c index 61593ab..9372958 100644 --- a/hbytes/hook.c +++ b/hbytes/hook.c @@ -6,8 +6,9 @@ #include "hbytes.h" #include "tables.h" -int staticerr(Tcl_Interp *ip, const char *m) { +int staticerr(Tcl_Interp *ip, const char *m, const char *ec) { Tcl_SetResult(ip, (char*)m, TCL_STATIC); + if (ec) Tcl_SetObjErrorCode(ip, Tcl_NewStringObj(ec,-1)); return TCL_ERROR; } @@ -146,7 +147,7 @@ static int hbytes_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { objfreeir(o); if (l & 1) return staticerr(ip, "hbytes: conversion from hex:" - " odd length in hex"); + " odd length in hex", "HBYTES SYNTAX"); startbytes= bytes= hbytes_arrayspace(OBJ_HBYTES(o), l/2); @@ -158,7 +159,7 @@ static int hbytes_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { if (ep != cbuf+2) { hbytes_free(OBJ_HBYTES(o)); return staticerr(ip, "hbytes: conversion from hex:" - " bad hex digit"); + " bad hex digit", "HBYTES SYNTAX"); } l -= 2; } @@ -213,9 +214,11 @@ int do_hbytes_overwrite(ClientData cd, Tcl_Interp *ip, sub_l= hbytes_len(&sub); if (start < 0) - return staticerr(ip, "hbytes overwrite start -ve"); + return staticerr(ip, "hbytes overwrite start -ve", + "HBYTES LENGTH RANGE"); if (start + sub_l > hbytes_len(v.hb)) - return staticerr(ip, "hbytes overwrite out of range"); + return staticerr(ip, "hbytes overwrite out of range", + "HBYTES LENGTH UNDERRUN"); memcpy(hbytes_data(v.hb) + start, hbytes_data(&sub), sub_l); return TCL_OK; } @@ -239,8 +242,9 @@ int do_hbytes_repeat(ClientData cd, Tcl_Interp *ip, const Byte *sub_d; sub_l= hbytes_len(&sub); - if (count < 0) return staticerr(ip, "hbytes repeat count -ve"); - if (count > INT_MAX/sub_l) return staticerr(ip, "hbytes repeat too long"); + if (count < 0) return staticerr(ip, "hbytes repeat count -ve", + "HBYTES LENGTH RANGE"); + if (count > INT_MAX/sub_l) return staticerr(ip, "hbytes repeat too long", 0); data= hbytes_arrayspace(result, sub_l*count); sub_d= hbytes_data(&sub); @@ -286,8 +290,11 @@ int do_hbytes_range(ClientData cd, Tcl_Interp *ip, int l; l= hbytes_len(&v); - if (start<0 || size<0 || l2) - return staticerr(ip, "hbytes h2ushort input more than 4 hex digits"); + return staticerr(ip, "hbytes h2ushort input more than 4 hex digits", + "HBYTES VALUE OVERFLOW"); data= hbytes_data(&hex); *result= data[l-1] | (l>1 ? data[0]<<8 : 0); @@ -315,7 +323,8 @@ int do_hbytes_ushort2h(ClientData cd, Tcl_Interp *ip, uint16_t us; if (input > 0x0ffff) - return staticerr(ip, "hbytes ushort2h input >2^16"); + return staticerr(ip, "hbytes ushort2h input >2^16", + "HBYTES VALUE OVERFLOW"); us= htons(input); hbytes_array(result,(const Byte*)&us,2); @@ -363,7 +372,7 @@ int get_urandom(Tcl_Interp *ip, Byte *buffer, int l) { return posixerr(ip,errno,"read " URANDOM); } else { assert(feof(urandom)); - return staticerr(ip, URANDOM " gave eof!"); + return staticerr(ip, URANDOM " gave eof!", 0); } } diff --git a/hbytes/ulongs.c b/hbytes/ulongs.c index e352ba1..e8ea9a8 100644 --- a/hbytes/ulongs.c +++ b/hbytes/ulongs.c @@ -8,7 +8,8 @@ int do_ulong_int2ul(ClientData cd, Tcl_Interp *ip, int v, uint32_t *result) { - if (v<0) return staticerr(ip,"cannot convert -ve integer to ulong"); + if (v<0) return + staticerr(ip,"cannot convert -ve integer to ulong","ULONG VALUE NEGATIVE"); *result= v; return TCL_OK; } @@ -35,7 +36,8 @@ int do_ulong_compare(ClientData cd, Tcl_Interp *ip, int do_ulong_ul2int(ClientData cd, Tcl_Interp *ip, uint32_t v, int *result) { - if (v>INT_MAX) return staticerr(ip,"ulong too large to fit in an int"); + if (v>INT_MAX) return + staticerr(ip,"ulong too large to fit in an int", "ULONG VALUE OVERFLOW"); *result= v; return TCL_OK; } @@ -48,7 +50,9 @@ int do_ulong_mask(ClientData cd, Tcl_Interp *ip, int do_ulong_shift(ClientData cd, Tcl_Interp *ip, int right, uint32_t v, int bits, uint32_t *result) { - if (bits > 32) return staticerr(ip,"shift out of range (32) bits"); + if (bits < 0) { bits= -bits; right= !right; } + if (bits > 32) return + staticerr(ip,"shift out of range (32) bits", "ULONG BITCOUNT OVERRUN"); *result= (bits==32 ? 0 : right ? v >> bits : v << bits); return TCL_OK; @@ -116,15 +120,16 @@ static int bf_uint_write(Tcl_Interp *ip, uint32_t *value_io, int *ok_io, Tcl_Obj *arg) { int rc, v; rc= pat_int(ip, arg, &v); if (rc) return rc; - if (v<0) return staticerr(ip,"value for bitfield is -ve"); + if (v<0) return + staticerr(ip,"value for bitfield is -ve", "ULONG VALUE NEGATIVE"); *value_io= v; return TCL_OK; } static int bf_uint_read(Tcl_Interp *ip, uint32_t *value_io, int *ok_io, Tcl_Obj *arg) { - if (*value_io > INT_MAX) - return staticerr(ip,"value from bitfield exceeds INT_MAX"); + if (*value_io > INT_MAX) return + staticerr(ip,"value from bitfield exceeds INT_MAX","ULONG VALUE OVERFLOW"); return bf_var_read(ip,arg, ret_int(ip,*value_io)); } @@ -152,10 +157,12 @@ static int do_bitfields(Tcl_Interp *ip, int writing, int *ok_r, while (--objc) { rc= Tcl_GetIntFromObj(ip,*++objv,&sz); if (rc) return rc; - if (!--objc) return staticerr(ip,"wrong # args: missing bitfield type"); + if (!--objc) return staticerr(ip,"wrong # args: missing bitfield type",0); - if (sz<0) return staticerr(ip,"bitfield size is -ve"); - if (sz>pos) return staticerr(ip,"total size of bitfields >32"); + if (sz<0) + return staticerr(ip,"bitfield size is -ve", "ULONG BITCOUNT NEGATIVE"); + if (sz>pos) return + staticerr(ip,"total size of bitfields >32", "ULONG BITCOUNT OVERRUN"); pos -= sz; @@ -168,7 +175,7 @@ static int do_bitfields(Tcl_Interp *ip, int writing, int *ok_r, if (ftype->want_arg) { if (!--objc) - return staticerr(ip,"wrong # args: missing arg for bitfield"); + return staticerr(ip,"wrong # args: missing arg for bitfield",0); arg= *++objv; } else { arg= 0; @@ -179,14 +186,15 @@ static int do_bitfields(Tcl_Interp *ip, int writing, int *ok_r, if (!*ok_r) return TCL_OK; if (this_field & ~sz_mask) - return staticerr(ip,"bitfield value has more bits than bitfield"); + return staticerr(ip,"bitfield value has more bits than bitfield", + "ULONG VALUE OVERFLOW"); value &= ~this_mask; value |= (this_field << pos); } - if (pos != 0) - return staticerr(ip,"bitfield sizes add up to <32"); + if (pos != 0) return + staticerr(ip,"bitfield sizes add up to <32","ULONG BITCOUNT UNDERRUN"); *value_io= value; return TCL_OK; @@ -261,7 +269,8 @@ static int ulong_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { int l; l= hbytes_len(OBJ_HBYTES(o)); - if (l > 4) return staticerr(ip, "hbytes as ulong must be of length < 4"); + if (l > 4) return + staticerr(ip,"hbytes as ulong with length >4","HBYTES LENGTH OVERRUN"); ul= 0; memcpy((Byte*)&ul + 4 - l, hbytes_data(OBJ_HBYTES(o)), l); ul= htonl(ul); @@ -277,7 +286,7 @@ static int ulong_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { } else { ul= strtoul(str,&ep,16); } - if (*ep || errno) return staticerr(ip, "bad unsigned long value"); + if (*ep || errno) return staticerr(ip, "bad unsigned long value", 0); } -- 2.30.2