[Gd-chatter] r11603 - in trunk/libraries/packetizer: . packetizer-test

hannes at gwydiondylan.org hannes at gwydiondylan.org
Fri Jan 4 03:22:14 CET 2008


Author: hannes
Date: Fri Jan  4 03:22:13 2008
New Revision: 11603

Modified:
   trunk/libraries/packetizer/module.dylan
   trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan
   trunk/libraries/packetizer/packetizer.dylan
   trunk/libraries/packetizer/protocol-definer-macro.dylan
Log:
Job: 7299
fix parsing of container-frames with a dynamic length expression
assembling those is still broken, added a testcase which shows that
 it is broken (no padding support!)


Modified: trunk/libraries/packetizer/module.dylan
==============================================================================
--- trunk/libraries/packetizer/module.dylan	(original)
+++ trunk/libraries/packetizer/module.dylan	Fri Jan  4 03:22:13 2008
@@ -126,7 +126,9 @@
     <decoded-header-frame>,
     payload, payload-setter;
 
-  export <variably-typed-container-frame>,
+  export <inline-layering-error>,
+    <missing-inline-layering-error>,
+    <variably-typed-container-frame>,
     <unparsed-variably-typed-container-frame>,
     <decoded-variably-typed-container-frame>;
 

Modified: trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan	(original)
+++ trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan	Fri Jan  4 03:22:13 2008
@@ -405,15 +405,59 @@
 define protocol dyn-length-in-container (container-frame)
   length frame.mylength * 8;
   field foo :: <unsigned-byte> = 0;
-  field mylength :: <unsigned-byte> = 3;
+  field mylength :: <unsigned-byte>,
+    fixup: byte-offset(frame-size(frame));
 end;
 
 define test dynlength ()
