Source

ocaml-bert / bert.ml

Diff from to

File bert.ml

   and local_decode local_bin = 
       (* see http://www.erlang.org/doc/apps/erts/erl_ext_dist.html for details*)
     begin match (String.get local_bin 0) with
+
       | 'a' ->  (* SMALL_INTEGER_EXT *)
-	  Ok( Int(int_of_char (String.get local_bin 1)), Str.string_after local_bin 2)
+	  if String.length local_bin > 1 then
+	    Ok( Int(int_of_char (String.get local_bin 1)), Str.string_after local_bin 2)
+	  else
+	    More(2);
       | 'b' ->  (* INTEGER_EXT *)
-	  Ok( Int( make_int32 (String.sub local_bin 1 5)), Str.string_after local_bin 5);
+	  if String.length local_bin > 4 then
+	    Ok( Int( make_int32 (String.sub local_bin 1 5)), Str.string_after local_bin 5)
+	  else 
+	    More(5);
+
       | 'c' -> (* FLOAT_EXT *)
-	  let v = Scanf.sscanf (String.sub local_bin 1 32) "%f" (fun x->x) in
-	    Ok( Float( v ), Str.string_after local_bin 32); 
+	  if String.length local_bin > 31 then	  
+	    let v = Scanf.sscanf (String.sub local_bin 1 32) "%f" (fun x->x) in
+	      Ok( Float( v ), Str.string_after local_bin 32); 
+	  else 
+	    More(32);
+
       | 'd' -> (* ATOM_EXT *)
 	  let len = (int_of_char (String.get local_bin 1))*256 + (int_of_char (String.get local_bin 2)) in
-	    Ok( Atom( String.sub local_bin 3 len ), Str.string_after local_bin (len+3) );
+	    if String.length local_bin > (len+2) then	  
+	      Ok( Atom( String.sub local_bin 3 len ), Str.string_after local_bin (len+3) )
+	    else
+	      More(len+3);
+
       | 'e' -> (* REFERENCE_EXT *)
 	  raise Not_supported;
       | 'f' -> (* PORT_EXT *)
 	  raise Not_supported;
       | 'g' -> (* PID_EXT *)
 	  raise Not_supported;
+
       | 'h' -> (* SMALL_TUPLE_EXT *)
 	  let len = int_of_char (String.get local_bin 1) in
 	    decode_tuple len (Str.string_after local_bin 2) []; (* is it OK to use list? *)
       | 'i' -> (* LARGE_TUPLE_EXT *)
 	  let len = make_int32 (String.sub local_bin 1 5) in
 	    decode_tuple len (Str.string_after local_bin 5) []; (* is it OK to use list? *)
+
       | 'j' -> (* NIL_EXT *)
 	  Ok( Nil, Str.string_after local_bin 1);
+
       | 'k' -> (* STRING_EXT *)
 	  let len = (int_of_char (String.get local_bin 1))*256 + (int_of_char (String.get local_bin 2)) in
-	    Ok( String( String.sub local_bin 3 len ), Str.string_after local_bin (len+3) );
+	    if String.length local_bin > (len+2) then
+	      Ok( String( String.sub local_bin 3 len ), Str.string_after local_bin (len+3) )
+	    else
+	      More(len+3);
+
       | 'l' -> (* LIST_EXT *)
 	  let len = make_int32 (String.sub local_bin 1 5) in
 	    decode_list len (Str.string_after local_bin 5) [];
-	  (*raise Not_supported; *)
+
       | 'm' -> (* BINARY_EXT *)
 	  let len = make_int32 (String.sub local_bin 1 5) in
-	  let remain = Str.string_after local_bin 5 in (* TODO: you'd better use Str.split *)
-	    Ok( Binary( Str.string_before remain len ),  Str.string_after remain len );
+	    if String.length local_bin > (4+len) then
+	      let remain = Str.string_after local_bin 5 in (* TODO: you'd better use Str.split *)
+		Ok( Binary( Str.string_before remain len ),  Str.string_after remain len )
+	    else
+	      More(5+len);
+
       | 'n' -> (* SMALL_BIG_EXT *)
 	  let n = int_of_char (String.get local_bin 1) in
-	  let sign = int_of_char  (String.get local_bin 2) in
-	  let result = make_small_bigint (String.sub local_bin 3 n) n in
-	    if sign=0 then 
-	      Ok( Int(result), Str.string_after local_bin (n+3) )
-	    else if sign=1 then
-	      Ok( Int(-result), Str.string_after local_bin (n+3) )
-	    else 
-	      raise Unknown_type;
+	    if String.length local_bin > (n+2) then
+	      let sign = int_of_char  (String.get local_bin 2) in
+	      let result = make_small_bigint (String.sub local_bin 3 n) n in
+		if sign=0 then 
+		  Ok( Int(result), Str.string_after local_bin (n+3) )
+		else if sign=1 then
+		  Ok( Int(-result), Str.string_after local_bin (n+3) )
+		else 
+		  raise Unknown_type
+	    else
+	      More(n+3);
+
       | 'o' -> (* LARGE_BIG_EXT *)
 	  let n = make_int32 local_bin in
-	  let sign = int_of_char  (String.get local_bin 5) in
-	  let result = make_small_bigint (String.sub local_bin 6 n) n in
-	    if sign=0 then 
-	      Ok( Int(result), Str.string_after local_bin (n+6) )
-	    else if sign=1 then
-	      Ok( Int(-result), Str.string_after local_bin (n+6) )
-	    else 
-	      raise Unknown_type;
+	    if String.length local_bin > (n+5) then
+	      let sign = int_of_char  (String.get local_bin 5) in
+	      let result = make_small_bigint (String.sub local_bin 6 n) n in
+		if sign=0 then 
+		  Ok( Int(result), Str.string_after local_bin (n+6) )
+		else if sign=1 then
+		  Ok( Int(-result), Str.string_after local_bin (n+6) )
+		else 
+		  raise Unknown_type
+	    else
+	      More(n+6);
+
       | 'p' -> (* NEW_REFERENCE_EXT *)
 	  raise Not_supported;
       | 'q' -> (* SMALL_ATOM_EXT *)
-	  let len = int_of_char (String.get local_bin 1) in   
-	    Ok( Atom( String.sub local_bin 2 len ), Str.string_after local_bin (len+2) );
+	  let len = int_of_char (String.get local_bin 1) in
+	    if String.length local_bin > (len+1) then
+	      Ok( Atom( String.sub local_bin 2 len ), Str.string_after local_bin (len+2) )
+	    else
+	      More( len+2 );
+
       | 'r' -> (* FUN_EXT *)
 	  raise Not_supported;	    
       | 's' -> (* NEW_FUN_EXT *)