source: proto/u16u8/QA/u16u8_testgen.py @ 357

Last change on this file since 357 was 357, checked in by cameron, 9 years ago

Initialize u16u8 project with QA framework.

File size: 4.7 KB
Line 
1from random import randint
2from binascii import b2a_hex
3
4def random_codepoint(UTF8_lgth):
5    if UTF8_lgth == 1: return randint(0, 0x7F)
6    if UTF8_lgth == 2: return randint(0, 0x7FF)
7    if UTF8_lgth == 3: codepoint = randint(0, 0xF7FF)
8    else: codepoint = randint(0, 0x10F7FF)
9    if codepoint <= 0xD7FF: return codepoint
10    else: return codepoint + 0x800
11
12def UTF8_length(cp):
13    if cp <= 0x7F: return 1
14    elif cp <= 0x7FF: return 2
15    elif cp <= 0xFFFF: return 3
16    else: return 4
17   
18def UTF16_length(cp):
19    if cp <= 0xFFFF: return 1
20    else: return 2
21
22
23def random_sequence_of_given_UTF16_length(pfx_type, lgth):
24    seq = []
25    remaining = lgth
26    while remaining > 0:
27        cp = random_codepoint(pfx_type)
28        cp_lgth = UTF16_length(cp)
29        if cp_lgth <= remaining:
30            seq.append(cp)
31            remaining -= cp_lgth
32    return seq
33
34def codepoint_to_UTF8(cp):
35    if cp <= 0x7F: return chr(cp)
36    suffix = chr(0x80 + (cp & 0x3F))
37    if cp <= 0x7FF:
38        return chr(0xC0 + (cp >> 6)) + suffix
39    suffix = chr(0x80 + ((cp >> 6) & 0x3F)) + suffix
40    if cp <= 0xFFFF:
41        return chr(0xE0 + (cp >> 12)) + suffix
42    suffix = chr(0x80 + ((cp >> 12) & 0x3F)) + suffix
43    return chr(0xF0 + (cp >> 18)) + suffix
44   
45def codepoint_to_UTF16BE(cp):
46    if cp <= 0xFFFF:
47        return chr(cp >> 8) + chr(cp & 0xFF)
48    else:
49        b = cp - 0x10000
50        return chr(0xD8 + (b >> 18)) + chr((b >> 10) & 0xFF) + chr(0xDC + ((b >> 8) & 0x3)) + chr(b & 0xFF)
51
52def codepoint_seq_to_UTF8(cpseq):
53    utf8 = []
54    for cp in cpseq: utf8 += codepoint_to_UTF8(cp)
55    return utf8
56
57def codepoint_seq_to_UTF16BE(cpseq):
58    utf16 = []
59    for cp in cpseq: utf16 += codepoint_to_UTF16BE(cp)
60    return utf16
61
62def random_nonsuffix():
63    byte = randint(0, 0xFF)
64    if byte <= 0x7F: return byte
65    else: return randint(0xC2, 0xF4)
66
67def gen_UTF16_error_sequences():
68    return [[randint(0xD8, 0xDB), randint(0x00, 0xFF), randint(0x00, 0xDB), randint(0x00, 0xFF)],
69             [randint(0xD8, 0xDB), randint(0x00, 0xFF), randint(0xE0, 0xFF), randint(0x00, 0xFF)],
70             [randint(0xDC, 0xDF), randint(0x00, 0xFF)]]
71             
72def gen_UTF16_incomplete_sequences():
73    return [[randint(0xD8, 0xDB), randint(0x00, 0xFF)]]
74
75
76
77def gen_err_string(error_sequence):
78    s = ''
79    for byte_val in error_sequence: s+= chr(byte_val)
80    return s
81
82prefix_groups = [(0,0), (1,4), (29,31), (60,64), (124,128), (129, 2045), (2046, 2047), (2048, 4196)]
83suffix_groups = [(0,0), (1, 4), (5,128), (500, 5000)]
84
85def generate_illegal_sequence_tests():
86   for pfx in prefix_groups:
87       for sfx in suffix_groups:
88           for error_seq in gen_UTF16_error_sequences():
89               pfx_lgth = randint(pfx[0], pfx[1])
90               sfx_lgth = randint(sfx[0], sfx[1])
91               pfx_type = randint(1,4)
92               sfx_type = randint(1,4)
93               pfx_seq = random_sequence_of_given_UTF16_length(pfx_type, pfx_lgth)
94               sfx_seq = random_sequence_of_given_UTF16_length(sfx_type, sfx_lgth)
95               err_string = gen_err_string(error_seq)
96               filename = 'Illegal_UTF-16_%s@%i' % (b2a_hex(err_string), (2*pfx_lgth))
97               f1 = file('TestFiles/' + filename, 'w')
98               for cp in pfx_seq: f1.write(codepoint_to_UTF16BE(cp))
99               f1.write(err_string)
100               for cp in sfx_seq: f1.write(codepoint_to_UTF16BE(cp))
101               f1.close()
102               f2 = file('ExpectedOutput/Files/' + filename, 'w')
103               for cp in pfx_seq: f2.write(codepoint_to_UTF8(cp))
104               f2.close()
105               f3 = file('ExpectedOutput/Messages/' + filename, 'w')
106               f3.write("Illegal UTF-16 sequence at position %i in source.\n" % (2*pfx_lgth))
107               f3.close()
108
109def generate_incomplete_sequence_tests():
110   for pfx in prefix_groups:
111       for error_seq in gen_UTF16_incomplete_sequences():
112           pfx_lgth = randint(pfx[0], pfx[1])
113           pfx_type = randint(1,4)
114           pfx_seq = random_sequence_of_given_UTF16_length(pfx_type, pfx_lgth)
115           err_string = gen_err_string(error_seq)
116           filename = 'Incomplete_UTF-16_%s@%i' % (b2a_hex(err_string), (2*pfx_lgth))
117           f1 = file('TestFiles/' + filename, 'w')
118           for cp in pfx_seq: f1.write(codepoint_to_UTF16BE(cp))
119           f1.write(err_string)
120           f1.close()
121           f2 = file('ExpectedOutput/Files/' + filename, 'w')
122           for cp in pfx_seq: f2.write(codepoint_to_UTF8(cp))
123           f2.close()
124           f3 = file('ExpectedOutput/Messages/' + filename, 'w')
125           f3.write("EOF with incomplete UTF-16 sequence at position %i in source.\n" % (2*pfx_lgth))
126           f3.close()
127
128if __name__ == "__main__":
129        generate_illegal_sequence_tests()
130        generate_incomplete_sequence_tests()
131
Note: See TracBrowser for help on using the repository browser.