+  let f = parse-frame(<dyn-length-in-container>, #(#x00, #x02));
+  check-equal("length frame.my-length; size of simple frame is correct", 16, f.frame-size);
+  let field-list = fields(f);
+  static-checker(field-list[0], 0, 8, 8);
+  static-checker(field-list[1], 8, 8, 16);
+  frame-field-checker(0, f, 0, 8, 8);
+  frame-field-checker(1, f, 8, 8, 16);
+  let g = parse-frame(<dyn-length-in-container>, #(#x00, #x03, #x02));
+  check-equal("length frame.my-length; size of frame with padding is correct", 24, g.frame-size);
+  frame-field-checker(0, g, 0, 8, 8);
+  frame-field-checker(1, g, 8, 8, 16);
+  //this tells us: we need padding frame fields!
+end;
+
+define test dynlength-assemble ()
   let f = make(<dyn-length-in-container>);
-  check-equal("size of frame with length is correct", 24, f.frame-size);
   let as = assemble-frame(f);
-  check-equal("size of assembled frame is correct", 3, as.packet.size);
+  check-equal("assembling of dynlength[1] works correct", 2, as.packet[1]);
+  let g = make(<dyn-length-in-container>);
+  let as = assemble-frame(g);
+  check-equal("assembly of dynlength[0] works correct", 0, as.packet[0]);
+  //hah, no padding support!
+  check-equal("assembly of dynlength[1] works correct", 3, as.packet[1]);
+  check-equal("assembly of dynlength[2] works correct", 0, as.packet[2]);
 end;
+
+define protocol dyn-length-as-client-field (container-frame)
+  field first-foo :: <dyn-length-in-container>;
+  field second-foo :: <dyn-length-in-container>;
+end;
+
+define test dyn-length-client ()
+  let f = parse-frame(<dyn-length-as-client-field>, #(#x00, #x02, #x00, #x02));
+  check-equal("size of dyn-length-client is correct", 32, f.frame-size);
+  let field-list = fields(f);
+  static-checker(field-list[0], 0, $unknown-at-compile-time, $unknown-at-compile-time);
+  static-checker(field-list[1], $unknown-at-compile-time, $unknown-at-compile-time, $unknown-at-compile-time);
+  frame-field-checker(0, f, 0, 16, 16);
+  frame-field-checker(1, f, 16, 16, 32);
+end;
+
+define test dyn-length-client2 ()
+  let f = parse-frame(<dyn-length-as-client-field>, #(#x00, #x03, #x04, #x00, #x04, #x01, #x02));
+  check-equal("size of dyn-length-client2 is correct", 56, f.frame-size);
+  frame-field-checker(0, f, 0, 24, 24);
+  frame-field-checker(1, f, 24, 32, 56);
+end;
+
 define suite packetizer-suite ()
   test packetizer-parser;
   test packetizer-dynamic-parser;
@@ -430,6 +474,8 @@
   test half-byte-parsing;
   test dns-foo-parsing;
   test dynlength;
+  test dyn-length-client;
+  test dyn-length-client2;
 end;
 
 define suite packetizer-assemble-suite ()
@@ -448,10 +494,11 @@
   test half-bytes-assembling;
   test bits-assemble;
   test dns-foo-assemble;
+  test dynlength-assemble;
 end;
 
 begin
-  run-test-application(packetizer-suite, arguments: #("-debug"));
-  run-test-application(packetizer-assemble-suite, arguments: #("-debug"));
+  run-test-application(packetizer-suite); //, arguments: #("-debug"));
+  run-test-application(packetizer-assemble-suite); //, arguments: #("-debug"));
 end;
 

Modified: trunk/libraries/packetizer/packetizer.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer.dylan	(original)
+++ trunk/libraries/packetizer/packetizer.dylan	Fri Jan  4 03:22:13 2008
@@ -151,10 +151,6 @@
 
 define open generic container-frame-size (frame :: <container-frame>) => (length :: false-or(<integer>));
 
-define method container-frame-size (frame :: <container-frame>) => (res :: false-or(<integer>))
-  #f
-end;
-
 define open generic frame-size (frame :: type-union(<frame>, subclass(<fixed-size-frame>)))
  => (length :: <integer>);
 
@@ -281,6 +277,12 @@
   end;
 end;
 
+define class <inline-layering-error> (<error>)
+end;
+
+define class <missing-inline-layering-error> (<error>)
+end;
+
 define inline method fixup-protocol-magic (frame :: <variably-typed-container-frame>) => (magic)
   let layer-table = recursive-reverse-layer(frame.object-class);
   if (layer-table)
@@ -288,10 +290,10 @@
     if (res)
       res
     else
-      error("Inline layering not found for %=", frame);
+      signal(make(<inline-layering-error>));
     end;
   else
-    error("No non-empty layering table not found for %=", frame);
+    signal(make(<missing-inline-layering-error>));
   end;
 end;
 
@@ -397,7 +399,11 @@
 define open generic payload-setter (value /* :: false-or(<frame>) */, object :: <header-frame>)
  => (res /* :: false-or(<frame>) */);
 define method frame-size (frame :: <container-frame>) => (res :: <integer>)
-  reduce1(\+, map(curry(get-field-size-aux, frame), frame.fields));
+  block()
+    container-frame-size(frame);
+  exception (e :: <error>)
+    reduce1(\+, map(curry(get-field-size-aux, frame), frame.fields));
+  end;
 end;
 
 define method assemble-frame (frame :: <unparsed-container-frame>) => (packet :: <unparsed-container-frame>);

Modified: trunk/libraries/packetizer/protocol-definer-macro.dylan
==============================================================================
--- trunk/libraries/packetizer/protocol-definer-macro.dylan	(original)
+++ trunk/libraries/packetizer/protocol-definer-macro.dylan	Fri Jan  4 03:22:13 2008
@@ -2,8 +2,6 @@
 Author:    Andreas Bogk, Hannes Mehnert
 Copyright: (C) 2005, 2006,  All rights reserved. Free for non-commercial use.
 
-
-
 define macro protocol-module-definer
   { protocol-module-definer (?:name; ?super:name; ?fields:*) }
  => { define module ?name
@@ -90,7 +88,7 @@
          end;
       end;
       define inline method field-size (frame :: subclass(?name)) => (res :: <number>)
-        if (?#"attrs" = #"abstract")
+        if (find-method(container-frame-size, list(?name)))
           $unknown-at-compile-time;
         else
           static-end(last("$" ## ?name ## "-fields"));
@@ -419,12 +417,14 @@
                    parent: parent);
   let length = field-size(frame-type);
   if (length = $unknown-at-compile-time)
-    let fr-length = container-frame-size(frame);
-    if (fr-length)
-      frame.packet := subsequence(frame.packet, length: fr-length);
-      values(frame, fr-length);
-    else
-      frame
+    block (ret)
+      let fr-length = container-frame-size(frame);
+      if (fr-length)
+        frame.packet := subsequence(frame.packet, length: fr-length);
+        ret(apply(values, frame, fr-length));
+      end;
+    exception (e :: <error>)
+      frame;
     end;
   else
     values(frame, length)



More information about the chatter mailing list