chiark / gitweb /
use of int and overflow review
[chiark-tcl.git] / cdb / writeable.c
index 6259ea05ea9803a41b619896cc56771774bbbeeb..0df1b2799ae55a59e60672c23e99fe56f97304aa 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "chiark_tcl_cdb.h"
 
+#define KEYLEN_MAX (INT_MAX/2)
+
 #define ftello ftell
 #define fseeko fseek
 
@@ -44,7 +46,8 @@ typedef struct Pathbuf {
 #define MAX_SUFFIX 5
 
 static void pathbuf_init(Pathbuf *pb, const char *pathb) {
-  int l= strlen(pathb);
+  size_t l= strlen(pathb);
+  assert(l < INT_MAX);
   pb->buf= TALLOC(l + MAX_SUFFIX + 1);
   memcpy(pb->buf, pathb, l);
   pb->sfx= pb->buf + l;
@@ -250,7 +253,7 @@ static int readlognum(FILE *f, int delim, int *num_r) {
   *p= 0;
 
   errno=0; ul= strtoul(numbuf, &ep, 10);
-  if (*ep || errno || ul >= INT_MAX/2) return -2;
+  if (*ep || errno || ul >= KEYLEN_MAX) return -2;
   *num_r= ul;
   return 0;
 }
@@ -313,7 +316,7 @@ static int readstorelogrecord(FILE *f, HashTable *ht,
 static int writerecord(FILE *f, const char *key, const HashValue *val) {
   int r;
 
-  r= fprintf(f, "+%d,%d:%s->", strlen(key), val->len, key);
+  r= fprintf(f, "+%d,%d:%s->", (int)strlen(key), val->len, key);
   if (r<0) return -1;
   
   r= fwrite(val->data, 1, val->len, f);
@@ -859,6 +862,9 @@ static int update(Tcl_Interp *ip, Rw *rw, const char *key,
   HashValue *val;
   int rc, r;
 
+  if (strlen(key) >= KEYLEN_MAX)
+    return cht_staticerr(ip, "key too long", "CDB KEYOVERFLOW");
+
   if (!rw->logfile) return cht_staticerr
     (ip, "previous compact failed; cdbwr must be closed and reopened "
      "before any further updates", "CDB BROKEN");