summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2018-10-30 01:13:44 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2018-10-30 01:15:04 +0100
commitf73e3ddc7bb778efb1c562633f9779bf027117d4 (patch)
treec4c10764d3f0c050194f47134ab04f5d4a8026c9
parentd7abe889accfc4a8e41d97d5f2327fde0ce9ca64 (diff)
downloadocaml-sid-f73e3ddc7bb778efb1c562633f9779bf027117d4.tar.gz
sid: catch more boundary violations
-rw-r--r--sid.ml17
-rw-r--r--sid_test.ml32
2 files changed, 48 insertions, 1 deletions
diff --git a/sid.ml b/sid.ml
index c6c7d3d..cbfe305 100644
--- a/sid.ml
+++ b/sid.ml
@@ -10,6 +10,7 @@ type sid =
and sub_auths = U32.t array
let sizeof_ident_auth = 6
+let max_ident_auth = U64.of_string "0x0000_ffff_ffff_ffff"
let sizeof_sub_auth = 4
let max_subauth_count = 15
@@ -93,10 +94,24 @@ module StringFmt = struct
expect_char s '-' 3;
let p = 4 in
let p, ia = read_decimal_u64 s p in
+ if ia > max_ident_auth then
+ raise (Invalid_argument
+ (Printf.sprintf
+ "Invalid SID: identifier authority cannot fit 6 B (%s)"
+ (U64.to_string max_ident_auth)));
let sa = ref [] and p' = ref p in
while !p' < n - 1 && List.length !sa < max_subauth_count do
expect_char s '-' !p';
- let np, d = read_decimal_u32 s (!p' + 1) in
+ let np, d =
+ try read_decimal_u32 s (!p' + 1)
+ with Invalid_argument e ->
+ (* Brr, but Stdint’s error messages aren’t overly instructive. *)
+ raise (Invalid_argument
+ (Printf.sprintf
+ "Invalid SID: error parsing subauth at position %d, \
+ (err: %s)"
+ (!p' + 1) e))
+ in
sa := d :: !sa;
p' := np
done;
diff --git a/sid_test.ml b/sid_test.ml
index 61e5366..f9e3688 100644
--- a/sid_test.ml
+++ b/sid_test.ml
@@ -1,5 +1,8 @@
open OUnit
+module U64 = Stdint.Uint64
+module U32 = Stdint.Uint32
+
(*
let () = Printexc.record_backtrace true ;;
*)
@@ -76,6 +79,32 @@ let sf_parse_trailing_ok () =
let s = unwrap_of_string "S-1-0-0-" in
assert_equal (Sid.to_string s) "S-1-0-0"
+let sf_parse_maxint_ok () =
+ let s = unwrap_of_string
+ (Printf.sprintf "S-1-281474976710655-%s-%s"
+ (U32.to_string U32.max_int)
+ (U32.to_string U32.max_int))
+ in
+ assert_equal (Sid.to_string s) "S-1-281474976710655-4294967295-4294967295"
+
+let sf_parse_oobia_fail () =
+ match Sid.of_string
+ (Printf.sprintf "S-1-%s-42" (U64.to_string U64.max_int))
+ with
+ | Ok _ -> assert_failure "unexpectedly parsed the out of bounds subauth"
+ | Error e ->
+ assert_equal e "Invalid SID: identifier authority cannot fit 6 B \
+ (281474976710655)"
+
+let sf_parse_oobsa_fail () =
+ match Sid.of_string
+ (Printf.sprintf "S-1-42-%s" (U64.to_string U64.max_int))
+ with
+ | Ok _ -> assert_failure "unexpectedly parsed the out of bounds subauth"
+ | Error e ->
+ assert_equal e "Invalid SID: error parsing subauth at position 7, \
+ (err: Uint32.of_string)"
+
let sf_parse_long_ok () =
let s = unwrap_of_string "S-1-1-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14"
and l = max_sid in
@@ -279,6 +308,9 @@ let string_format_test = "string-format-syntax" >:::
; "parse-junk-fail" >:: sf_parse_junk_fail
; "parse-ia-junk-fail" >:: sf_parse_ia_junk_fail
; "parse-trailing-ok" >:: sf_parse_trailing_ok
+ ; "parse-maxint-ok" >:: sf_parse_maxint_ok
+ ; "parse-oobia-fail" >:: sf_parse_oobia_fail
+ ; "parse-oobsa-fail" >:: sf_parse_oobsa_fail
; "parse-long-ok" >:: sf_parse_long_ok
; "parse-too-long-ok" >:: sf_parse_too_long_ok
]