2 #include "oscam-string.h"
4 /* This function encapsulates malloc. It automatically adds an error message
5 to the log if it failed and calls cs_exit(quiterror) if quiterror > -1.
6 result will be automatically filled with the new memory position or NULL
8 bool cs_malloc(void *result
, size_t size
)
14 fprintf(stderr
, "%s: ERROR: Can't allocate %zu bytes!", __func__
, size
);
18 memset(*tmp
, 0, size
);
23 /* This function encapsulates realloc. It automatically adds an error message
24 to the log if it failed and calls cs_exit(quiterror) if quiterror > -1.
25 result will be automatically filled with the new memory position or NULL
26 on failure. If a failure occured, the existing memory in result will
28 bool cs_realloc(void *result
, size_t size
)
30 void **tmp
= result
, **tmp2
= result
;
31 *tmp
= realloc(*tmp
, size
);
34 fprintf(stderr
, "%s: ERROR: Can't allocate %zu bytes!", __func__
, size
);
40 /* Allocates a new empty string and copies str into it. You need to free() the result. */
41 char *cs_strdup(const char *str
)
46 if(cs_malloc(&newstr
, strlen(str
) + 1))
48 strncpy(newstr
, str
, strlen(str
));
54 /* Ordinary strncpy does not terminate the string if the source is exactly
55 as long or longer as the specified size. This can raise security issues.
56 This function is a replacement which makes sure that a \0 is always added.
57 num should be the real size of char array (do not subtract -1). */
58 void cs_strncpy(char *destination
, const char *source
, size_t num
)
62 destination
[0] = '\0';
65 uint32_t l
, size
= strlen(source
);
70 memcpy(destination
, source
, l
);
71 destination
[l
] = '\0';
74 /* Converts the string txt to it's lower case representation. */
75 char *strtolower(char *txt
)
80 if(isupper((uchar
)*p
))
81 { *p
= tolower((uchar
) * p
); }
86 /* Converts the string txt to it's upper case representation. */
87 char *strtoupper(char *txt
)
92 if(islower((uchar
)*p
))
93 { *p
= toupper((uchar
) * p
); }
104 for(p1
= p2
= txt
; (*p1
== ' ') || (*p1
== '\t') || (*p1
== '\n') || (*p1
== '\r'); p1
++)
113 for(p1
= txt
+ l
- 1; l
> 0 && ((*p1
== ' ') || (*p1
== '\t') || (*p1
== '\n') || (*p1
== '\r')); *p1
-- = '\0', l
--)
119 char *trim2(char *txt
)
123 for(i
=n
=0; i
<(int32_t)strlen(txt
); i
++)
125 if(txt
[i
] == ' ' || txt
[i
] == '\t') continue;
126 if(txt
[i
] == '#') {break;}
135 char *remove_white_chars(char *txt
)
138 char *p1
= txt
, *p2
= txt
;
144 if((' ' != *p1
) && ('\t' != *p1
) &&
145 ('\n' != *p1
) && ('\r' != *p1
))
156 bool streq(const char *s1
, const char *s2
)
158 if(!s1
&& s2
) { return 0; }
159 if(s1
&& !s2
) { return 0; }
160 if(!s1
&& !s2
) { return 1; }
161 return strcmp(s1
, s2
) == 0;
164 char *cs_hexdump(int32_t m
, const uchar
*buf
, int32_t n
, char *target
, int32_t len
)
170 { n
= (len
/ m
) - 1; }
173 snprintf(target
+ (m
* i
), len
- (m
* i
), "%02X%s", *buf
++, m
> 2 ? " " : "");
179 int32_t gethexval(char c
)
181 if(c
>= '0' && c
<= '9') { return c
- '0'; }
182 if(c
>= 'A' && c
<= 'F') { return c
- 'A' + 10; }
183 if(c
>= 'a' && c
<= 'f') { return c
- 'a' + 10; }
187 int32_t cs_atob(uchar
*buf
, char *asc
, int32_t n
)
190 for(i
= 0; i
< n
; i
++)
192 rc
= (gethexval(asc
[i
<< 1]) << 4) | gethexval(asc
[(i
<< 1) + 1]);
200 uint32_t cs_atoi(char *asc
, int32_t l
, int32_t val_on_err
)
204 for(i
= ((l
- 1) << 1), errno
= 0; i
>= 0 && n
< 4; i
-= 2)
206 int32_t b
= (gethexval(asc
[i
]) << 4) | gethexval(asc
[i
+ 1]);
210 rc
= val_on_err
? 0xFFFFFFFF : 0;
219 int32_t byte_atob(char *asc
)
222 if(strlen(trim(asc
)) != 2)
228 rc
= (gethexval(asc
[0]) << 4) | gethexval(asc
[1]);
235 int32_t word_atob(char *asc
)
238 if(strlen(trim(asc
)) != 4)
244 rc
= gethexval(asc
[0]) << 12 | gethexval(asc
[1]) << 8 |
245 gethexval(asc
[2]) << 4 | gethexval(asc
[3]);
254 * converts an 1-6 digit asc hexstring
256 int32_t dyn_word_atob(char *asc
)
259 int32_t i
, len
= strlen(trim(asc
));
260 if(len
<= 6 && len
> 0)
262 for(i
= 0, rc
= 0; i
< len
; i
++)
264 rc
= rc
<< 4 | gethexval(asc
[i
]);
272 int32_t key_atob_l(char *asc
, uchar
*bin
, int32_t l
)
274 int32_t i
, n1
, n2
, rc
;
275 for(i
= rc
= 0; i
< l
; i
+= 2)
277 if((n1
= gethexval(asc
[i
])) < 0) { rc
= -1; }
278 if((n2
= gethexval(asc
[i
+ 1])) < 0) { rc
= -1; }
279 bin
[i
>> 1] = (n1
<< 4) + (n2
& 0xff);
284 uint32_t b2i(int32_t n
, const uchar
*b
)
289 return (b
[0] << 8) | b
[1];
291 return (b
[0] << 16) | (b
[1] << 8) | b
[2];
293 return ((b
[0] << 24) | (b
[1] << 16) | (b
[2] << 8) | b
[3]) & 0xffffffffL
;
295 cs_log("Error in b2i, n=%i", n
);
300 uint64_t b2ll(int32_t n
, uchar
*b
)
304 for(i
= 0; i
< n
; k
+= b
[i
++])
309 uchar
*i2b_buf(int32_t n
, uint32_t i
, uchar
*b
)
314 b
[0] = (i
>> 8) & 0xff;
318 b
[0] = (i
>> 16) & 0xff;
319 b
[1] = (i
>> 8) & 0xff;
322 b
[0] = (i
>> 24) & 0xff;
323 b
[1] = (i
>> 16) & 0xff;
324 b
[2] = (i
>> 8) & 0xff;
331 void ull2b_buf(uint64_t i
, uchar
*b
)
333 b
[0] = (i
>> 56) & 0xff;
334 b
[1] = (i
>> 48) & 0xff;
335 b
[2] = (i
>> 40) & 0xff;
336 b
[3] = (i
>> 32) & 0xff;
337 b
[4] = (i
>> 24) & 0xff;
338 b
[5] = (i
>> 16) & 0xff;
339 b
[6] = (i
>> 8) & 0xff;
343 uint32_t a2i(char *asc
, int32_t bytes
)
347 for(rc
= i
= 0, n
= strlen(trim(asc
)) - 1; i
< abs(bytes
) << 1; n
--, i
++)
352 if((rcl
= gethexval(asc
[n
])) < 0)
357 rc
|= rcl
<< (i
<< 2);
362 { rc
|= 0xf << (i
<< 2); }
369 int32_t boundary(int32_t exp
, int32_t n
)
371 return (((n
- 1) >> exp
) + 1) << exp
;
374 /* Checks whether an array has at least one non-zero byte.
375 length specifies the maximum length to check for. */
376 int32_t array_has_nonzero_byte(uchar
*value
, int32_t length
)
382 for(i
= 0; i
< length
; i
++)
392 #define RAND_POOL_SIZE 64
394 // The last bytes are used to init random seed
395 static uint8_t rand_pool
[RAND_POOL_SIZE
+ sizeof(uint32_t)];
397 void get_random_bytes_init(void)
400 int fd
= open("/dev/urandom", O_RDONLY
);
403 fd
= open("/dev/random", O_RDONLY
);
407 if(read(fd
, rand_pool
, RAND_POOL_SIZE
+ sizeof(uint32_t)) > -1)
409 uint32_t pool_seed
= b2i(4, rand_pool
+ RAND_POOL_SIZE
);
415 void get_random_bytes(uint8_t *dst
, uint32_t dst_len
)
417 static uint32_t rand_pool_pos
; // *MUST* be static
419 for(i
= 0; i
< dst_len
; i
++)
421 rand_pool_pos
++; // Races are welcome...
422 dst
[i
] = rand() ^ rand_pool
[rand_pool_pos
% RAND_POOL_SIZE
];
426 static uint32_t crc_table
[256] =
428 0x00000000L
, 0x77073096L
, 0xee0e612cL
, 0x990951baL
, 0x076dc419L
,
429 0x706af48fL
, 0xe963a535L
, 0x9e6495a3L
, 0x0edb8832L
, 0x79dcb8a4L
,
430 0xe0d5e91eL
, 0x97d2d988L
, 0x09b64c2bL
, 0x7eb17cbdL
, 0xe7b82d07L
,
431 0x90bf1d91L
, 0x1db71064L
, 0x6ab020f2L
, 0xf3b97148L
, 0x84be41deL
,
432 0x1adad47dL
, 0x6ddde4ebL
, 0xf4d4b551L
, 0x83d385c7L
, 0x136c9856L
,
433 0x646ba8c0L
, 0xfd62f97aL
, 0x8a65c9ecL
, 0x14015c4fL
, 0x63066cd9L
,
434 0xfa0f3d63L
, 0x8d080df5L
, 0x3b6e20c8L
, 0x4c69105eL
, 0xd56041e4L
,
435 0xa2677172L
, 0x3c03e4d1L
, 0x4b04d447L
, 0xd20d85fdL
, 0xa50ab56bL
,
436 0x35b5a8faL
, 0x42b2986cL
, 0xdbbbc9d6L
, 0xacbcf940L
, 0x32d86ce3L
,
437 0x45df5c75L
, 0xdcd60dcfL
, 0xabd13d59L
, 0x26d930acL
, 0x51de003aL
,
438 0xc8d75180L
, 0xbfd06116L
, 0x21b4f4b5L
, 0x56b3c423L
, 0xcfba9599L
,
439 0xb8bda50fL
, 0x2802b89eL
, 0x5f058808L
, 0xc60cd9b2L
, 0xb10be924L
,
440 0x2f6f7c87L
, 0x58684c11L
, 0xc1611dabL
, 0xb6662d3dL
, 0x76dc4190L
,
441 0x01db7106L
, 0x98d220bcL
, 0xefd5102aL
, 0x71b18589L
, 0x06b6b51fL
,
442 0x9fbfe4a5L
, 0xe8b8d433L
, 0x7807c9a2L
, 0x0f00f934L
, 0x9609a88eL
,
443 0xe10e9818L
, 0x7f6a0dbbL
, 0x086d3d2dL
, 0x91646c97L
, 0xe6635c01L
,
444 0x6b6b51f4L
, 0x1c6c6162L
, 0x856530d8L
, 0xf262004eL
, 0x6c0695edL
,
445 0x1b01a57bL
, 0x8208f4c1L
, 0xf50fc457L
, 0x65b0d9c6L
, 0x12b7e950L
,
446 0x8bbeb8eaL
, 0xfcb9887cL
, 0x62dd1ddfL
, 0x15da2d49L
, 0x8cd37cf3L
,
447 0xfbd44c65L
, 0x4db26158L
, 0x3ab551ceL
, 0xa3bc0074L
, 0xd4bb30e2L
,
448 0x4adfa541L
, 0x3dd895d7L
, 0xa4d1c46dL
, 0xd3d6f4fbL
, 0x4369e96aL
,
449 0x346ed9fcL
, 0xad678846L
, 0xda60b8d0L
, 0x44042d73L
, 0x33031de5L
,
450 0xaa0a4c5fL
, 0xdd0d7cc9L
, 0x5005713cL
, 0x270241aaL
, 0xbe0b1010L
,
451 0xc90c2086L
, 0x5768b525L
, 0x206f85b3L
, 0xb966d409L
, 0xce61e49fL
,
452 0x5edef90eL
, 0x29d9c998L
, 0xb0d09822L
, 0xc7d7a8b4L
, 0x59b33d17L
,
453 0x2eb40d81L
, 0xb7bd5c3bL
, 0xc0ba6cadL
, 0xedb88320L
, 0x9abfb3b6L
,
454 0x03b6e20cL
, 0x74b1d29aL
, 0xead54739L
, 0x9dd277afL
, 0x04db2615L
,
455 0x73dc1683L
, 0xe3630b12L
, 0x94643b84L
, 0x0d6d6a3eL
, 0x7a6a5aa8L
,
456 0xe40ecf0bL
, 0x9309ff9dL
, 0x0a00ae27L
, 0x7d079eb1L
, 0xf00f9344L
,
457 0x8708a3d2L
, 0x1e01f268L
, 0x6906c2feL
, 0xf762575dL
, 0x806567cbL
,
458 0x196c3671L
, 0x6e6b06e7L
, 0xfed41b76L
, 0x89d32be0L
, 0x10da7a5aL
,
459 0x67dd4accL
, 0xf9b9df6fL
, 0x8ebeeff9L
, 0x17b7be43L
, 0x60b08ed5L
,
460 0xd6d6a3e8L
, 0xa1d1937eL
, 0x38d8c2c4L
, 0x4fdff252L
, 0xd1bb67f1L
,
461 0xa6bc5767L
, 0x3fb506ddL
, 0x48b2364bL
, 0xd80d2bdaL
, 0xaf0a1b4cL
,
462 0x36034af6L
, 0x41047a60L
, 0xdf60efc3L
, 0xa867df55L
, 0x316e8eefL
,
463 0x4669be79L
, 0xcb61b38cL
, 0xbc66831aL
, 0x256fd2a0L
, 0x5268e236L
,
464 0xcc0c7795L
, 0xbb0b4703L
, 0x220216b9L
, 0x5505262fL
, 0xc5ba3bbeL
,
465 0xb2bd0b28L
, 0x2bb45a92L
, 0x5cb36a04L
, 0xc2d7ffa7L
, 0xb5d0cf31L
,
466 0x2cd99e8bL
, 0x5bdeae1dL
, 0x9b64c2b0L
, 0xec63f226L
, 0x756aa39cL
,
467 0x026d930aL
, 0x9c0906a9L
, 0xeb0e363fL
, 0x72076785L
, 0x05005713L
,
468 0x95bf4a82L
, 0xe2b87a14L
, 0x7bb12baeL
, 0x0cb61b38L
, 0x92d28e9bL
,
469 0xe5d5be0dL
, 0x7cdcefb7L
, 0x0bdbdf21L
, 0x86d3d2d4L
, 0xf1d4e242L
,
470 0x68ddb3f8L
, 0x1fda836eL
, 0x81be16cdL
, 0xf6b9265bL
, 0x6fb077e1L
,
471 0x18b74777L
, 0x88085ae6L
, 0xff0f6a70L
, 0x66063bcaL
, 0x11010b5cL
,
472 0x8f659effL
, 0xf862ae69L
, 0x616bffd3L
, 0x166ccf45L
, 0xa00ae278L
,
473 0xd70dd2eeL
, 0x4e048354L
, 0x3903b3c2L
, 0xa7672661L
, 0xd06016f7L
,
474 0x4969474dL
, 0x3e6e77dbL
, 0xaed16a4aL
, 0xd9d65adcL
, 0x40df0b66L
,
475 0x37d83bf0L
, 0xa9bcae53L
, 0xdebb9ec5L
, 0x47b2cf7fL
, 0x30b5ffe9L
,
476 0xbdbdf21cL
, 0xcabac28aL
, 0x53b39330L
, 0x24b4a3a6L
, 0xbad03605L
,
477 0xcdd70693L
, 0x54de5729L
, 0x23d967bfL
, 0xb3667a2eL
, 0xc4614ab8L
,
478 0x5d681b02L
, 0x2a6f2b94L
, 0xb40bbe37L
, 0xc30c8ea1L
, 0x5a05df1bL
,
483 * crc32 -- compute the CRC-32 of a data stream
484 * Copyright (C) 1995-1996 Mark Adler
485 * For conditions of distribution and use, see copyright notice in zlib.h
487 #define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
488 #define DO2(buf) DO1(buf); DO1(buf);
489 #define DO4(buf) DO2(buf); DO2(buf);
490 #define DO8(buf) DO4(buf); DO4(buf);
492 uint32_t crc32(uint32_t crc
, const uint8_t *buf
, uint32_t len
)
496 crc
= crc
^ 0xffffffffL
;
510 return crc
^ 0xffffffffL
;
513 static uint16_t ccitt_crc_table
[256] =
515 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5,
516 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b,
517 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
518 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
519 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c,
520 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
521 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b,
522 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
523 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6,
524 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
525 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5,
526 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
527 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969,
528 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96,
529 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
530 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
531 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03,
532 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
533 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6,
534 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
535 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
536 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb,
537 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1,
538 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
539 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c,
540 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2,
541 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
542 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
543 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447,
544 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
545 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2,
546 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
547 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
548 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827,
549 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c,
550 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
551 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0,
552 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d,
553 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
554 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
555 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba,
556 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
557 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
560 uint16_t ccitt_crc(uint8_t *data
, size_t length
, uint16_t seed
, uint16_t final
)
566 for (count
= 0; count
< length
; ++count
)
568 temp
= (*data
++ ^ (crc
>> 8)) & 0xff;
569 crc
= ccitt_crc_table
[temp
] ^ (crc
<< 8);
571 return (uint16_t)(crc
^ final
);
574 // https://en.wikipedia.org/wiki/Jenkins_hash_function
575 uint32_t jhash(const char *key
, size_t len
)
578 for(hash
= i
= 0; i
< len
; i
++)
581 hash
+= (hash
<< 10);
585 hash
^= (hash
>> 11);
586 hash
+= (hash
<< 15);
590 /* Converts a char to it's hex representation. See char_to_hex on how to use it. */
591 char to_hex(char code
)
593 static const char hex
[] = "0123456789abcdef";
594 return hex
[(int)code
& 15];
597 /* Converts a char array to a char array with hex values (needed for example for md5).
598 Note that result needs to be at least (p_array_len * 2) + 1 large. */
599 void char_to_hex(const unsigned char *p_array
, uint32_t p_array_len
, unsigned char *result
)
601 result
[p_array_len
* 2] = '\0';
602 const unsigned char *p_end
= p_array
+ p_array_len
;
604 const unsigned char *p
;
605 for(p
= p_array
; p
!= p_end
; p
++, pos
+= 2)
607 result
[pos
] = to_hex(*p
>> 4);
608 result
[pos
+ 1] = to_hex(*p
& 15);
612 static inline unsigned char to_uchar(char ch
)
617 void base64_encode(const char *in
, size_t inlen
, char *out
, size_t outlen
)
619 static const char b64str
[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
620 while(inlen
&& outlen
)
622 *out
++ = b64str
[(to_uchar(in
[0]) >> 2) & 0x3f];
623 if(!--outlen
) { break; }
624 *out
++ = b64str
[((to_uchar(in
[0]) << 4) + (--inlen
? to_uchar(in
[1]) >> 4 : 0)) & 0x3f];
625 if(!--outlen
) { break; }
626 *out
++ = (inlen
? b64str
[((to_uchar(in
[1]) << 2) + (--inlen
? to_uchar(in
[2]) >> 6 : 0)) & 0x3f] : '=');
627 if(!--outlen
) { break; }
628 *out
++ = inlen
? b64str
[to_uchar(in
[2]) & 0x3f] : '=';
629 if(!--outlen
) { break; }
630 if(inlen
) { inlen
--; }
631 if(inlen
) { in
+= 3; }
632 if(outlen
) { *out
= '\0'; }
636 size_t b64encode(const char *in
, size_t inlen
, char **out
)
638 size_t outlen
= 1 + BASE64_LENGTH(inlen
);
644 if(!cs_malloc(out
, outlen
))
646 base64_encode(in
, inlen
, *out
, outlen
);
650 static int8_t b64decoder
[256];
652 /* Prepares the base64 decoding array */
653 void b64prepare(void)
655 const unsigned char alphabet
[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
657 for(i
= sizeof(b64decoder
) - 1; i
>= 0; --i
)
662 for(i
= sizeof(alphabet
) - 1; i
>= 0; --i
)
664 b64decoder
[alphabet
[i
]] = i
;
668 /* Decodes a base64-encoded string. The given array will be used directly for output and is thus modified! */
669 int32_t b64decode(unsigned char *result
)
671 int32_t i
, len
= strlen((char *)result
), j
= 0, bits
= 0, char_count
= 0;
673 if(!b64decoder
[0]) { b64prepare(); }
675 for(i
= 0; i
< len
; ++i
)
677 if(result
[i
] == '=') { break; }
678 int8_t tmp
= b64decoder
[result
[i
]];
679 if(tmp
== -1) { continue; }
684 result
[j
++] = bits
>> 16;
685 result
[j
++] = (bits
>> 8) & 0xff;
686 result
[j
++] = bits
& 0xff;
711 result
[j
++] = bits
>> 10;
715 result
[j
++] = bits
>> 16;
716 result
[j
++] = (bits
>> 8) & 0xff;
725 #ifdef READ_SDT_CHARSETS
727 // ISO_6937 function taken from VLC
728 /*****************************************************************************
729 * Local conversion routine from ISO_6937 to UTF-8 charset. Support for this
730 * is still missing in libiconv, hence multiple operating systems lack it.
731 * The conversion table adds Euro sign (0xA4) as per ETSI EN 300 468 Annex A
732 *****************************************************************************/
734 static const uint16_t iso_6937_to_ucs4
[128] =
736 /* 0x80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
737 /* 0x88 */ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
738 /* 0x90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
739 /* 0x98 */ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
740 /* 0xa0 */ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0000, 0x00a7,
741 /* 0xa8 */ 0x00a4, 0x2018, 0x201c, 0x00ab, 0x2190, 0x2191, 0x2192, 0x2193,
742 /* 0xb0 */ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7,
743 /* 0xb8 */ 0x00f7, 0x2019, 0x201d, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
744 /* 0xc0 */ 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
745 /* 0xc8 */ 0xffff, 0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff,
746 /* 0xd0 */ 0x2014, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x266a, 0x00ac, 0x00a6,
747 /* 0xd8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e,
748 /* 0xe0 */ 0x2126, 0x00c6, 0x00d0, 0x00aa, 0x0126, 0x0000, 0x0132, 0x013f,
749 /* 0xe8 */ 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0x0149,
750 /* 0xf0 */ 0x0138, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0140,
751 /* 0xf8 */ 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x00ad
754 /* The outer array range runs from 0xc1 to 0xcf, the inner range from 0x40
756 static const uint16_t iso_6937_to_ucs4_comb
[15][64] =
760 /* 0x40 */ 0x0000, 0x00c0, 0x0000, 0x0000, 0x0000, 0x00c8, 0x0000, 0x0000,
761 /* 0x48 */ 0x0000, 0x00cc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d2,
762 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d9, 0x0000, 0x0000,
763 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
764 /* 0x60 */ 0x0000, 0x00e0, 0x0000, 0x0000, 0x0000, 0x00e8, 0x0000, 0x0000,
765 /* 0x68 */ 0x0000, 0x00ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f2,
766 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f9, 0x0000, 0x0000,
767 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
771 /* 0x40 */ 0x0000, 0x00c1, 0x0000, 0x0106, 0x0000, 0x00c9, 0x0000, 0x0000,
772 /* 0x48 */ 0x0000, 0x00cd, 0x0000, 0x0000, 0x0139, 0x0000, 0x0143, 0x00d3,
773 /* 0x50 */ 0x0000, 0x0000, 0x0154, 0x015a, 0x0000, 0x00da, 0x0000, 0x0000,
774 /* 0x58 */ 0x0000, 0x00dd, 0x0179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
775 /* 0x60 */ 0x0000, 0x00e1, 0x0000, 0x0107, 0x0000, 0x00e9, 0x0000, 0x0000,
776 /* 0x68 */ 0x0000, 0x00ed, 0x0000, 0x0000, 0x013a, 0x0000, 0x0144, 0x00f3,
777 /* 0x70 */ 0x0000, 0x0000, 0x0155, 0x015b, 0x0000, 0x00fa, 0x0000, 0x0000,
778 /* 0x78 */ 0x0000, 0x00fd, 0x017a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
782 /* 0x40 */ 0x0000, 0x00c2, 0x0000, 0x0108, 0x0000, 0x00ca, 0x0000, 0x011c,
783 /* 0x48 */ 0x0124, 0x00ce, 0x0134, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d4,
784 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x015c, 0x0000, 0x00db, 0x0000, 0x0174,
785 /* 0x58 */ 0x0000, 0x0176, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
786 /* 0x60 */ 0x0000, 0x00e2, 0x0000, 0x0109, 0x0000, 0x00ea, 0x0000, 0x011d,
787 /* 0x68 */ 0x0125, 0x00ee, 0x0135, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f4,
788 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x015d, 0x0000, 0x00fb, 0x0000, 0x0175,
789 /* 0x78 */ 0x0000, 0x0177, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
793 /* 0x40 */ 0x0000, 0x00c3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
794 /* 0x48 */ 0x0000, 0x0128, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d1, 0x00d5,
795 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0168, 0x0000, 0x0000,
796 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
797 /* 0x60 */ 0x0000, 0x00e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
798 /* 0x68 */ 0x0000, 0x0129, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f1, 0x00f5,
799 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0169, 0x0000, 0x0000,
800 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
804 /* 0x40 */ 0x0000, 0x0100, 0x0000, 0x0000, 0x0000, 0x0112, 0x0000, 0x0000,
805 /* 0x48 */ 0x0000, 0x012a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014c,
806 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016a, 0x0000, 0x0000,
807 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
808 /* 0x60 */ 0x0000, 0x0101, 0x0000, 0x0000, 0x0000, 0x0113, 0x0000, 0x0000,
809 /* 0x68 */ 0x0000, 0x012b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014d,
810 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016b, 0x0000, 0x0000,
811 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
815 /* 0x40 */ 0x0000, 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011e,
816 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
817 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x0000, 0x0000,
818 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
819 /* 0x60 */ 0x0000, 0x0103, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011f,
820 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
821 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x0000, 0x0000,
822 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
826 /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x010a, 0x0000, 0x0116, 0x0000, 0x0120,
827 /* 0x48 */ 0x0000, 0x0130, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
828 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
829 /* 0x58 */ 0x0000, 0x0000, 0x017b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
830 /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x010b, 0x0000, 0x0117, 0x0000, 0x0121,
831 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
832 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
833 /* 0x78 */ 0x0000, 0x0000, 0x017c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
837 /* 0x40 */ 0x0000, 0x00c4, 0x0000, 0x0000, 0x0000, 0x00cb, 0x0000, 0x0000,
838 /* 0x48 */ 0x0000, 0x00cf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d6,
839 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00dc, 0x0000, 0x0000,
840 /* 0x58 */ 0x0000, 0x0178, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
841 /* 0x60 */ 0x0000, 0x00e4, 0x0000, 0x0000, 0x0000, 0x00eb, 0x0000, 0x0000,
842 /* 0x68 */ 0x0000, 0x00ef, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f6,
843 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00fc, 0x0000, 0x0000,
844 /* 0x78 */ 0x0000, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
852 /* 0x40 */ 0x0000, 0x00c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
853 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
854 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016e, 0x0000, 0x0000,
855 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
856 /* 0x60 */ 0x0000, 0x00e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
857 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
858 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016f, 0x0000, 0x0000,
859 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
863 /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x00c7, 0x0000, 0x0000, 0x0000, 0x0122,
864 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0136, 0x013b, 0x0000, 0x0145, 0x0000,
865 /* 0x50 */ 0x0000, 0x0000, 0x0156, 0x015e, 0x0162, 0x0000, 0x0000, 0x0000,
866 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
867 /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x00e7, 0x0000, 0x0000, 0x0000, 0x0123,
868 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0137, 0x013c, 0x0000, 0x0146, 0x0000,
869 /* 0x70 */ 0x0000, 0x0000, 0x0157, 0x015f, 0x0163, 0x0000, 0x0000, 0x0000,
870 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
878 /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
879 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0150,
880 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0170, 0x0000, 0x0000,
881 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
882 /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
883 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0151,
884 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0171, 0x0000, 0x0000,
885 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
889 /* 0x40 */ 0x0000, 0x0104, 0x0000, 0x0000, 0x0000, 0x0118, 0x0000, 0x0000,
890 /* 0x48 */ 0x0000, 0x012e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
891 /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0172, 0x0000, 0x0000,
892 /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
893 /* 0x60 */ 0x0000, 0x0105, 0x0000, 0x0000, 0x0000, 0x0119, 0x0000, 0x0000,
894 /* 0x68 */ 0x0000, 0x012f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
895 /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0173, 0x0000, 0x0000,
896 /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
900 /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x010c, 0x010e, 0x011a, 0x0000, 0x0000,
901 /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x013d, 0x0000, 0x0147, 0x0000,
902 /* 0x50 */ 0x0000, 0x0000, 0x0158, 0x0160, 0x0164, 0x0000, 0x0000, 0x0000,
903 /* 0x58 */ 0x0000, 0x0000, 0x017d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
904 /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x010d, 0x010f, 0x011b, 0x0000, 0x0000,
905 /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x013e, 0x0000, 0x0148, 0x0000,
906 /* 0x70 */ 0x0000, 0x0000, 0x0159, 0x0161, 0x0165, 0x0000, 0x0000, 0x0000,
907 /* 0x78 */ 0x0000, 0x0000, 0x017e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
911 size_t ISO6937toUTF8( const unsigned char **inbuf
, size_t *inbytesleft
,
912 unsigned char **outbuf
, size_t *outbytesleft
)
916 if( !inbuf
|| !(*inbuf
) )
917 return (size_t)(0); /* Reset state requested */
919 const unsigned char *iptr
= *inbuf
;
920 const unsigned char *iend
= iptr
+ *inbytesleft
;
921 unsigned char *optr
= *outbuf
;
922 unsigned char *oend
= optr
+ *outbytesleft
;
926 while ( iptr
< iend
)
933 break; /* No space in outbuf */
940 if ( optr
+ 2 >= oend
)
943 break; /* No space in outbuf for multibyte char */
946 ch
= iso_6937_to_ucs4
[*iptr
- 0x80];
950 /* Composed character */
951 if ( iptr
+ 1 >= iend
)
954 break; /* No next character */
956 if ( iptr
[1] < 0x40 || iptr
[1] >= 0x80 ||
957 !(ch
= iso_6937_to_ucs4_comb
[iptr
[0] - 0xc1][iptr
[1] - 0x40]) )
960 break; /* Illegal combination */
977 optr
[1] = 0x80 | (ch
& 0x3f);
978 optr
[0] = 0xc0 | (ch
>> 6);
983 optr
[2] = 0x80 | (ch
& 0x3f);
985 optr
[1] = 0x80 | (ch
& 0x3f);
986 optr
[0] = 0xe0 | (ch
>> 6);
993 *inbytesleft
= iend
- iptr
;
994 *outbytesleft
= oend
- optr
;
1006 #include "oscam-string-isotables.h"
1008 static const uint16_t *get_iso8859_table(int8_t iso_table_number
)
1010 if(iso_table_number
> 1 && iso_table_number
< 17 && iso_table_number
!= 12)
1012 if(iso_table_number
< 12)
1013 { return iso_8859_to_unicode
[iso_table_number
- 2]; }
1015 { return iso_8859_to_unicode
[iso_table_number
- 3]; }
1022 size_t ISO8859toUTF8(int8_t iso_table_number
, const unsigned char **inbuf
, size_t *inbytesleft
,
1023 unsigned char **outbuf
, size_t *outbytesleft
)
1027 if( !inbuf
|| !(*inbuf
) )
1028 return (size_t)(0); /* Reset state requested */
1030 const unsigned char *iptr
= *inbuf
;
1031 const unsigned char *iend
= iptr
+ *inbytesleft
;
1032 unsigned char *optr
= *outbuf
;
1033 unsigned char *oend
= optr
+ *outbytesleft
;
1036 const uint16_t *iso_table
= NULL
;
1038 if( iso_table_number
!= 1 )
1040 iso_table
= get_iso8859_table(iso_table_number
);
1041 if ( iso_table
== NULL
)
1044 return (size_t)(-1);
1048 while ( iptr
< iend
)
1055 break; /* No space in outbuf */
1061 if( iso_table_number
== 1 || *iptr
< 0xA1 )
1067 ch
= iso_table
[*iptr
- 0xA1];
1077 break; /* No space in outbuf for char */
1080 optr
[0] = ch
& 0xff;
1083 else if ( ch
< 0x800 )
1085 if ( optr
+ 1 >= oend
)
1088 break; /* No space in outbuf for multibyte char */
1091 optr
[1] = 0x80 | (ch
& 0x3f);
1092 optr
[0] = 0xc0 | (ch
>> 6);
1097 if ( optr
+ 2 >= oend
)
1100 break; /* No space in outbuf for multibyte char */
1103 optr
[2] = 0x80 | (ch
& 0x3f);
1105 optr
[1] = 0x80 | (ch
& 0x3f);
1106 optr
[0] = 0xe0 | (ch
>> 6);
1113 *inbytesleft
= iend
- iptr
;
1114 *outbytesleft
= oend
- optr
;
1119 return (size_t)(-1);
1128 size_t UnicodetoUTF8(const unsigned char **inbuf
, size_t *inbytesleft
, unsigned char **outbuf
, size_t *outbytesleft
)
1130 if( !inbuf
|| !(*inbuf
) )
1131 return (size_t)(0); /* Reset state requested */
1133 const unsigned char *iptr
= *inbuf
;
1134 const unsigned char *iend
= iptr
+ *inbytesleft
;
1135 unsigned char *optr
= *outbuf
;
1136 unsigned char *oend
= optr
+ *outbytesleft
;
1140 while ( iptr
+1 < iend
)
1142 ch
= (iptr
[0] << 8) | iptr
[1];
1151 break; /* No space in outbuf for char */
1154 optr
[0] = ch
& 0xff;
1157 else if ( ch
< 0x800 )
1159 if ( optr
+ 1 >= oend
)
1162 break; /* No space in outbuf for multibyte char */
1165 optr
[1] = 0x80 | (ch
& 0x3f);
1166 optr
[0] = 0xc0 | (ch
>> 6);
1171 if ( optr
+ 2 >= oend
)
1174 break; /* No space in outbuf for multibyte char */
1177 optr
[2] = 0x80 | (ch
& 0x3f);
1179 optr
[1] = 0x80 | (ch
& 0x3f);
1180 optr
[0] = 0xe0 | (ch
>> 6);
1187 *inbytesleft
= iend
- iptr
;
1188 *outbytesleft
= oend
- optr
;
1193 return (size_t)(-1);