···910(* Test that encode_utf8 never crashes on arbitrary input *)
11let test_encode_no_crash input =
12- let _ = Punycode.encode_utf8 input in
13- ()
1415(* Test that decode_utf8 never crashes on arbitrary input *)
16let test_decode_no_crash input =
17- let _ = Punycode.decode_utf8 input in
18- ()
1920-(* Test roundtrip: encode then decode should give back original *)
021let test_roundtrip input =
22 match Punycode.encode_utf8 input with
23 | Ok encoded -> (
24 match Punycode.decode_utf8 encoded with
25- | Ok decoded -> check_eq ~pp:Format.pp_print_string input decoded
000026 | Error _ ->
27 (* Some encoded values might not decode, that's ok for fuzz testing *)
28- ())
29 | Error _ ->
30 (* Some inputs might not encode, that's ok *)
31- ()
32-33-(* Test that error printing never crashes *)
34-let () =
35- let pos = { Punycode.byte_offset = 0; char_index = 0 } in
36- let errors =
37- [
38- Punycode.Overflow pos;
39- Punycode.Invalid_character (pos, Uchar.of_int 0x1F600);
40- Punycode.Invalid_digit (pos, 'x');
41- Punycode.Unexpected_end pos;
42- Punycode.Invalid_utf8 pos;
43- Punycode.Label_too_long 100;
44- Punycode.Empty_label;
45- ]
46- in
47- List.iter
48- (fun e ->
49- let _ = Format.asprintf "%a" Punycode.pp_error e in
50- let _ = Punycode.error_to_string e in
51- ())
52- errors
5354(* Test ASCII-only strings (should pass through mostly unchanged) *)
55let test_ascii_string input =
56- let ascii_only =
57- String.init
58- (String.length input mod 64)
59- (fun i -> Char.chr (Char.code input.[i mod String.length input] mod 128))
60- in
61- if String.length ascii_only > 0 then
62- match Punycode.encode ascii_only with Ok _ -> () | Error _ -> ()
00006364(* Test inputs starting with ACE prefix "xn--" *)
65let test_ace_prefix input =
66 let ace_input = "xn--" ^ input in
67- let _ = Punycode.decode_utf8 ace_input in
68- ()
6970let () =
71 add_test ~name:"punycode: encode no crash" [ bytes ] test_encode_no_crash;
···910(* Test that encode_utf8 never crashes on arbitrary input *)
11let test_encode_no_crash input =
12+ ignore (Punycode.encode_utf8 input);
13+ check true
1415(* Test that decode_utf8 never crashes on arbitrary input *)
16let test_decode_no_crash input =
17+ ignore (Punycode.decode_utf8 input);
18+ check true
1920+(* Test roundtrip: encode then decode should give back original (case-insensitive)
21+ IDNA/Punycode lowercases ASCII characters during encoding per RFC 5891 *)
22let test_roundtrip input =
23 match Punycode.encode_utf8 input with
24 | Ok encoded -> (
25 match Punycode.decode_utf8 encoded with
26+ | Ok decoded ->
27+ (* Compare lowercase versions since IDNA lowercases ASCII *)
28+ check_eq ~pp:Format.pp_print_string
29+ (String.lowercase_ascii input)
30+ (String.lowercase_ascii decoded)
31 | Error _ ->
32 (* Some encoded values might not decode, that's ok for fuzz testing *)
33+ check true)
34 | Error _ ->
35 (* Some inputs might not encode, that's ok *)
36+ check true
0000000000000000000003738(* Test ASCII-only strings (should pass through mostly unchanged) *)
39let test_ascii_string input =
40+ if String.length input > 0 then begin
41+ let ascii_only =
42+ String.init
43+ (String.length input mod 64)
44+ (fun i ->
45+ Char.chr (Char.code input.[i mod String.length input] mod 128))
46+ in
47+ if String.length ascii_only > 0 then
48+ ignore (Punycode.encode_utf8 ascii_only)
49+ end;
50+ check true
5152(* Test inputs starting with ACE prefix "xn--" *)
53let test_ace_prefix input =
54 let ace_input = "xn--" ^ input in
55+ ignore (Punycode.decode_utf8 ace_input);
56+ check true
5758let () =
59 add_test ~name:"punycode: encode no crash" [ bytes ] test_encode_no_crash;