Software /
code /
prosody
Comparison
util-src/encodings.c @ 7889:b8d694646597
util-src/*.c: Attach pointer * to name instead of type
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 12 Feb 2017 16:42:29 +0100 |
parent | 7835:a809dcfd0c5b |
child | 7998:604beb13596a |
comparison
equal
deleted
inserted
replaced
7888:74187ee6ed55 | 7889:b8d694646597 |
---|---|
28 /***************** BASE64 *****************/ | 28 /***************** BASE64 *****************/ |
29 | 29 |
30 static const char code[] = | 30 static const char code[] = |
31 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 31 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
32 | 32 |
33 static void base64_encode(luaL_Buffer* b, unsigned int c1, unsigned int c2, unsigned int c3, int n) { | 33 static void base64_encode(luaL_Buffer *b, unsigned int c1, unsigned int c2, unsigned int c3, int n) { |
34 unsigned long tuple = c3 + 256UL * (c2 + 256UL * c1); | 34 unsigned long tuple = c3 + 256UL * (c2 + 256UL * c1); |
35 int i; | 35 int i; |
36 char s[4]; | 36 char s[4]; |
37 | 37 |
38 for(i = 0; i < 4; i++) { | 38 for(i = 0; i < 4; i++) { |
45 } | 45 } |
46 | 46 |
47 luaL_addlstring(b, s, 4); | 47 luaL_addlstring(b, s, 4); |
48 } | 48 } |
49 | 49 |
50 static int Lbase64_encode(lua_State* L) { /** encode(s) */ | 50 static int Lbase64_encode(lua_State *L) { /** encode(s) */ |
51 size_t l; | 51 size_t l; |
52 const unsigned char* s = (const unsigned char*)luaL_checklstring(L, 1, &l); | 52 const unsigned char *s = (const unsigned char *)luaL_checklstring(L, 1, &l); |
53 luaL_Buffer b; | 53 luaL_Buffer b; |
54 int n; | 54 int n; |
55 luaL_buffinit(L, &b); | 55 luaL_buffinit(L, &b); |
56 | 56 |
57 for(n = l / 3; n--; s += 3) { | 57 for(n = l / 3; n--; s += 3) { |
60 | 60 |
61 switch(l % 3) { | 61 switch(l % 3) { |
62 case 1: | 62 case 1: |
63 base64_encode(&b, s[0], 0, 0, 1); | 63 base64_encode(&b, s[0], 0, 0, 1); |
64 break; | 64 break; |
65 | |
65 case 2: | 66 case 2: |
66 base64_encode(&b, s[0], s[1], 0, 2); | 67 base64_encode(&b, s[0], s[1], 0, 2); |
67 break; | 68 break; |
68 } | 69 } |
69 | 70 |
70 luaL_pushresult(&b); | 71 luaL_pushresult(&b); |
71 return 1; | 72 return 1; |
72 } | 73 } |
73 | 74 |
74 static void base64_decode(luaL_Buffer* b, int c1, int c2, int c3, int c4, int n) { | 75 static void base64_decode(luaL_Buffer *b, int c1, int c2, int c3, int c4, int n) { |
75 unsigned long tuple = c4 + 64L * (c3 + 64L * (c2 + 64L * c1)); | 76 unsigned long tuple = c4 + 64L * (c3 + 64L * (c2 + 64L * c1)); |
76 char s[3]; | 77 char s[3]; |
77 | 78 |
78 switch(--n) { | 79 switch(--n) { |
79 case 3: | 80 case 3: |
80 s[2] = (char) tuple; | 81 s[2] = (char) tuple; |
82 | |
81 case 2: | 83 case 2: |
82 s[1] = (char)(tuple >> 8); | 84 s[1] = (char)(tuple >> 8); |
85 | |
83 case 1: | 86 case 1: |
84 s[0] = (char)(tuple >> 16); | 87 s[0] = (char)(tuple >> 16); |
85 } | 88 } |
86 | 89 |
87 luaL_addlstring(b, s, n); | 90 luaL_addlstring(b, s, n); |
88 } | 91 } |
89 | 92 |
90 static int Lbase64_decode(lua_State* L) { /** decode(s) */ | 93 static int Lbase64_decode(lua_State *L) { /** decode(s) */ |
91 size_t l; | 94 size_t l; |
92 const char* s = luaL_checklstring(L, 1, &l); | 95 const char *s = luaL_checklstring(L, 1, &l); |
93 luaL_Buffer b; | 96 luaL_Buffer b; |
94 int n = 0; | 97 int n = 0; |
95 char t[4]; | 98 char t[4]; |
96 luaL_buffinit(L, &b); | 99 luaL_buffinit(L, &b); |
97 | 100 |
98 for(;;) { | 101 for(;;) { |
99 int c = *s++; | 102 int c = *s++; |
100 | 103 |
101 switch(c) { | 104 switch(c) { |
102 const char* p; | 105 const char *p; |
106 | |
103 default: | 107 default: |
104 p = strchr(code, c); | 108 p = strchr(code, c); |
105 | 109 |
106 if(p == NULL) { | 110 if(p == NULL) { |
107 return 0; | 111 return 0; |
113 base64_decode(&b, t[0], t[1], t[2], t[3], 4); | 117 base64_decode(&b, t[0], t[1], t[2], t[3], 4); |
114 n = 0; | 118 n = 0; |
115 } | 119 } |
116 | 120 |
117 break; | 121 break; |
122 | |
118 case '=': | 123 case '=': |
119 | 124 |
120 switch(n) { | 125 switch(n) { |
121 case 1: | 126 case 1: |
122 base64_decode(&b, t[0], 0, 0, 0, 1); | 127 base64_decode(&b, t[0], 0, 0, 0, 1); |
123 break; | 128 break; |
129 | |
124 case 2: | 130 case 2: |
125 base64_decode(&b, t[0], t[1], 0, 0, 2); | 131 base64_decode(&b, t[0], t[1], 0, 0, 2); |
126 break; | 132 break; |
133 | |
127 case 3: | 134 case 3: |
128 base64_decode(&b, t[0], t[1], t[2], 0, 3); | 135 base64_decode(&b, t[0], t[1], t[2], 0, 3); |
129 break; | 136 break; |
130 } | 137 } |
131 | 138 |
132 n = 0; | 139 n = 0; |
133 break; | 140 break; |
141 | |
134 case 0: | 142 case 0: |
135 luaL_pushresult(&b); | 143 luaL_pushresult(&b); |
136 return 1; | 144 return 1; |
145 | |
137 case '\n': | 146 case '\n': |
138 case '\r': | 147 case '\r': |
139 case '\t': | 148 case '\t': |
140 case ' ': | 149 case ' ': |
141 case '\f': | 150 case '\f': |
161 #define MAXUNICODE 0x10FFFF | 170 #define MAXUNICODE 0x10FFFF |
162 | 171 |
163 /* | 172 /* |
164 * Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. | 173 * Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. |
165 */ | 174 */ |
166 static const char* utf8_decode(const char* o, int* val) { | 175 static const char *utf8_decode(const char *o, int *val) { |
167 static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; | 176 static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; |
168 const unsigned char* s = (const unsigned char*)o; | 177 const unsigned char *s = (const unsigned char *)o; |
169 unsigned int c = s[0]; | 178 unsigned int c = s[0]; |
170 unsigned int res = 0; /* final result */ | 179 unsigned int res = 0; /* final result */ |
171 | 180 |
172 if(c < 0x80) { /* ascii? */ | 181 if(c < 0x80) { /* ascii? */ |
173 res = c; | 182 res = c; |
196 | 205 |
197 if(val) { | 206 if(val) { |
198 *val = res; | 207 *val = res; |
199 } | 208 } |
200 | 209 |
201 return (const char*)s + 1; /* +1 to include first byte */ | 210 return (const char *)s + 1; /* +1 to include first byte */ |
202 } | 211 } |
203 | 212 |
204 /* | 213 /* |
205 * Check that a string is valid UTF-8 | 214 * Check that a string is valid UTF-8 |
206 * Returns NULL if not | 215 * Returns NULL if not |
207 */ | 216 */ |
208 const char* check_utf8(lua_State* L, int idx, size_t* l) { | 217 const char *check_utf8(lua_State *L, int idx, size_t *l) { |
209 size_t pos, len; | 218 size_t pos, len; |
210 const char* s = luaL_checklstring(L, 1, &len); | 219 const char *s = luaL_checklstring(L, 1, &len); |
211 pos = 0; | 220 pos = 0; |
212 | 221 |
213 while(pos <= len) { | 222 while(pos <= len) { |
214 const char* s1 = utf8_decode(s + pos, NULL); | 223 const char *s1 = utf8_decode(s + pos, NULL); |
215 | 224 |
216 if(s1 == NULL) { /* conversion error? */ | 225 if(s1 == NULL) { /* conversion error? */ |
217 return NULL; | 226 return NULL; |
218 } | 227 } |
219 | 228 |
225 } | 234 } |
226 | 235 |
227 return s; | 236 return s; |
228 } | 237 } |
229 | 238 |
230 static int Lutf8_valid(lua_State* L) { | 239 static int Lutf8_valid(lua_State *L) { |
231 lua_pushboolean(L, check_utf8(L, 1, NULL) != NULL); | 240 lua_pushboolean(L, check_utf8(L, 1, NULL) != NULL); |
232 return 1; | 241 return 1; |
233 } | 242 } |
234 | 243 |
235 static int Lutf8_length(lua_State* L) { | 244 static int Lutf8_length(lua_State *L) { |
236 size_t len; | 245 size_t len; |
237 | 246 |
238 if(!check_utf8(L, 1, &len)) { | 247 if(!check_utf8(L, 1, &len)) { |
239 lua_pushnil(L); | 248 lua_pushnil(L); |
240 lua_pushliteral(L, "invalid utf8"); | 249 lua_pushliteral(L, "invalid utf8"); |
256 | 265 |
257 #include <unicode/usprep.h> | 266 #include <unicode/usprep.h> |
258 #include <unicode/ustring.h> | 267 #include <unicode/ustring.h> |
259 #include <unicode/utrace.h> | 268 #include <unicode/utrace.h> |
260 | 269 |
261 static int icu_stringprep_prep(lua_State* L, const UStringPrepProfile* profile) { | 270 static int icu_stringprep_prep(lua_State *L, const UStringPrepProfile *profile) { |
262 size_t input_len; | 271 size_t input_len; |
263 int32_t unprepped_len, prepped_len, output_len; | 272 int32_t unprepped_len, prepped_len, output_len; |
264 const char* input; | 273 const char *input; |
265 char output[1024]; | 274 char output[1024]; |
266 | 275 |
267 UChar unprepped[1024]; /* Temporary unicode buffer (1024 characters) */ | 276 UChar unprepped[1024]; /* Temporary unicode buffer (1024 characters) */ |
268 UChar prepped[1024]; | 277 UChar prepped[1024]; |
269 | 278 |
304 | 313 |
305 return 1; | 314 return 1; |
306 } | 315 } |
307 } | 316 } |
308 | 317 |
309 UStringPrepProfile* icu_nameprep; | 318 UStringPrepProfile *icu_nameprep; |
310 UStringPrepProfile* icu_nodeprep; | 319 UStringPrepProfile *icu_nodeprep; |
311 UStringPrepProfile* icu_resourceprep; | 320 UStringPrepProfile *icu_resourceprep; |
312 UStringPrepProfile* icu_saslprep; | 321 UStringPrepProfile *icu_saslprep; |
313 | 322 |
314 /* initialize global ICU stringprep profiles */ | 323 /* initialize global ICU stringprep profiles */ |
315 void init_icu() { | 324 void init_icu() { |
316 UErrorCode err = U_ZERO_ERROR; | 325 UErrorCode err = U_ZERO_ERROR; |
317 utrace_setLevel(UTRACE_VERBOSE); | 326 utrace_setLevel(UTRACE_VERBOSE); |
344 | 353 |
345 /****************** libidn ********************/ | 354 /****************** libidn ********************/ |
346 | 355 |
347 #include <stringprep.h> | 356 #include <stringprep.h> |
348 | 357 |
349 static int stringprep_prep(lua_State* L, const Stringprep_profile* profile) { | 358 static int stringprep_prep(lua_State *L, const Stringprep_profile *profile) { |
350 size_t len; | 359 size_t len; |
351 const char* s; | 360 const char *s; |
352 char string[1024]; | 361 char string[1024]; |
353 int ret; | 362 int ret; |
354 | 363 |
355 if(!lua_isstring(L, 1)) { | 364 if(!lua_isstring(L, 1)) { |
356 lua_pushnil(L); | 365 lua_pushnil(L); |
396 /***************** IDNA *****************/ | 405 /***************** IDNA *****************/ |
397 #ifdef USE_STRINGPREP_ICU | 406 #ifdef USE_STRINGPREP_ICU |
398 #include <unicode/ustdio.h> | 407 #include <unicode/ustdio.h> |
399 #include <unicode/uidna.h> | 408 #include <unicode/uidna.h> |
400 /* IDNA2003 or IDNA2008 ? ? ? */ | 409 /* IDNA2003 or IDNA2008 ? ? ? */ |
401 static int Lidna_to_ascii(lua_State* L) { /** idna.to_ascii(s) */ | 410 static int Lidna_to_ascii(lua_State *L) { /** idna.to_ascii(s) */ |
402 size_t len; | 411 size_t len; |
403 int32_t ulen, dest_len, output_len; | 412 int32_t ulen, dest_len, output_len; |
404 const char* s = luaL_checklstring(L, 1, &len); | 413 const char *s = luaL_checklstring(L, 1, &len); |
405 UChar ustr[1024]; | 414 UChar ustr[1024]; |
406 UErrorCode err = U_ZERO_ERROR; | 415 UErrorCode err = U_ZERO_ERROR; |
407 UChar dest[1024]; | 416 UChar dest[1024]; |
408 char output[1024]; | 417 char output[1024]; |
409 | 418 |
430 | 439 |
431 return 1; | 440 return 1; |
432 } | 441 } |
433 } | 442 } |
434 | 443 |
435 static int Lidna_to_unicode(lua_State* L) { /** idna.to_unicode(s) */ | 444 static int Lidna_to_unicode(lua_State *L) { /** idna.to_unicode(s) */ |
436 size_t len; | 445 size_t len; |
437 int32_t ulen, dest_len, output_len; | 446 int32_t ulen, dest_len, output_len; |
438 const char* s = luaL_checklstring(L, 1, &len); | 447 const char *s = luaL_checklstring(L, 1, &len); |
439 UChar ustr[1024]; | 448 UChar ustr[1024]; |
440 UErrorCode err = U_ZERO_ERROR; | 449 UErrorCode err = U_ZERO_ERROR; |
441 UChar dest[1024]; | 450 UChar dest[1024]; |
442 char output[1024]; | 451 char output[1024]; |
443 | 452 |
470 /****************** libidn ********************/ | 479 /****************** libidn ********************/ |
471 | 480 |
472 #include <idna.h> | 481 #include <idna.h> |
473 #include <idn-free.h> | 482 #include <idn-free.h> |
474 | 483 |
475 static int Lidna_to_ascii(lua_State* L) { /** idna.to_ascii(s) */ | 484 static int Lidna_to_ascii(lua_State *L) { /** idna.to_ascii(s) */ |
476 size_t len; | 485 size_t len; |
477 const char* s = check_utf8(L, 1, &len); | 486 const char *s = check_utf8(L, 1, &len); |
478 char* output = NULL; | 487 char *output = NULL; |
479 int ret; | 488 int ret; |
480 | 489 |
481 if(s == NULL || len != strlen(s)) { | 490 if(s == NULL || len != strlen(s)) { |
482 lua_pushnil(L); | 491 lua_pushnil(L); |
483 return 1; /* TODO return error message */ | 492 return 1; /* TODO return error message */ |
494 idn_free(output); | 503 idn_free(output); |
495 return 1; /* TODO return error message */ | 504 return 1; /* TODO return error message */ |
496 } | 505 } |
497 } | 506 } |
498 | 507 |
499 static int Lidna_to_unicode(lua_State* L) { /** idna.to_unicode(s) */ | 508 static int Lidna_to_unicode(lua_State *L) { /** idna.to_unicode(s) */ |
500 size_t len; | 509 size_t len; |
501 const char* s = luaL_checklstring(L, 1, &len); | 510 const char *s = luaL_checklstring(L, 1, &len); |
502 char* output = NULL; | 511 char *output = NULL; |
503 int ret = idna_to_unicode_8z8z(s, &output, 0); | 512 int ret = idna_to_unicode_8z8z(s, &output, 0); |
504 | 513 |
505 if(ret == IDNA_SUCCESS) { | 514 if(ret == IDNA_SUCCESS) { |
506 lua_pushstring(L, output); | 515 lua_pushstring(L, output); |
507 idn_free(output); | 516 idn_free(output); |
520 { NULL, NULL } | 529 { NULL, NULL } |
521 }; | 530 }; |
522 | 531 |
523 /***************** end *****************/ | 532 /***************** end *****************/ |
524 | 533 |
525 LUALIB_API int luaopen_util_encodings(lua_State* L) { | 534 LUALIB_API int luaopen_util_encodings(lua_State *L) { |
526 #if (LUA_VERSION_NUM > 501) | 535 #if (LUA_VERSION_NUM > 501) |
527 luaL_checkversion(L); | 536 luaL_checkversion(L); |
528 #endif | 537 #endif |
529 #ifdef USE_STRINGPREP_ICU | 538 #ifdef USE_STRINGPREP_ICU |
530 init_icu(); | 539 init_icu(); |