chiark / gitweb /
Logging fixes.
authorian <ian>
Sat, 21 Sep 2002 14:12:49 +0000 (14:12 +0000)
committerian <ian>
Sat, 21 Sep 2002 14:12:49 +0000 (14:12 +0000)
base/chiark-tcl.h
base/hook.c
crypto/crypto.c
dgram/dgram.c
dgram/sockaddr.c
hbytes/chop.c
hbytes/hbytes.h
hbytes/hook.c
hbytes/ulongs.c

index 0f38890..7b66932 100644 (file)
  *               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);
index 61593ab..9372958 100644 (file)
@@ -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 || l<start+size)
-    return staticerr(ip, "hbytes range subscripts out of range");
+  if (start<0 || size<0)
+    return staticerr(ip,"hbytes range subscript(s) -ve","HBYTES LENGTH RANGE");
+  if (l<start+size)
+    return staticerr(ip, "hbytes range subscripts too big",
+                    "HBYTES LENGTH UNDERRUN");
 
   data= hbytes_data(&v);
   hbytes_array(result, data+start, size);
@@ -303,7 +310,8 @@ int do_hbytes_h2ushort(ClientData cd, Tcl_Interp *ip,
 
   l= hbytes_len(&hex);
   if (l>2)
-    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);
   }
 }
 
index 457dc9e..1fc1f83 100644 (file)
@@ -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; i<alg->blocksize; 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; i<alg->blocksize; 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);
 
index 0dd40aa..e541a3a 100644 (file)
@@ -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;
index a191cac..c5592ea 100644 (file)
@@ -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");
 
   }
 
index 48eb770..cccd43f 100644 (file)
@@ -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) {
index 0f38890..7b66932 100644 (file)
  *               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);
index 61593ab..9372958 100644 (file)
@@ -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 || l<start+size)
-    return staticerr(ip, "hbytes range subscripts out of range");
+  if (start<0 || size<0)
+    return staticerr(ip,"hbytes range subscript(s) -ve","HBYTES LENGTH RANGE");
+  if (l<start+size)
+    return staticerr(ip, "hbytes range subscripts too big",
+                    "HBYTES LENGTH UNDERRUN");
 
   data= hbytes_data(&v);
   hbytes_array(result, data+start, size);
@@ -303,7 +310,8 @@ int do_hbytes_h2ushort(ClientData cd, Tcl_Interp *ip,
 
   l= hbytes_len(&hex);
   if (l>2)
-    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);
   }
 }
 
index e352ba1..e8ea9a8 100644 (file)
@@ -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);
 
   }