chiark / gitweb /
check for extra bits
[chiark-tcl.git] / maskmap / maskmap.c
index 1ae8439b6a3c28acac50ee6e1f729968f7e6a659..1f122e9f114e53a85749cde15a7227a3774f0fc4 100644 (file)
@@ -36,21 +36,22 @@ static void mme_free(MaskMap_Entry *mme) {
 }
 
 static int mme_parsekey(Tcl_Interp *ip, MaskMap_Entry *mme,
-                       Tcl_Obj *prefixo, Tcl_Obj *prefixleno,
+                       Tcl_Obj *prefixo, Tcl_Obj *prefixbitso,
                        int inmap) {
  /* *mme should be blank entry; after exit (even error exit) it will be valid
   * - on errors, it will be blank.  inmap is 1 if we're parsing an existing
   * map or 0 if it's an entry to be added or modified. */
   HBytes_Value prefix;
-  int suppliedprefixbytes, prefixlen, wantprefixbytes;
+  int suppliedprefixbytes, prefixbits, wantprefixbytes, sparebits;
+  const Byte *data;
   int rc;
 
   hbytes_empty(&prefix);
   
   rc= pat_hb(ip,prefixo,&prefix);  if (rc) goto x_rc;
-  rc= pat_int(ip,prefixleno,&prefixlen);  if (rc) goto x_rc;
+  rc= pat_int(ip,prefixbitso,&prefixbits);  if (rc) goto x_rc;
 
-  wantprefixbytes= prefix_bytes(prefixlen);
+  wantprefixbytes= prefix_bytes(prefixbits);
   suppliedprefixbytes= hbytes_len(&prefix);
 
   if (suppliedprefixbytes < wantprefixbytes) {
@@ -63,9 +64,17 @@ static int mme_parsekey(Tcl_Interp *ip, MaskMap_Entry *mme,
                  "HBYTES MASKMAP SYNTAX OVERRUN");
     goto x_rc;
   }
-  mme->prefixlen= prefixlen;
+  sparebits= wantprefixbytes*8 - prefixbits;
+  data= hbytes_data(&prefix);
+  if (sparebits && (data[wantprefixbytes-1] & ((1u << sparebits)-1))) {
+    rc= staticerr(ip, "mask-map entry PREFIX contains bits excluded"
+                 " by PREFIX-LEN", "HBYTES MASKMAP SYNTAX EXCLBITS");
+    goto x_rc;
+  }
+
+  mme->prefixlen= prefixbits;
   mme->prefix= TALLOC(wantprefixbytes);  assert(mme->prefix);
-  memcpy(mme->prefix, hbytes_data(&prefix), wantprefixbytes);
+  memcpy(mme->prefix, data, wantprefixbytes);
   return TCL_OK;
 
  x_rc:
@@ -102,7 +111,8 @@ static void mm_allocentries(MaskMap_Value *mm, int len) {
 int do_maskmap_amend(ClientData cd, Tcl_Interp *ip,
                     MaskMap_Var map, HBytes_Value prefix,
                     int preflen, Tcl_Obj *data) {
-  return TCL_OK; /*fixme*/
+  
+  return TCL_OK;
 }
 
 int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip,