@@ -6,59 +6,44 @@ def test_rfc9112_parse_as_octets():
6
6
""" RFC 9112 Section 2.2-2: MUST parse HTTP message as sequence of octets."""
7
7
print (" Testing: Parse HTTP message as sequence of octets..." )
8
8
9
- # Test that we parse HTTP messages as individual octets, not Unicode characters
10
9
var http_message = " GET /path HTTP/1.1\r\n Host: example.com\r\n\r\n "
11
10
var octets = http_message.as_bytes()
12
11
13
- # Verify we access individual octets (bytes), not Unicode code points
14
- testing.assert_equal(octets[0 ], ord (' G' )) # First octet is 'G'
15
- testing.assert_equal(octets[4 ], ord (' /' )) # Fifth octet is '/'
12
+ testing.assert_equal(octets[0 ], ord (' G' ))
13
+ testing.assert_equal(octets[4 ], ord (' /' ))
16
14
17
- # Find the first CR and LF octets in the message
18
15
var found_cr = False
19
16
var found_lf = False
20
17
for i in range (len (octets)):
21
- if octets[i] == 0x 0D and not found_cr: # First CR
18
+ if octets[i] == 0x 0D and not found_cr:
22
19
found_cr = True
23
- if octets[i] == 0x 0A and not found_lf: # First LF
20
+ if octets[i] == 0x 0A and not found_lf:
24
21
found_lf = True
25
22
if found_cr and found_lf:
26
23
break
27
24
28
- testing.assert_true(found_cr) # CR found as octet
29
- testing.assert_true(found_lf) # LF found as octet
30
-
31
- print (" ✓ HTTP message parsed as sequence of octets" )
25
+ testing.assert_true(found_cr)
26
+ testing.assert_true(found_lf)
32
27
33
28
34
29
def test_rfc9112_us_ascii_superset_encoding ():
35
30
""" RFC 9112 Section 2.2-2: MUST use encoding that is superset of US-ASCII."""
36
31
print (" Testing: Encoding is superset of US-ASCII..." )
37
32
38
- # US-ASCII range is 0x00-0x7F
39
- # ISO-8859-1 (0x00-0xFF) is a valid superset
40
-
41
- # Test US-ASCII characters are valid
42
33
testing.assert_true(ord (' G' ) <= 0x 7F ) # US-ASCII
43
34
testing.assert_true(ord (' ' ) <= 0x 7F ) # US-ASCII
44
35
testing.assert_true(0x 0A <= 0x 7F ) # LF in US-ASCII
45
36
testing.assert_true(0x 0D <= 0x 7F ) # CR in US-ASCII
46
-
47
- # Test that superset (ISO-8859-1) includes extended range
48
37
testing.assert_true(0x 80 <= 0x FF ) # Extended range valid
49
38
testing.assert_true(0x FF <= 0x FF ) # Maximum byte valid
50
-
51
- print (" ✓ Encoding is superset of US-ASCII (ISO-8859-1)" )
52
39
53
40
54
41
def test_rfc9112_lf_security_vulnerability ():
55
42
""" RFC 9112 Section 2.2-2: Prevent LF (%x 0A) security vulnerabilities."""
56
43
print (" Testing: LF (%x 0A) security vulnerability prevention..." )
57
44
58
- # The critical security issue: LF (%x0A) in multibyte sequences
59
45
var lf_octet : UInt8 = 0x 0A
60
46
61
- # When parsed as octets (safe), LF is clearly identifiable
62
47
var test_data = " GET /\r\n Host: test\r\n\r\n "
63
48
var data_octets = test_data.as_bytes()
64
49
@@ -67,22 +52,16 @@ def test_rfc9112_lf_security_vulnerability():
67
52
if data_octets[i] == lf_octet:
68
53
lf_positions.append(i)
69
54
70
- # Should find LF octets at specific positions
71
55
testing.assert_true(len (lf_positions) > 0 )
72
- print (" ✓ LF (%x 0A) handled safely as octet" )
73
- print (" - Found " + String(len (lf_positions)) + " LF octets in message" )
74
- print (" - No multibyte character sequence confusion" )
75
56
76
57
77
58
def test_rfc9112_string_parser_safety ():
78
59
""" RFC 9112 Section 2.2-2: String parsers only used after protocol element extraction."""
79
60
print (" Testing: String parsers used only after safe extraction..." )
80
61
81
- # Demonstrate the RFC requirement: protocol elements extracted as octets first
82
62
var http_request = " GET /api/data HTTP/1.1\r\n Host: server.com\r\n\r\n "
83
63
var request_octets = http_request.as_bytes()
84
64
85
- # Step 1: Extract protocol elements as octets (safe)
86
65
var method_end = - 1
87
66
for i in range (len (request_octets)):
88
67
if request_octets[i] == ord (' ' ):
@@ -91,15 +70,10 @@ def test_rfc9112_string_parser_safety():
91
70
92
71
testing.assert_true(method_end > 0 )
93
72
94
- # Step 2: Verify the extracted octets match expected method
95
- testing.assert_equal(request_octets[0 ], ord (' G' )) # First octet
96
- testing.assert_equal(request_octets[1 ], ord (' E' )) # Second octet
97
- testing.assert_equal(request_octets[2 ], ord (' T' )) # Third octet
98
- testing.assert_equal(method_end, 3 ) # Method is 3 octets
99
-
100
- print (" ✓ String parsing only after protocol element extraction" )
101
- print (" - Protocol elements extracted as octets first" )
102
- print (" - String conversion only after safe extraction" )
73
+ testing.assert_equal(request_octets[0 ], ord (' G' ))
74
+ testing.assert_equal(request_octets[1 ], ord (' E' ))
75
+ testing.assert_equal(request_octets[2 ], ord (' T' ))
76
+ testing.assert_equal(method_end, 3 )
103
77
104
78
105
79
def main ():
0 commit comments