1#!./parrot
2# Copyright (C) 2006-2012, Parrot Foundation.
3
4=head1 NAME
5
6t/library/mime_base64.t - MIME::Base64 tests
7
8=head1 SYNOPSIS
9
10    % prove t/library/mime_base64.t
11
12=head1 DESCRIPTION
13
14
15This file contains various tests related to base64 encoding and decoding.  Some
16test cases were taken from base64.t of MIME::Base64 from Perl 5.
17
18=cut
19
20.sub test :main
21    load_bytecode "dumper.pbc"
22    load_bytecode 'Test/More.pbc'
23    load_bytecode 'MIME/Base64.pbc'
24    load_bytecode 'PGE.pbc'
25    load_bytecode 'PGE/Util.pbc'
26    load_language 'data_json'
27
28    .local pmc plan, is, ok, lives_ok
29    plan     = get_hll_global [ 'Test'; 'More' ], 'plan'
30    is       = get_hll_global [ 'Test'; 'More' ], 'is'
31    ok       = get_hll_global [ 'Test'; 'More' ], 'ok'
32
33    plan(551)
34
35    .local pmc json
36    json = compreg 'data_json'
37
38    .local pmc encode_decode_tests, decode_tests
39    encode_decode_tests = json.'compile'( <<'END_JSON' )
40[ ["Hello, World!\n","SGVsbG8sIFdvcmxkIQo="],
41  ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
42  "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh\nYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYQ=="],
43  ["\u0000","AA=="],
44  ["\u0001","AQ=="],
45  ["\u0002","Ag=="],
46  ["\u0003","Aw=="],
47  ["\u0004","BA=="],
48  ["\u0005","BQ=="],
49  ["\u0006","Bg=="],
50  ["\u0007","Bw=="],
51  ["\b","CA=="],
52  ["\t","CQ=="],
53  ["\n","Cg=="],
54  ["\u000b","Cw=="],
55  ["\f","DA=="],
56  ["\r","DQ=="],
57  ["\u000e","Dg=="],
58  ["\u000f","Dw=="],
59  ["\u0010","EA=="],
60  ["\u0011","EQ=="],
61  ["\u0012","Eg=="],
62  ["\u0013","Ew=="],
63  ["\u0014","FA=="],
64  ["\u0015","FQ=="],
65  ["\u0016","Fg=="],
66  ["\u0017","Fw=="],
67  ["\u0018","GA=="],
68  ["\u0019","GQ=="],
69  ["\u001a","Gg=="],
70  ["\u001b","Gw=="],
71  ["\u001c","HA=="],
72  ["\u001d","HQ=="],
73  ["\u001e","Hg=="],
74  ["\u001f","Hw=="],
75  [" ","IA=="],
76  ["!","IQ=="],
77  ["\"","Ig=="],
78  ["#","Iw=="],
79  ["$","JA=="],
80  ["%","JQ=="],
81  ["&","Jg=="],
82  ["'","Jw=="],
83  ["(","KA=="],
84  [")","KQ=="],
85  ["*","Kg=="],
86  ["+","Kw=="],
87  [",","LA=="],
88  ["-","LQ=="],
89  [".","Lg=="],
90  ["/","Lw=="],
91  ["0","MA=="],
92  ["1","MQ=="],
93  ["2","Mg=="],
94  ["3","Mw=="],
95  ["4","NA=="],
96  ["5","NQ=="],
97  ["6","Ng=="],
98  ["7","Nw=="],
99  ["8","OA=="],
100  ["9","OQ=="],
101  [":","Og=="],
102  [";","Ow=="],
103  ["<","PA=="],
104  ["=","PQ=="],
105  [">","Pg=="],
106  ["?","Pw=="],
107  ["@","QA=="],
108  ["A","QQ=="],
109  ["B","Qg=="],
110  ["C","Qw=="],
111  ["D","RA=="],
112  ["E","RQ=="],
113  ["F","Rg=="],
114  ["G","Rw=="],
115  ["H","SA=="],
116  ["I","SQ=="],
117  ["J","Sg=="],
118  ["K","Sw=="],
119  ["L","TA=="],
120  ["M","TQ=="],
121  ["N","Tg=="],
122  ["O","Tw=="],
123  ["P","UA=="],
124  ["Q","UQ=="],
125  ["R","Ug=="],
126  ["S","Uw=="],
127  ["T","VA=="],
128  ["U","VQ=="],
129  ["V","Vg=="],
130  ["W","Vw=="],
131  ["X","WA=="],
132  ["Y","WQ=="],
133  ["Z","Wg=="],
134  ["[","Ww=="],
135  ["\\","XA=="],
136  ["]","XQ=="],
137  ["^","Xg=="],
138  ["_","Xw=="],
139  ["`","YA=="],
140  ["a","YQ=="],
141  ["b","Yg=="],
142  ["c","Yw=="],
143  ["d","ZA=="],
144  ["e","ZQ=="],
145  ["f","Zg=="],
146  ["g","Zw=="],
147  ["h","aA=="],
148  ["i","aQ=="],
149  ["j","ag=="],
150  ["k","aw=="],
151  ["l","bA=="],
152  ["m","bQ=="],
153  ["n","bg=="],
154  ["o","bw=="],
155  ["p","cA=="],
156  ["q","cQ=="],
157  ["r","cg=="],
158  ["s","cw=="],
159  ["t","dA=="],
160  ["u","dQ=="],
161  ["v","dg=="],
162  ["w","dw=="],
163  ["x","eA=="],
164  ["y","eQ=="],
165  ["z","eg=="],
166  ["{","ew=="],
167  ["|","fA=="],
168  ["}","fQ=="],
169  ["~","fg=="],
170  ["\u007f","fw=="],
171  ["\u0080","woA="],
172  ["\u0081","woE="],
173  ["\u0082","woI="],
174  ["\u0083","woM="],
175  ["\u0084","woQ="],
176  ["\u0085","woU="],
177  ["\u0086","woY="],
178  ["\u0087","woc="],
179  ["\u0088","wog="],
180  ["\u0089","wok="],
181  ["\u008a","woo="],
182  ["\u008b","wos="],
183  ["\u008c","wow="],
184  ["\u008d","wo0="],
185  ["\u008e","wo4="],
186  ["\u008f","wo8="],
187  ["\u0090","wpA="],
188  ["\u0091","wpE="],
189  ["\u0092","wpI="],
190  ["\u0093","wpM="],
191  ["\u0094","wpQ="],
192  ["\u0095","wpU="],
193  ["\u0096","wpY="],
194  ["\u0097","wpc="],
195  ["\u0098","wpg="],
196  ["\u0099","wpk="],
197  ["\u009a","wpo="],
198  ["\u009b","wps="],
199  ["\u009c","wpw="],
200  ["\u009d","wp0="],
201  ["\u009e","wp4="],
202  ["\u009f","wp8="],
203  ["\u00a0","wqA="],
204  ["\u00a1","wqE="],
205  ["\u00a2","wqI="],
206  ["\u00a3","wqM="],
207  ["\u00a4","wqQ="],
208  ["\u00a5","wqU="],
209  ["\u00a6","wqY="],
210  ["\u00a7","wqc="],
211  ["\u00a8","wqg="],
212  ["\u00a9","wqk="],
213  ["\u00aa","wqo="],
214  ["\u00ab","wqs="],
215  ["\u00ac","wqw="],
216  ["\u00ad","wq0="],
217  ["\u00ae","wq4="],
218  ["\u00af","wq8="],
219  ["\u00b0","wrA="],
220  ["\u00b1","wrE="],
221  ["\u00b2","wrI="],
222  ["\u00b3","wrM="],
223  ["\u00b4","wrQ="],
224  ["\u00b5","wrU="],
225  ["\u00b6","wrY="],
226  ["\u00b7","wrc="],
227  ["\u00b8","wrg="],
228  ["\u00b9","wrk="],
229  ["\u00ba","wro="],
230  ["\u00bb","wrs="],
231  ["\u00bc","wrw="],
232  ["\u00bd","wr0="],
233  ["\u00be","wr4="],
234  ["\u00bf","wr8="],
235  ["\u00c0","w4A="],
236  ["\u00c1","w4E="],
237  ["\u00c2","w4I="],
238  ["\u00c3","w4M="],
239  ["\u00c4","w4Q="],
240  ["\u00c5","w4U="],
241  ["\u00c6","w4Y="],
242  ["\u00c7","w4c="],
243  ["\u00c8","w4g="],
244  ["\u00c9","w4k="],
245  ["\u00ca","w4o="],
246  ["\u00cb","w4s="],
247  ["\u00cc","w4w="],
248  ["\u00cd","w40="],
249  ["\u00ce","w44="],
250  ["\u00cf","w48="],
251  ["\u00d0","w5A="],
252  ["\u00d1","w5E="],
253  ["\u00d2","w5I="],
254  ["\u00d3","w5M="],
255  ["\u00d4","w5Q="],
256  ["\u00d5","w5U="],
257  ["\u00d6","w5Y="],
258  ["\u00d7","w5c="],
259  ["\u00d8","w5g="],
260  ["\u00d9","w5k="],
261  ["\u00da","w5o="],
262  ["\u00db","w5s="],
263  ["\u00dc","w5w="],
264  ["\u00dd","w50="],
265  ["\u00de","w54="],
266  ["\u00df","w58="],
267  ["\u00e0","w6A="],
268  ["\u00e1","w6E="],
269  ["\u00e2","w6I="],
270  ["\u00e3","w6M="],
271  ["\u00e4","w6Q="],
272  ["\u00e5","w6U="],
273  ["\u00e6","w6Y="],
274  ["\u00e7","w6c="],
275  ["\u00e8","w6g="],
276  ["\u00e9","w6k="],
277  ["\u00ea","w6o="],
278  ["\u00eb","w6s="],
279  ["\u00ec","w6w="],
280  ["\u00ed","w60="],
281  ["\u00ee","w64="],
282  ["\u00ef","w68="],
283  ["\u00f0","w7A="],
284  ["\u00f1","w7E="],
285  ["\u00f2","w7I="],
286  ["\u00f3","w7M="],
287  ["\u00f4","w7Q="],
288  ["\u00f5","w7U="],
289  ["\u00f6","w7Y="],
290  ["\u00f7","w7c="],
291  ["\u00f8","w7g="],
292  ["\u00f9","w7k="],
293  ["\u00fa","w7o="],
294  ["\u00fb","w7s="],
295  ["\u00fc","w7w="],
296  ["\u00fd","w70="],
297  ["\u00fe","w74="],
298  ["\u00ff","w78="],
299  ["\u0000\u00ff","AMO/"],
300  ["\u00ff\u0000","w78A"],
301  ["\u0000\u0000\u0000","AAAA"],
302  ["",""],
303  ["a","YQ=="],
304  ["aa","YWE="],
305  ["aaa","YWFh"],
306  ["aaa","YWFh"],
307  ["aaa","YWFh"],
308  ["aaa","YWFh"],
309  ["Aladdin:open sesame","QWxhZGRpbjpvcGVuIHNlc2FtZQ=="],
310  ["Multipurpose Internet Mail Extensions: The Base64 Content-Transfer-Encoding is designed to represent sequences of octets in a form that is not humanly readable. ",
311  "TXVsdGlwdXJwb3NlIEludGVybmV0IE1haWwgRXh0ZW5zaW9uczogVGhlIEJhc2U2NCBDb250ZW50\nLVRyYW5zZmVyLUVuY29kaW5nIGlzIGRlc2lnbmVkIHRvIHJlcHJlc2VudCBzZXF1ZW5jZXMgb2Yg\nb2N0ZXRzIGluIGEgZm9ybSB0aGF0IGlzIG5vdCBodW1hbmx5IHJlYWRhYmxlLiA="]
312]
313END_JSON
314
315    decode_tests = json.'compile'( <<'END_JSON' )
316[ ["YWE=","aa"],
317  [" YWE=","aa"],
318  ["Y WE=","aa"],
319  ["YWE= ","aa"],
320  ["Y\nW\r\nE=","aa"],
321  ["YWE=====","aa"],
322  ["YWE","aa"],
323  ["YWFh====","aaa"],
324  ["YQ","a"],
325  ["",""]
326]
327END_JSON
328
329# TODO: These decoding tests seem to cause weird output
330# ["Y",""],
331# ["x==",""],
332
333    .local int count
334    count = 0
335    .local pmc test_iterator, test_case
336    .local string plain, base64, comment, comment_count, enc, esc_plain
337
338    encode_decode_tests = encode_decode_tests()
339    test_iterator = iter encode_decode_tests
340    enc_dec_loop:
341        unless test_iterator goto enc_dec_loop_end
342        test_case   = shift test_iterator
343        plain       = shift test_case
344        base64      = shift test_case
345        comment     = 'encode'
346        comment_count = count
347        $I0 = encoding plain
348        enc = encodingname $I0
349        esc_plain = escape plain
350        comment = concat comment, comment_count
351        comment = concat comment, " "
352        comment = concat comment, enc
353        comment = concat comment, ":\""
354        comment = concat comment, esc_plain
355        comment = concat comment, "\""
356        test_encode( plain, base64, comment )
357        comment     = 'decode'
358        comment_count = count
359        comment = concat comment, comment_count
360        test_decode( plain, base64, comment )
361        inc count
362    goto enc_dec_loop
363    enc_dec_loop_end:
364
365    decode_tests = decode_tests()
366    test_iterator = iter decode_tests
367    dec_loop:
368        unless test_iterator goto dec_loop_end
369        test_case   = shift test_iterator
370        base64      = shift test_case
371        plain       = shift test_case
372        comment     = 'decode'
373        comment_count = count
374        comment = concat comment, comment_count
375        test_decode( plain, base64, comment )
376        inc count
377    goto dec_loop
378    dec_loop_end:
379
380    gh813_base64_utf8()
381
382.end
383
384.sub gh813_base64_utf8
385    .local pmc lives_ok
386    lives_ok = get_hll_global [ 'Test'; 'More' ], 'lives_ok'
387
388    lives_ok(<<'CODE', 'enc_sub("\x{203e}") # Github issue #813')
389.sub foo
390    .local pmc enc_sub
391    enc_sub = get_global [ "MIME"; "Base64" ], 'encode_base64'
392
393    .local string result_encode
394    result_encode = enc_sub(utf8:"\x{203e}")
395.end
396CODE
397
398.end
399
400.sub test_encode
401    .param string plain
402    .param string base64
403    .param string comment
404
405    .local pmc enc_sub
406    enc_sub = get_global [ "MIME"; "Base64" ], 'encode_base64'
407
408    .local pmc is
409    is   = get_hll_global [ 'Test'; 'More' ], 'is'
410
411    .local string result_encode
412    result_encode = enc_sub( plain )
413    is( result_encode, base64, comment )
414.end
415
416
417.sub test_decode
418    .param string plain
419    .param string base64
420    .param string comment
421
422    .include "iglobals.pasm"
423    .local pmc interp
424    interp = getinterp
425    .local pmc config
426    config = interp[.IGLOBALS_CONFIG_HASH]
427    .local int has_icu
428    has_icu = config['has_icu']
429    .local int bigendian
430    bigendian  = config['bigendian']
431
432    .local pmc dec_sub
433    dec_sub = get_global [ "MIME"; "Base64" ], 'decode_base64'
434
435    .local pmc is, skip
436    is   = get_hll_global [ 'Test'; 'More' ], 'is'
437    skip = get_hll_global [ 'Test'; 'More' ], 'skip'
438
439    $S0 = 'AAAA'
440    ne base64, $S0, CONT_TEST
441        ## Note: also fails on solaris little-endian
442        skip(1, '\0\0\0 fails to compare for unknown reasons GH #855')
443        goto END
444        unless bigendian goto CONT_TEST
445            skip(1, 'multi-byte codepoint test in big-endian')
446            goto END
447  CONT_TEST:
448    .local string decode, result_decode
449    .local string enc, enc1
450    $I0 = encoding plain
451    enc = encodingname $I0
452    if $I0 > 2 goto DEC_ENC
453        # ascii, latin1
454        decode = dec_sub( base64 )
455        decode = trans_encoding decode, $I0
456        goto DEC_2
457  DEC_ENC:
458    decode = dec_sub( base64, enc )
459  DEC_2:
460    $I1 = encoding decode
461    enc1 = encodingname $I1
462    comment = concat comment, " "
463    comment = concat comment, enc1
464    comment = concat comment, " <-"
465    comment = concat comment, enc
466
467    .local string plain_norm, result_norm
468    if has_icu goto HAS_ICU
469        is( decode, plain, comment )
470	goto END
471  HAS_ICU:
472    result_norm = compose decode
473    plain_norm  = compose plain
474    is( result_norm, plain_norm, comment )
475  END:
476.end
477
478
479=head1 AUTHOR
480
481Bernhard Schmalhofer <Bernhard Schmalhofer@gmx.de> and Reini Urban.
482
483=cut
484
485# Local Variables:
486#   mode: pir
487#   fill-column: 100
488# End:
489# vim: expandtab shiftwidth=4 ft=pir:
490