Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "unicpriv.h"
6 /*=================================================================================
8 =================================================================================*/
9 typedef int (*uSubGeneratorFunc) (uint16_t in, unsigned char* out);
10 /*=================================================================================
12 =================================================================================*/
14 typedef int (*uGeneratorFunc) (
15 int32_t* state,
16 uint16_t in,
17 unsigned char* out,
18 uint32_t outbuflen,
19 uint32_t* outlen
20 );
22 int uGenerate(
23 uScanClassID scanClass,
24 int32_t* state,
25 uint16_t in,
26 unsigned char* out,
27 uint32_t outbuflen,
28 uint32_t* outlen
29 );
31 #define uSubGenerator(sub,in,out) (* m_subgenerator[sub])((in),(out))
33 int uCheckAndGenAlways1Byte(
34 int32_t* state,
35 uint16_t in,
36 unsigned char* out,
37 uint32_t outbuflen,
38 uint32_t* outlen
39 );
40 int uCheckAndGenAlways2Byte(
41 int32_t* state,
42 uint16_t in,
43 unsigned char* out,
44 uint32_t outbuflen,
45 uint32_t* outlen
46 );
47 int uCheckAndGenAlways2ByteShiftGR(
48 int32_t* state,
49 uint16_t in,
50 unsigned char* out,
51 uint32_t outbuflen,
52 uint32_t* outlen
53 );
54 int uGenerateShift(
55 uShiftOutTable *shift,
56 int32_t* state,
57 uint16_t in,
58 unsigned char* out,
59 uint32_t outbuflen,
60 uint32_t* outlen
61 );
62 int uCheckAndGen2ByteGRPrefix8F(
63 int32_t* state,
64 uint16_t in,
65 unsigned char* out,
66 uint32_t outbuflen,
67 uint32_t* outlen
68 );
69 int uCheckAndGen2ByteGRPrefix8EA2(
70 int32_t* state,
71 uint16_t in,
72 unsigned char* out,
73 uint32_t outbuflen,
74 uint32_t* outlen
75 );
77 int uCheckAndGen2ByteGRPrefix8EA3(
78 int32_t* state,
79 uint16_t in,
80 unsigned char* out,
81 uint32_t outbuflen,
82 uint32_t* outlen
83 );
85 int uCheckAndGen2ByteGRPrefix8EA4(
86 int32_t* state,
87 uint16_t in,
88 unsigned char* out,
89 uint32_t outbuflen,
90 uint32_t* outlen
91 );
93 int uCheckAndGen2ByteGRPrefix8EA5(
94 int32_t* state,
95 uint16_t in,
96 unsigned char* out,
97 uint32_t outbuflen,
98 uint32_t* outlen
99 );
101 int uCheckAndGen2ByteGRPrefix8EA6(
102 int32_t* state,
103 uint16_t in,
104 unsigned char* out,
105 uint32_t outbuflen,
106 uint32_t* outlen
107 );
109 int uCheckAndGen2ByteGRPrefix8EA7(
110 int32_t* state,
111 uint16_t in,
112 unsigned char* out,
113 uint32_t outbuflen,
114 uint32_t* outlen
115 );
116 int uCnGAlways8BytesDecomposedHangul(
117 int32_t* state,
118 uint16_t in,
119 unsigned char* out,
120 uint32_t outbuflen,
121 uint32_t* outlen
122 );
124 int uCheckAndGenJohabHangul(
125 int32_t* state,
126 uint16_t in,
127 unsigned char* out,
128 uint32_t outbuflen,
129 uint32_t* outlen
130 );
132 int uCheckAndGenJohabSymbol(
133 int32_t* state,
134 uint16_t in,
135 unsigned char* out,
136 uint32_t outbuflen,
137 uint32_t* outlen
138 );
141 int uCheckAndGen4BytesGB18030(
142 int32_t* state,
143 uint16_t in,
144 unsigned char* out,
145 uint32_t outbuflen,
146 uint32_t* outlen
147 );
149 int uGenAlways2Byte(
150 uint16_t in,
151 unsigned char* out
152 );
153 int uGenAlways2ByteShiftGR(
154 uint16_t in,
155 unsigned char* out
156 );
157 int uGenAlways1Byte(
158 uint16_t in,
159 unsigned char* out
160 );
161 int uGenAlways1BytePrefix8E(
162 uint16_t in,
163 unsigned char* out
164 );
165 /*=================================================================================
167 =================================================================================*/
168 const uGeneratorFunc m_generator[uNumOfCharsetType] =
169 {
170 uCheckAndGenAlways1Byte,
171 uCheckAndGenAlways2Byte,
172 uCheckAndGenAlways2ByteShiftGR,
173 uCheckAndGen2ByteGRPrefix8F,
174 uCheckAndGen2ByteGRPrefix8EA2,
175 uCheckAndGen2ByteGRPrefix8EA3,
176 uCheckAndGen2ByteGRPrefix8EA4,
177 uCheckAndGen2ByteGRPrefix8EA5,
178 uCheckAndGen2ByteGRPrefix8EA6,
179 uCheckAndGen2ByteGRPrefix8EA7,
180 uCnGAlways8BytesDecomposedHangul,
181 uCheckAndGenJohabHangul,
182 uCheckAndGenJohabSymbol,
183 uCheckAndGen4BytesGB18030,
184 uCheckAndGenAlways2Byte /* place-holder for GR128 */
185 };
187 /*=================================================================================
189 =================================================================================*/
191 const uSubGeneratorFunc m_subgenerator[uNumOfCharType] =
192 {
193 uGenAlways1Byte,
194 uGenAlways2Byte,
195 uGenAlways2ByteShiftGR,
196 uGenAlways1BytePrefix8E
197 };
198 /*=================================================================================
200 =================================================================================*/
201 int uGenerate(
202 uScanClassID scanClass,
203 int32_t* state,
204 uint16_t in,
205 unsigned char* out,
206 uint32_t outbuflen,
207 uint32_t* outlen
208 )
209 {
210 return (* m_generator[scanClass]) (state,in,out,outbuflen,outlen);
211 }
212 /*=================================================================================
214 =================================================================================*/
215 int uGenAlways1Byte(
216 uint16_t in,
217 unsigned char* out
218 )
219 {
220 out[0] = (unsigned char)in;
221 return 1;
222 }
224 /*=================================================================================
226 =================================================================================*/
227 int uGenAlways2Byte(
228 uint16_t in,
229 unsigned char* out
230 )
231 {
232 out[0] = (unsigned char)((in >> 8) & 0xff);
233 out[1] = (unsigned char)(in & 0xff);
234 return 1;
235 }
236 /*=================================================================================
238 =================================================================================*/
239 int uGenAlways2ByteShiftGR(
240 uint16_t in,
241 unsigned char* out
242 )
243 {
244 out[0] = (unsigned char)(((in >> 8) & 0xff) | 0x80);
245 out[1] = (unsigned char)((in & 0xff) | 0x80);
246 return 1;
247 }
248 /*=================================================================================
250 =================================================================================*/
251 int uGenAlways1BytePrefix8E(
252 uint16_t in,
253 unsigned char* out
254 )
255 {
256 out[0] = 0x8E;
257 out[1] = (unsigned char)(in & 0xff);
258 return 1;
259 }
260 /*=================================================================================
262 =================================================================================*/
263 int uCheckAndGenAlways1Byte(
264 int32_t* state,
265 uint16_t in,
266 unsigned char* out,
267 uint32_t outbuflen,
268 uint32_t* outlen
269 )
270 {
271 /* Don't check inlen. The caller should ensure it is larger than 0 */
272 /* Oops, I don't agree. Code changed to check every time. [CATA] */
273 if(outbuflen < 1)
274 return 0;
275 else
276 {
277 *outlen = 1;
278 out[0] = in & 0xff;
279 return 1;
280 }
281 }
283 /*=================================================================================
285 =================================================================================*/
286 int uCheckAndGenAlways2Byte(
287 int32_t* state,
288 uint16_t in,
289 unsigned char* out,
290 uint32_t outbuflen,
291 uint32_t* outlen
292 )
293 {
294 if(outbuflen < 2)
295 return 0;
296 else
297 {
298 *outlen = 2;
299 out[0] = ((in >> 8 ) & 0xff);
300 out[1] = in & 0xff;
301 return 1;
302 }
303 }
304 /*=================================================================================
306 =================================================================================*/
307 int uCheckAndGenAlways2ByteShiftGR(
308 int32_t* state,
309 uint16_t in,
310 unsigned char* out,
311 uint32_t outbuflen,
312 uint32_t* outlen
313 )
314 {
315 if(outbuflen < 2)
316 return 0;
317 else
318 {
319 *outlen = 2;
320 out[0] = ((in >> 8 ) & 0xff) | 0x80;
321 out[1] = (in & 0xff) | 0x80;
322 return 1;
323 }
324 }
325 /*=================================================================================
327 =================================================================================*/
328 int uGenerateShift(
329 uShiftOutTable *shift,
330 int32_t* state,
331 uint16_t in,
332 unsigned char* out,
333 uint32_t outbuflen,
334 uint32_t* outlen
335 )
336 {
337 int16_t i;
338 const uShiftOutCell* cell = &(shift->shiftcell[0]);
339 int16_t itemnum = shift->numOfItem;
340 unsigned char inH, inL;
341 inH = (in >> 8) & 0xff;
342 inL = (in & 0xff );
343 for(i=0;i<itemnum;i++)
344 {
345 if( ( inL >= cell[i].shiftout_MinLB) &&
346 ( inL <= cell[i].shiftout_MaxLB) &&
347 ( inH >= cell[i].shiftout_MinHB) &&
348 ( inH <= cell[i].shiftout_MaxHB) )
349 {
350 if(outbuflen < cell[i].reserveLen)
351 {
352 return 0;
353 }
354 else
355 {
356 *outlen = cell[i].reserveLen;
357 return (uSubGenerator(cell[i].classID,in,out));
358 }
359 }
360 }
361 return 0;
362 }
363 /*=================================================================================
365 =================================================================================*/
366 int uCheckAndGen2ByteGRPrefix8F(int32_t* state,
367 uint16_t in,
368 unsigned char* out,
369 uint32_t outbuflen,
370 uint32_t* outlen
371 )
372 {
373 if(outbuflen < 3)
374 return 0;
375 else
376 {
377 *outlen = 3;
378 out[0] = 0x8F;
379 out[1] = ((in >> 8 ) & 0xff) | 0x80;
380 out[2] = (in & 0xff) | 0x80;
381 return 1;
382 }
383 }
384 /*=================================================================================
386 =================================================================================*/
387 int uCheckAndGen2ByteGRPrefix8EA2(int32_t* state,
388 uint16_t in,
389 unsigned char* out,
390 uint32_t outbuflen,
391 uint32_t* outlen
392 )
393 {
394 if(outbuflen < 4)
395 return 0;
396 else
397 {
398 *outlen = 4;
399 out[0] = 0x8E;
400 out[1] = 0xA2;
401 out[2] = ((in >> 8 ) & 0xff) | 0x80;
402 out[3] = (in & 0xff) | 0x80;
403 return 1;
404 }
405 }
408 /*=================================================================================
410 =================================================================================*/
411 int uCheckAndGen2ByteGRPrefix8EA3(int32_t* state,
412 uint16_t in,
413 unsigned char* out,
414 uint32_t outbuflen,
415 uint32_t* outlen
416 )
417 {
418 if(outbuflen < 4)
419 return 0;
420 else
421 {
422 *outlen = 4;
423 out[0] = 0x8E;
424 out[1] = 0xA3;
425 out[2] = ((in >> 8 ) & 0xff) | 0x80;
426 out[3] = (in & 0xff) | 0x80;
427 return 1;
428 }
429 }
430 /*=================================================================================
432 =================================================================================*/
433 int uCheckAndGen2ByteGRPrefix8EA4(int32_t* state,
434 uint16_t in,
435 unsigned char* out,
436 uint32_t outbuflen,
437 uint32_t* outlen
438 )
439 {
440 if(outbuflen < 4)
441 return 0;
442 else
443 {
444 *outlen = 4;
445 out[0] = 0x8E;
446 out[1] = 0xA4;
447 out[2] = ((in >> 8 ) & 0xff) | 0x80;
448 out[3] = (in & 0xff) | 0x80;
449 return 1;
450 }
451 }
452 /*=================================================================================
454 =================================================================================*/
455 int uCheckAndGen2ByteGRPrefix8EA5(int32_t* state,
456 uint16_t in,
457 unsigned char* out,
458 uint32_t outbuflen,
459 uint32_t* outlen
460 )
461 {
462 if(outbuflen < 4)
463 return 0;
464 else
465 {
466 *outlen = 4;
467 out[0] = 0x8E;
468 out[1] = 0xA5;
469 out[2] = ((in >> 8 ) & 0xff) | 0x80;
470 out[3] = (in & 0xff) | 0x80;
471 return 1;
472 }
473 }
474 /*=================================================================================
476 =================================================================================*/
477 int uCheckAndGen2ByteGRPrefix8EA6(int32_t* state,
478 uint16_t in,
479 unsigned char* out,
480 uint32_t outbuflen,
481 uint32_t* outlen
482 )
483 {
484 if(outbuflen < 4)
485 return 0;
486 else
487 {
488 *outlen = 4;
489 out[0] = 0x8E;
490 out[1] = 0xA6;
491 out[2] = ((in >> 8 ) & 0xff) | 0x80;
492 out[3] = (in & 0xff) | 0x80;
493 return 1;
494 }
495 }
496 /*=================================================================================
498 =================================================================================*/
499 int uCheckAndGen2ByteGRPrefix8EA7(int32_t* state,
500 uint16_t in,
501 unsigned char* out,
502 uint32_t outbuflen,
503 uint32_t* outlen
504 )
505 {
506 if(outbuflen < 4)
507 return 0;
508 else
509 {
510 *outlen = 4;
511 out[0] = 0x8E;
512 out[1] = 0xA7;
513 out[2] = ((in >> 8 ) & 0xff) | 0x80;
514 out[3] = (in & 0xff) | 0x80;
515 return 1;
516 }
517 }
518 /*=================================================================================
520 =================================================================================*/
521 #define SBase 0xAC00
522 #define LCount 19
523 #define VCount 21
524 #define TCount 28
525 #define NCount (VCount * TCount)
526 /*=================================================================================
528 =================================================================================*/
529 int uCnGAlways8BytesDecomposedHangul(
530 int32_t* state,
531 uint16_t in,
532 unsigned char* out,
533 uint32_t outbuflen,
534 uint32_t* outlen
535 )
536 {
537 static const uint8_t lMap[LCount] = {
538 0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xa9, 0xb1, 0xb2, 0xb3, 0xb5,
539 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe
540 };
542 static const uint8_t tMap[TCount] = {
543 0xd4, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa9, 0xaa,
544 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb4, 0xb5,
545 0xb6, 0xb7, 0xb8, 0xba, 0xbb, 0xbc, 0xbd, 0xbe
546 };
548 uint16_t SIndex, LIndex, VIndex, TIndex;
550 if(outbuflen < 8)
551 return 0;
553 /* the following line are copy from Unicode 2.0 page 3-13 */
554 /* item 1 of Hangul Syllabel Decomposition */
555 SIndex = in - SBase;
557 /* the following lines are copy from Unicode 2.0 page 3-14 */
558 /* item 2 of Hangul Syllabel Decomposition w/ modification */
559 LIndex = SIndex / NCount;
560 VIndex = (SIndex % NCount) / TCount;
561 TIndex = SIndex % TCount;
563 /*
564 * A Hangul syllable not enumerated in KS X 1001 is represented
565 * by a sequence of 8 bytes beginning with Hangul-filler
566 * (0xA4D4 in EUC-KR and 0x2454 in ISO-2022-KR) followed by three
567 * Jamos (2 bytes each the first of which is 0xA4 in EUC-KR) making
568 * up the syllable. ref. KS X 1001:1998 Annex 3
569 */
570 *outlen = 8;
571 out[0] = out[2] = out[4] = out[6] = 0xa4;
572 out[1] = 0xd4;
573 out[3] = lMap[LIndex] ;
574 out[5] = (VIndex + 0xbf);
575 out[7] = tMap[TIndex];
577 return 1;
578 }
580 int uCheckAndGenJohabHangul(
581 int32_t* state,
582 uint16_t in,
583 unsigned char* out,
584 uint32_t outbuflen,
585 uint32_t* outlen
586 )
587 {
588 if(outbuflen < 2)
589 return 0;
590 else
591 {
592 /*
593 See Table 4-45 (page 183) of CJKV Information Processing
594 for detail explanation of the following table.
595 */
596 /*
597 static const uint8_t lMap[LCount] = {
598 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
599 };
600 Therefore lMap[i] == i+2;
601 */
603 static const uint8_t vMap[VCount] = {
604 /* no 0,1,2 */
605 3,4,5,6,7, /* no 8,9 */
606 10,11,12,13,14,15, /* no 16,17 */
607 18,19,20,21,22,23, /* no 24,25 */
608 26,27,28,29
609 };
610 static const uint8_t tMap[TCount] = {
611 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17, /* no 18 */
612 19,20,21,22,23,24,25,26,27,28,29
613 };
614 uint16_t SIndex, LIndex, VIndex, TIndex, ch;
615 /* the following line are copy from Unicode 2.0 page 3-13 */
616 /* item 1 of Hangul Syllabel Decomposition */
617 SIndex = in - SBase;
619 /* the following lines are copy from Unicode 2.0 page 3-14 */
620 /* item 2 of Hangul Syllabel Decomposition w/ modification */
621 LIndex = SIndex / NCount;
622 VIndex = (SIndex % NCount) / TCount;
623 TIndex = SIndex % TCount;
625 *outlen = 2;
626 ch = 0x8000 |
627 ((LIndex+2)<<10) |
628 (vMap[VIndex]<<5)|
629 tMap[TIndex];
630 out[0] = (ch >> 8);
631 out[1] = ch & 0x00FF;
632 #if 0
633 printf("Johab Hangul %x %x in=%x L=%d V=%d T=%d\n", out[0], out[1], in, LIndex, VIndex, TIndex);
634 #endif
635 return 1;
636 }
637 }
638 int uCheckAndGenJohabSymbol(
639 int32_t* state,
640 uint16_t in,
641 unsigned char* out,
642 uint32_t outbuflen,
643 uint32_t* outlen
644 )
645 {
646 if(outbuflen < 2)
647 return 0;
648 else
649 {
650 /* The following code are based on the Perl code listed under
651 * "ISO-2022-KR or EUC-KR to Johab Conversion" (page 1013)
652 * in the book "CJKV Information Processing" by
653 * Ken Lunde <lunde@adobe.com>
654 *
655 * sub convert2johab($) { # Convert ISO-2022-KR or EUC-KR to Johab
656 * my @euc = unpack("C*", $_[0]);
657 * my ($fe_off, $hi_off, $lo_off) = (0,0,1);
658 * my @out = ();
659 * while(($hi, $lo) = splice(@euc, 0, 2)) {
660 * $hi &= 127; $lo &= 127;
661 * $fe_off = 21 if $hi == 73;
662 * $fe_off = 34 if $hi == 126;
663 * ($hi_off, $lo_off) = ($lo_off, $hi_off) if ($hi <74 or $hi >125);
664 * push(@out, ((($hi+$hi_off) >> 1)+ ($hi <74 ? 200:187)- $fe_off),
665 * $lo + ((($hi+$lo_off) & 1) ? ($lo > 110 ? 34:16):128));
666 * }
667 * return pack("C*", @out);
668 */
670 unsigned char fe_off = 0;
671 unsigned char hi_off = 0;
672 unsigned char lo_off = 1;
673 unsigned char hi = (in >> 8) & 0x7F;
674 unsigned char lo = in & 0x7F;
675 if(73 == hi)
676 fe_off = 21;
677 if(126 == hi)
678 fe_off = 34;
679 if( (hi < 74) || ( hi > 125) )
680 {
681 hi_off = 1;
682 lo_off = 0;
683 }
684 *outlen = 2;
685 out[0] = ((hi+hi_off) >> 1) + ((hi<74) ? 200 : 187 ) - fe_off;
686 out[1] = lo + (((hi+lo_off) & 1) ? ((lo > 110) ? 34 : 16) :
687 128);
688 #if 0
689 printf("Johab Symbol %x %x in=%x\n", out[0], out[1], in);
690 #endif
691 return 1;
692 }
693 }
694 int uCheckAndGen4BytesGB18030(
695 int32_t* state,
696 uint16_t in,
697 unsigned char* out,
698 uint32_t outbuflen,
699 uint32_t* outlen
700 )
701 {
702 if(outbuflen < 4)
703 return 0;
704 out[0] = (in / (10*126*10)) + 0x81;
705 in %= (10*126*10);
706 out[1] = (in / (10*126)) + 0x30;
707 in %= (10*126);
708 out[2] = (in / (10)) + 0x81;
709 out[3] = (in % 10) + 0x30;
710 *outlen = 4;
711 return 1;
712 }