Software / code / prosody
Comparison
util-src/encodings.c @ 6615:8e4572a642cb
util-src/*.c: astyle --indent=tab --brackets=attach --indent-switches --break-blocks --pad-oper --unpad-paren --add-brackets --align-pointer=type --lineend=linux
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Fri, 03 Apr 2015 19:52:48 +0200 |
| parent | 6608:b6e558febb7a |
| child | 6643:127b9f0c6135 |
comparison
equal
deleted
inserted
replaced
| 6613:2aae36312eb9 | 6615:8e4572a642cb |
|---|---|
| 1 /* Prosody IM | 1 /* Prosody IM |
| 2 -- Copyright (C) 2008-2010 Matthew Wild | 2 -- Copyright (C) 2008-2010 Matthew Wild |
| 3 -- Copyright (C) 2008-2010 Waqas Hussain | 3 -- Copyright (C) 2008-2010 Waqas Hussain |
| 4 -- Copyright (C) 1994-2015 Lua.org, PUC-Rio. | 4 -- Copyright (C) 1994-2015 Lua.org, PUC-Rio. |
| 5 -- | 5 -- |
| 6 -- This project is MIT/X11 licensed. Please see the | 6 -- This project is MIT/X11 licensed. Please see the |
| 7 -- COPYING file in the source package for more information. | 7 -- COPYING file in the source package for more information. |
| 8 -- | 8 -- |
| 9 */ | 9 */ |
| 10 | 10 |
| 25 #define luaL_register(L, N, R) luaL_setfuncs(L, R, 0) | 25 #define luaL_register(L, N, R) luaL_setfuncs(L, R, 0) |
| 26 #endif | 26 #endif |
| 27 | 27 |
| 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 { | 34 unsigned long tuple = c3 + 256UL * (c2 + 256UL * c1); |
| 35 unsigned long tuple=c3+256UL*(c2+256UL*c1); | |
| 36 int i; | 35 int i; |
| 37 char s[4]; | 36 char s[4]; |
| 38 for (i=0; i<4; i++) { | 37 |
| 39 s[3-i] = code[tuple % 64]; | 38 for(i = 0; i < 4; i++) { |
| 39 s[3 - i] = code[tuple % 64]; | |
| 40 tuple /= 64; | 40 tuple /= 64; |
| 41 } | 41 } |
| 42 for (i=n+1; i<4; i++) s[i]='='; | 42 |
| 43 luaL_addlstring(b,s,4); | 43 for(i = n + 1; i < 4; i++) { |
| 44 } | 44 s[i] = '='; |
| 45 | 45 } |
| 46 static int Lbase64_encode(lua_State *L) /** encode(s) */ | 46 |
| 47 { | 47 luaL_addlstring(b, s, 4); |
| 48 } | |
| 49 | |
| 50 static int Lbase64_encode(lua_State* L) { /** encode(s) */ | |
| 48 size_t l; | 51 size_t l; |
| 49 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); |
| 50 luaL_Buffer b; | 53 luaL_Buffer b; |
| 51 int n; | 54 int n; |
| 52 luaL_buffinit(L,&b); | 55 luaL_buffinit(L, &b); |
| 53 for (n=l/3; n--; s+=3) base64_encode(&b,s[0],s[1],s[2],3); | 56 |
| 54 switch (l%3) | 57 for(n = l / 3; n--; s += 3) { |
| 55 { | 58 base64_encode(&b, s[0], s[1], s[2], 3); |
| 56 case 1: base64_encode(&b,s[0],0,0,1); break; | 59 } |
| 57 case 2: base64_encode(&b,s[0],s[1],0,2); break; | 60 |
| 58 } | 61 switch(l % 3) { |
| 62 case 1: | |
| 63 base64_encode(&b, s[0], 0, 0, 1); | |
| 64 break; | |
| 65 case 2: | |
| 66 base64_encode(&b, s[0], s[1], 0, 2); | |
| 67 break; | |
| 68 } | |
| 69 | |
| 59 luaL_pushresult(&b); | 70 luaL_pushresult(&b); |
| 60 return 1; | 71 return 1; |
| 61 } | 72 } |
| 62 | 73 |
| 63 static void base64_decode(luaL_Buffer *b, int c1, int c2, int c3, int c4, int n) | 74 static void base64_decode(luaL_Buffer* b, int c1, int c2, int c3, int c4, int n) { |
| 64 { | 75 unsigned long tuple = c4 + 64L * (c3 + 64L * (c2 + 64L * c1)); |
| 65 unsigned long tuple=c4+64L*(c3+64L*(c2+64L*c1)); | |
| 66 char s[3]; | 76 char s[3]; |
| 67 switch (--n) | 77 |
| 68 { | 78 switch(--n) { |
| 69 case 3: s[2]=(char) tuple; | 79 case 3: |
| 70 case 2: s[1]=(char) (tuple >> 8); | 80 s[2] = (char) tuple; |
| 71 case 1: s[0]=(char) (tuple >> 16); | 81 case 2: |
| 72 } | 82 s[1] = (char)(tuple >> 8); |
| 73 luaL_addlstring(b,s,n); | 83 case 1: |
| 74 } | 84 s[0] = (char)(tuple >> 16); |
| 75 | 85 } |
| 76 static int Lbase64_decode(lua_State *L) /** decode(s) */ | 86 |
| 77 { | 87 luaL_addlstring(b, s, n); |
| 88 } | |
| 89 | |
| 90 static int Lbase64_decode(lua_State* L) { /** decode(s) */ | |
| 78 size_t l; | 91 size_t l; |
| 79 const char *s=luaL_checklstring(L,1,&l); | 92 const char* s = luaL_checklstring(L, 1, &l); |
| 80 luaL_Buffer b; | 93 luaL_Buffer b; |
| 81 int n=0; | 94 int n = 0; |
| 82 char t[4]; | 95 char t[4]; |
| 83 luaL_buffinit(L,&b); | 96 luaL_buffinit(L, &b); |
| 84 for (;;) | 97 |
| 85 { | 98 for(;;) { |
| 86 int c=*s++; | 99 int c = *s++; |
| 87 switch (c) | 100 |
| 88 { | 101 switch(c) { |
| 89 const char *p; | 102 const char* p; |
| 90 default: | 103 default: |
| 91 p=strchr(code,c); if (p==NULL) return 0; | 104 p = strchr(code, c); |
| 92 t[n++]= (char) (p-code); | 105 |
| 93 if (n==4) | 106 if(p == NULL) { |
| 94 { | 107 return 0; |
| 95 base64_decode(&b,t[0],t[1],t[2],t[3],4); | |
| 96 n=0; | |
| 97 } | 108 } |
| 109 | |
| 110 t[n++] = (char)(p - code); | |
| 111 | |
| 112 if(n == 4) { | |
| 113 base64_decode(&b, t[0], t[1], t[2], t[3], 4); | |
| 114 n = 0; | |
| 115 } | |
| 116 | |
| 98 break; | 117 break; |
| 99 case '=': | 118 case '=': |
| 100 switch (n) | 119 |
| 101 { | 120 switch(n) { |
| 102 case 1: base64_decode(&b,t[0],0,0,0,1); break; | 121 case 1: |
| 103 case 2: base64_decode(&b,t[0],t[1],0,0,2); break; | 122 base64_decode(&b, t[0], 0, 0, 0, 1); |
| 104 case 3: base64_decode(&b,t[0],t[1],t[2],0,3); break; | 123 break; |
| 124 case 2: | |
| 125 base64_decode(&b, t[0], t[1], 0, 0, 2); | |
| 126 break; | |
| 127 case 3: | |
| 128 base64_decode(&b, t[0], t[1], t[2], 0, 3); | |
| 129 break; | |
| 105 } | 130 } |
| 106 n=0; | 131 |
| 132 n = 0; | |
| 107 break; | 133 break; |
| 108 case 0: | 134 case 0: |
| 109 luaL_pushresult(&b); | 135 luaL_pushresult(&b); |
| 110 return 1; | 136 return 1; |
| 111 case '\n': case '\r': case '\t': case ' ': case '\f': case '\b': | 137 case '\n': |
| 138 case '\r': | |
| 139 case '\t': | |
| 140 case ' ': | |
| 141 case '\f': | |
| 142 case '\b': | |
| 112 break; | 143 break; |
| 113 } | 144 } |
| 114 } | 145 } |
| 115 } | 146 } |
| 116 | 147 |
| 117 static const luaL_Reg Reg_base64[] = | 148 static const luaL_Reg Reg_base64[] = { |
| 118 { | |
| 119 { "encode", Lbase64_encode }, | 149 { "encode", Lbase64_encode }, |
| 120 { "decode", Lbase64_decode }, | 150 { "decode", Lbase64_decode }, |
| 121 { NULL, NULL } | 151 { NULL, NULL } |
| 122 }; | 152 }; |
| 123 | 153 |
| 131 #define MAXUNICODE 0x10FFFF | 161 #define MAXUNICODE 0x10FFFF |
| 132 | 162 |
| 133 /* | 163 /* |
| 134 * Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. | 164 * Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. |
| 135 */ | 165 */ |
| 136 static const char *utf8_decode (const char *o, int *val) { | 166 static const char* utf8_decode(const char* o, int* val) { |
| 137 static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; | 167 static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; |
| 138 const unsigned char *s = (const unsigned char *)o; | 168 const unsigned char* s = (const unsigned char*)o; |
| 139 unsigned int c = s[0]; | 169 unsigned int c = s[0]; |
| 140 unsigned int res = 0; /* final result */ | 170 unsigned int res = 0; /* final result */ |
| 141 if (c < 0x80) /* ascii? */ | 171 |
| 172 if(c < 0x80) { /* ascii? */ | |
| 142 res = c; | 173 res = c; |
| 143 else { | 174 } else { |
| 144 int count = 0; /* to count number of continuation bytes */ | 175 int count = 0; /* to count number of continuation bytes */ |
| 145 while (c & 0x40) { /* still have continuation bytes? */ | 176 |
| 177 while(c & 0x40) { /* still have continuation bytes? */ | |
| 146 int cc = s[++count]; /* read next byte */ | 178 int cc = s[++count]; /* read next byte */ |
| 147 if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ | 179 |
| 148 return NULL; /* invalid byte sequence */ | 180 if((cc & 0xC0) != 0x80) { /* not a continuation byte? */ |
| 181 return NULL; /* invalid byte sequence */ | |
| 182 } | |
| 183 | |
| 149 res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ | 184 res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ |
| 150 c <<= 1; /* to test next bit */ | 185 c <<= 1; /* to test next bit */ |
| 151 } | 186 } |
| 187 | |
| 152 res |= ((c & 0x7F) << (count * 5)); /* add first byte */ | 188 res |= ((c & 0x7F) << (count * 5)); /* add first byte */ |
| 153 if (count > 3 || res > MAXUNICODE || res <= limits[count] || (0xd800 <= res && res <= 0xdfff) ) | 189 |
| 154 return NULL; /* invalid byte sequence */ | 190 if(count > 3 || res > MAXUNICODE || res <= limits[count] || (0xd800 <= res && res <= 0xdfff)) { |
| 191 return NULL; /* invalid byte sequence */ | |
| 192 } | |
| 193 | |
| 155 s += count; /* skip continuation bytes read */ | 194 s += count; /* skip continuation bytes read */ |
| 156 } | 195 } |
| 157 if (val) *val = res; | 196 |
| 158 return (const char *)s + 1; /* +1 to include first byte */ | 197 if(val) { |
| 198 *val = res; | |
| 199 } | |
| 200 | |
| 201 return (const char*)s + 1; /* +1 to include first byte */ | |
| 159 } | 202 } |
| 160 | 203 |
| 161 /* | 204 /* |
| 162 * Check that a string is valid UTF-8 | 205 * Check that a string is valid UTF-8 |
| 163 * Returns NULL if not | 206 * Returns NULL if not |
| 164 */ | 207 */ |
| 165 const char* check_utf8 (lua_State *L, int idx, size_t *l) { | 208 const char* check_utf8(lua_State* L, int idx, size_t* l) { |
| 166 size_t pos, len; | 209 size_t pos, len; |
| 167 const char *s = luaL_checklstring(L, 1, &len); | 210 const char* s = luaL_checklstring(L, 1, &len); |
| 168 pos = 0; | 211 pos = 0; |
| 169 while (pos <= len) { | 212 |
| 170 const char *s1 = utf8_decode(s + pos, NULL); | 213 while(pos <= len) { |
| 171 if (s1 == NULL) { /* conversion error? */ | 214 const char* s1 = utf8_decode(s + pos, NULL); |
| 215 | |
| 216 if(s1 == NULL) { /* conversion error? */ | |
| 172 return NULL; | 217 return NULL; |
| 173 } | 218 } |
| 219 | |
| 174 pos = s1 - s; | 220 pos = s1 - s; |
| 175 } | 221 } |
| 222 | |
| 176 if(l != NULL) { | 223 if(l != NULL) { |
| 177 *l = len; | 224 *l = len; |
| 178 } | 225 } |
| 226 | |
| 179 return s; | 227 return s; |
| 180 } | 228 } |
| 181 | 229 |
| 182 static int Lutf8_valid(lua_State *L) { | 230 static int Lutf8_valid(lua_State* L) { |
| 183 lua_pushboolean(L, check_utf8(L, 1, NULL) != NULL); | 231 lua_pushboolean(L, check_utf8(L, 1, NULL) != NULL); |
| 184 return 1; | 232 return 1; |
| 185 } | 233 } |
| 186 | 234 |
| 187 static int Lutf8_length(lua_State *L) { | 235 static int Lutf8_length(lua_State* L) { |
| 188 size_t len; | 236 size_t len; |
| 237 | |
| 189 if(!check_utf8(L, 1, &len)) { | 238 if(!check_utf8(L, 1, &len)) { |
| 190 lua_pushnil(L); | 239 lua_pushnil(L); |
| 191 lua_pushliteral(L, "invalid utf8"); | 240 lua_pushliteral(L, "invalid utf8"); |
| 192 return 2; | 241 return 2; |
| 193 } | 242 } |
| 243 | |
| 194 lua_pushinteger(L, len); | 244 lua_pushinteger(L, len); |
| 195 return 1; | 245 return 1; |
| 196 } | 246 } |
| 197 | 247 |
| 198 static const luaL_Reg Reg_utf8[] = | 248 static const luaL_Reg Reg_utf8[] = { |
| 199 { | |
| 200 { "valid", Lutf8_valid }, | 249 { "valid", Lutf8_valid }, |
| 201 { "length", Lutf8_length }, | 250 { "length", Lutf8_length }, |
| 202 { NULL, NULL } | 251 { NULL, NULL } |
| 203 }; | 252 }; |
| 204 | 253 |
| 208 | 257 |
| 209 #include <unicode/usprep.h> | 258 #include <unicode/usprep.h> |
| 210 #include <unicode/ustring.h> | 259 #include <unicode/ustring.h> |
| 211 #include <unicode/utrace.h> | 260 #include <unicode/utrace.h> |
| 212 | 261 |
| 213 static int icu_stringprep_prep(lua_State *L, const UStringPrepProfile *profile) | 262 static int icu_stringprep_prep(lua_State* L, const UStringPrepProfile* profile) { |
| 214 { | |
| 215 size_t input_len; | 263 size_t input_len; |
| 216 int32_t unprepped_len, prepped_len, output_len; | 264 int32_t unprepped_len, prepped_len, output_len; |
| 217 const char *input; | 265 const char* input; |
| 218 char output[1024]; | 266 char output[1024]; |
| 219 | 267 |
| 220 UChar unprepped[1024]; /* Temporary unicode buffer (1024 characters) */ | 268 UChar unprepped[1024]; /* Temporary unicode buffer (1024 characters) */ |
| 221 UChar prepped[1024]; | 269 UChar prepped[1024]; |
| 222 | 270 |
| 223 UErrorCode err = U_ZERO_ERROR; | 271 UErrorCode err = U_ZERO_ERROR; |
| 224 | 272 |
| 225 if(!lua_isstring(L, 1)) { | 273 if(!lua_isstring(L, 1)) { |
| 226 lua_pushnil(L); | 274 lua_pushnil(L); |
| 227 return 1; | 275 return 1; |
| 228 } | 276 } |
| 277 | |
| 229 input = lua_tolstring(L, 1, &input_len); | 278 input = lua_tolstring(L, 1, &input_len); |
| 230 if (input_len >= 1024) { | 279 |
| 231 lua_pushnil(L); | 280 if(input_len >= 1024) { |
| 232 return 1; | 281 lua_pushnil(L); |
| 233 } | 282 return 1; |
| 283 } | |
| 284 | |
| 234 u_strFromUTF8(unprepped, 1024, &unprepped_len, input, input_len, &err); | 285 u_strFromUTF8(unprepped, 1024, &unprepped_len, input, input_len, &err); |
| 235 if (U_FAILURE(err)) { | 286 |
| 236 lua_pushnil(L); | 287 if(U_FAILURE(err)) { |
| 237 return 1; | 288 lua_pushnil(L); |
| 238 } | 289 return 1; |
| 290 } | |
| 291 | |
| 239 prepped_len = usprep_prepare(profile, unprepped, unprepped_len, prepped, 1024, 0, NULL, &err); | 292 prepped_len = usprep_prepare(profile, unprepped, unprepped_len, prepped, 1024, 0, NULL, &err); |
| 240 if (U_FAILURE(err)) { | 293 |
| 294 if(U_FAILURE(err)) { | |
| 241 lua_pushnil(L); | 295 lua_pushnil(L); |
| 242 return 1; | 296 return 1; |
| 243 } else { | 297 } else { |
| 244 u_strToUTF8(output, 1024, &output_len, prepped, prepped_len, &err); | 298 u_strToUTF8(output, 1024, &output_len, prepped, prepped_len, &err); |
| 245 if (U_SUCCESS(err) && output_len < 1024) | 299 |
| 300 if(U_SUCCESS(err) && output_len < 1024) { | |
| 246 lua_pushlstring(L, output, output_len); | 301 lua_pushlstring(L, output, output_len); |
| 247 else | 302 } else { |
| 248 lua_pushnil(L); | 303 lua_pushnil(L); |
| 249 return 1; | 304 } |
| 250 } | 305 |
| 251 } | 306 return 1; |
| 252 | 307 } |
| 253 UStringPrepProfile *icu_nameprep; | 308 } |
| 254 UStringPrepProfile *icu_nodeprep; | 309 |
| 255 UStringPrepProfile *icu_resourceprep; | 310 UStringPrepProfile* icu_nameprep; |
| 256 UStringPrepProfile *icu_saslprep; | 311 UStringPrepProfile* icu_nodeprep; |
| 312 UStringPrepProfile* icu_resourceprep; | |
| 313 UStringPrepProfile* icu_saslprep; | |
| 257 | 314 |
| 258 /* initialize global ICU stringprep profiles */ | 315 /* initialize global ICU stringprep profiles */ |
| 259 void init_icu() | 316 void init_icu() { |
| 260 { | |
| 261 UErrorCode err = U_ZERO_ERROR; | 317 UErrorCode err = U_ZERO_ERROR; |
| 262 utrace_setLevel(UTRACE_VERBOSE); | 318 utrace_setLevel(UTRACE_VERBOSE); |
| 263 icu_nameprep = usprep_openByType(USPREP_RFC3491_NAMEPREP, &err); | 319 icu_nameprep = usprep_openByType(USPREP_RFC3491_NAMEPREP, &err); |
| 264 icu_nodeprep = usprep_openByType(USPREP_RFC3920_NODEPREP, &err); | 320 icu_nodeprep = usprep_openByType(USPREP_RFC3920_NODEPREP, &err); |
| 265 icu_resourceprep = usprep_openByType(USPREP_RFC3920_RESOURCEPREP, &err); | 321 icu_resourceprep = usprep_openByType(USPREP_RFC3920_RESOURCEPREP, &err); |
| 266 icu_saslprep = usprep_openByType(USPREP_RFC4013_SASLPREP, &err); | 322 icu_saslprep = usprep_openByType(USPREP_RFC4013_SASLPREP, &err); |
| 267 if (U_FAILURE(err)) fprintf(stderr, "[c] util.encodings: error: %s\n", u_errorName((UErrorCode)err)); | 323 |
| 324 if(U_FAILURE(err)) { | |
| 325 fprintf(stderr, "[c] util.encodings: error: %s\n", u_errorName((UErrorCode)err)); | |
| 326 } | |
| 268 } | 327 } |
| 269 | 328 |
| 270 #define MAKE_PREP_FUNC(myFunc, prep) \ | 329 #define MAKE_PREP_FUNC(myFunc, prep) \ |
| 271 static int myFunc(lua_State *L) { return icu_stringprep_prep(L, prep); } | 330 static int myFunc(lua_State *L) { return icu_stringprep_prep(L, prep); } |
| 272 | 331 |
| 273 MAKE_PREP_FUNC(Lstringprep_nameprep, icu_nameprep) /** stringprep.nameprep(s) */ | 332 MAKE_PREP_FUNC(Lstringprep_nameprep, icu_nameprep) /** stringprep.nameprep(s) */ |
| 274 MAKE_PREP_FUNC(Lstringprep_nodeprep, icu_nodeprep) /** stringprep.nodeprep(s) */ | 333 MAKE_PREP_FUNC(Lstringprep_nodeprep, icu_nodeprep) /** stringprep.nodeprep(s) */ |
| 275 MAKE_PREP_FUNC(Lstringprep_resourceprep, icu_resourceprep) /** stringprep.resourceprep(s) */ | 334 MAKE_PREP_FUNC(Lstringprep_resourceprep, icu_resourceprep) /** stringprep.resourceprep(s) */ |
| 276 MAKE_PREP_FUNC(Lstringprep_saslprep, icu_saslprep) /** stringprep.saslprep(s) */ | 335 MAKE_PREP_FUNC(Lstringprep_saslprep, icu_saslprep) /** stringprep.saslprep(s) */ |
| 277 | 336 |
| 278 static const luaL_Reg Reg_stringprep[] = | 337 static const luaL_Reg Reg_stringprep[] = { |
| 279 { | |
| 280 { "nameprep", Lstringprep_nameprep }, | 338 { "nameprep", Lstringprep_nameprep }, |
| 281 { "nodeprep", Lstringprep_nodeprep }, | 339 { "nodeprep", Lstringprep_nodeprep }, |
| 282 { "resourceprep", Lstringprep_resourceprep }, | 340 { "resourceprep", Lstringprep_resourceprep }, |
| 283 { "saslprep", Lstringprep_saslprep }, | 341 { "saslprep", Lstringprep_saslprep }, |
| 284 { NULL, NULL } | 342 { NULL, NULL } |
| 287 | 345 |
| 288 /****************** libidn ********************/ | 346 /****************** libidn ********************/ |
| 289 | 347 |
| 290 #include <stringprep.h> | 348 #include <stringprep.h> |
| 291 | 349 |
| 292 static int stringprep_prep(lua_State *L, const Stringprep_profile *profile) | 350 static int stringprep_prep(lua_State* L, const Stringprep_profile* profile) { |
| 293 { | |
| 294 size_t len; | 351 size_t len; |
| 295 const char *s; | 352 const char* s; |
| 296 char string[1024]; | 353 char string[1024]; |
| 297 int ret; | 354 int ret; |
| 355 | |
| 298 if(!lua_isstring(L, 1)) { | 356 if(!lua_isstring(L, 1)) { |
| 299 lua_pushnil(L); | 357 lua_pushnil(L); |
| 300 return 1; | 358 return 1; |
| 301 } | 359 } |
| 360 | |
| 302 s = check_utf8(L, 1, &len); | 361 s = check_utf8(L, 1, &len); |
| 303 if (s == NULL || len >= 1024 || len != strlen(s)) { | 362 |
| 363 if(s == NULL || len >= 1024 || len != strlen(s)) { | |
| 304 lua_pushnil(L); | 364 lua_pushnil(L); |
| 305 return 1; /* TODO return error message */ | 365 return 1; /* TODO return error message */ |
| 306 } | 366 } |
| 367 | |
| 307 strcpy(string, s); | 368 strcpy(string, s); |
| 308 ret = stringprep(string, 1024, (Stringprep_profile_flags)0, profile); | 369 ret = stringprep(string, 1024, (Stringprep_profile_flags)0, profile); |
| 309 if (ret == STRINGPREP_OK) { | 370 |
| 371 if(ret == STRINGPREP_OK) { | |
| 310 lua_pushstring(L, string); | 372 lua_pushstring(L, string); |
| 311 return 1; | 373 return 1; |
| 312 } else { | 374 } else { |
| 313 lua_pushnil(L); | 375 lua_pushnil(L); |
| 314 return 1; /* TODO return error message */ | 376 return 1; /* TODO return error message */ |
| 321 MAKE_PREP_FUNC(Lstringprep_nameprep, stringprep_nameprep) /** stringprep.nameprep(s) */ | 383 MAKE_PREP_FUNC(Lstringprep_nameprep, stringprep_nameprep) /** stringprep.nameprep(s) */ |
| 322 MAKE_PREP_FUNC(Lstringprep_nodeprep, stringprep_xmpp_nodeprep) /** stringprep.nodeprep(s) */ | 384 MAKE_PREP_FUNC(Lstringprep_nodeprep, stringprep_xmpp_nodeprep) /** stringprep.nodeprep(s) */ |
| 323 MAKE_PREP_FUNC(Lstringprep_resourceprep, stringprep_xmpp_resourceprep) /** stringprep.resourceprep(s) */ | 385 MAKE_PREP_FUNC(Lstringprep_resourceprep, stringprep_xmpp_resourceprep) /** stringprep.resourceprep(s) */ |
| 324 MAKE_PREP_FUNC(Lstringprep_saslprep, stringprep_saslprep) /** stringprep.saslprep(s) */ | 386 MAKE_PREP_FUNC(Lstringprep_saslprep, stringprep_saslprep) /** stringprep.saslprep(s) */ |
| 325 | 387 |
| 326 static const luaL_Reg Reg_stringprep[] = | 388 static const luaL_Reg Reg_stringprep[] = { |
| 327 { | |
| 328 { "nameprep", Lstringprep_nameprep }, | 389 { "nameprep", Lstringprep_nameprep }, |
| 329 { "nodeprep", Lstringprep_nodeprep }, | 390 { "nodeprep", Lstringprep_nodeprep }, |
| 330 { "resourceprep", Lstringprep_resourceprep }, | 391 { "resourceprep", Lstringprep_resourceprep }, |
| 331 { "saslprep", Lstringprep_saslprep }, | 392 { "saslprep", Lstringprep_saslprep }, |
| 332 { NULL, NULL } | 393 { NULL, NULL } |
| 336 /***************** IDNA *****************/ | 397 /***************** IDNA *****************/ |
| 337 #ifdef USE_STRINGPREP_ICU | 398 #ifdef USE_STRINGPREP_ICU |
| 338 #include <unicode/ustdio.h> | 399 #include <unicode/ustdio.h> |
| 339 #include <unicode/uidna.h> | 400 #include <unicode/uidna.h> |
| 340 /* IDNA2003 or IDNA2008 ? ? ? */ | 401 /* IDNA2003 or IDNA2008 ? ? ? */ |
| 341 static int Lidna_to_ascii(lua_State *L) /** idna.to_ascii(s) */ | 402 static int Lidna_to_ascii(lua_State* L) { /** idna.to_ascii(s) */ |
| 342 { | |
| 343 size_t len; | 403 size_t len; |
| 344 int32_t ulen, dest_len, output_len; | 404 int32_t ulen, dest_len, output_len; |
| 345 const char *s = luaL_checklstring(L, 1, &len); | 405 const char* s = luaL_checklstring(L, 1, &len); |
| 346 UChar ustr[1024]; | 406 UChar ustr[1024]; |
| 347 UErrorCode err = U_ZERO_ERROR; | 407 UErrorCode err = U_ZERO_ERROR; |
| 348 UChar dest[1024]; | 408 UChar dest[1024]; |
| 349 char output[1024]; | 409 char output[1024]; |
| 350 | 410 |
| 351 u_strFromUTF8(ustr, 1024, &ulen, s, len, &err); | 411 u_strFromUTF8(ustr, 1024, &ulen, s, len, &err); |
| 352 if (U_FAILURE(err)) { | 412 |
| 413 if(U_FAILURE(err)) { | |
| 353 lua_pushnil(L); | 414 lua_pushnil(L); |
| 354 return 1; | 415 return 1; |
| 355 } | 416 } |
| 356 | 417 |
| 357 dest_len = uidna_IDNToASCII(ustr, ulen, dest, 1024, UIDNA_USE_STD3_RULES, NULL, &err); | 418 dest_len = uidna_IDNToASCII(ustr, ulen, dest, 1024, UIDNA_USE_STD3_RULES, NULL, &err); |
| 358 if (U_FAILURE(err)) { | 419 |
| 420 if(U_FAILURE(err)) { | |
| 359 lua_pushnil(L); | 421 lua_pushnil(L); |
| 360 return 1; | 422 return 1; |
| 361 } else { | 423 } else { |
| 362 u_strToUTF8(output, 1024, &output_len, dest, dest_len, &err); | 424 u_strToUTF8(output, 1024, &output_len, dest, dest_len, &err); |
| 363 if (U_SUCCESS(err) && output_len < 1024) | 425 |
| 426 if(U_SUCCESS(err) && output_len < 1024) { | |
| 364 lua_pushlstring(L, output, output_len); | 427 lua_pushlstring(L, output, output_len); |
| 365 else | 428 } else { |
| 366 lua_pushnil(L); | 429 lua_pushnil(L); |
| 367 return 1; | 430 } |
| 368 } | 431 |
| 369 } | 432 return 1; |
| 370 | 433 } |
| 371 static int Lidna_to_unicode(lua_State *L) /** idna.to_unicode(s) */ | 434 } |
| 372 { | 435 |
| 436 static int Lidna_to_unicode(lua_State* L) { /** idna.to_unicode(s) */ | |
| 373 size_t len; | 437 size_t len; |
| 374 int32_t ulen, dest_len, output_len; | 438 int32_t ulen, dest_len, output_len; |
| 375 const char *s = luaL_checklstring(L, 1, &len); | 439 const char* s = luaL_checklstring(L, 1, &len); |
| 376 UChar ustr[1024]; | 440 UChar ustr[1024]; |
| 377 UErrorCode err = U_ZERO_ERROR; | 441 UErrorCode err = U_ZERO_ERROR; |
| 378 UChar dest[1024]; | 442 UChar dest[1024]; |
| 379 char output[1024]; | 443 char output[1024]; |
| 380 | 444 |
| 381 u_strFromUTF8(ustr, 1024, &ulen, s, len, &err); | 445 u_strFromUTF8(ustr, 1024, &ulen, s, len, &err); |
| 382 if (U_FAILURE(err)) { | 446 |
| 447 if(U_FAILURE(err)) { | |
| 383 lua_pushnil(L); | 448 lua_pushnil(L); |
| 384 return 1; | 449 return 1; |
| 385 } | 450 } |
| 386 | 451 |
| 387 dest_len = uidna_IDNToUnicode(ustr, ulen, dest, 1024, UIDNA_USE_STD3_RULES, NULL, &err); | 452 dest_len = uidna_IDNToUnicode(ustr, ulen, dest, 1024, UIDNA_USE_STD3_RULES, NULL, &err); |
| 388 if (U_FAILURE(err)) { | 453 |
| 454 if(U_FAILURE(err)) { | |
| 389 lua_pushnil(L); | 455 lua_pushnil(L); |
| 390 return 1; | 456 return 1; |
| 391 } else { | 457 } else { |
| 392 u_strToUTF8(output, 1024, &output_len, dest, dest_len, &err); | 458 u_strToUTF8(output, 1024, &output_len, dest, dest_len, &err); |
| 393 if (U_SUCCESS(err) && output_len < 1024) | 459 |
| 460 if(U_SUCCESS(err) && output_len < 1024) { | |
| 394 lua_pushlstring(L, output, output_len); | 461 lua_pushlstring(L, output, output_len); |
| 395 else | 462 } else { |
| 396 lua_pushnil(L); | 463 lua_pushnil(L); |
| 464 } | |
| 465 | |
| 397 return 1; | 466 return 1; |
| 398 } | 467 } |
| 399 } | 468 } |
| 400 | 469 |
| 401 #else /* USE_STRINGPREP_ICU */ | 470 #else /* USE_STRINGPREP_ICU */ |
| 402 /****************** libidn ********************/ | 471 /****************** libidn ********************/ |
| 403 | 472 |
| 404 #include <idna.h> | 473 #include <idna.h> |
| 405 #include <idn-free.h> | 474 #include <idn-free.h> |
| 406 | 475 |
| 407 static int Lidna_to_ascii(lua_State *L) /** idna.to_ascii(s) */ | 476 static int Lidna_to_ascii(lua_State* L) { /** idna.to_ascii(s) */ |
| 408 { | |
| 409 size_t len; | 477 size_t len; |
| 410 const char *s = check_utf8(L, 1, &len); | 478 const char* s = check_utf8(L, 1, &len); |
| 411 if (s == NULL || len != strlen(s)) { | 479 |
| 480 if(s == NULL || len != strlen(s)) { | |
| 412 lua_pushnil(L); | 481 lua_pushnil(L); |
| 413 return 1; /* TODO return error message */ | 482 return 1; /* TODO return error message */ |
| 414 } | 483 } |
| 484 | |
| 415 char* output = NULL; | 485 char* output = NULL; |
| 416 int ret = idna_to_ascii_8z(s, &output, IDNA_USE_STD3_ASCII_RULES); | 486 int ret = idna_to_ascii_8z(s, &output, IDNA_USE_STD3_ASCII_RULES); |
| 417 if (ret == IDNA_SUCCESS) { | 487 |
| 488 if(ret == IDNA_SUCCESS) { | |
| 418 lua_pushstring(L, output); | 489 lua_pushstring(L, output); |
| 419 idn_free(output); | 490 idn_free(output); |
| 420 return 1; | 491 return 1; |
| 421 } else { | 492 } else { |
| 422 lua_pushnil(L); | 493 lua_pushnil(L); |
| 423 idn_free(output); | 494 idn_free(output); |
| 424 return 1; /* TODO return error message */ | 495 return 1; /* TODO return error message */ |
| 425 } | 496 } |
| 426 } | 497 } |
| 427 | 498 |
| 428 static int Lidna_to_unicode(lua_State *L) /** idna.to_unicode(s) */ | 499 static int Lidna_to_unicode(lua_State* L) { /** idna.to_unicode(s) */ |
| 429 { | |
| 430 size_t len; | 500 size_t len; |
| 431 const char *s = luaL_checklstring(L, 1, &len); | 501 const char* s = luaL_checklstring(L, 1, &len); |
| 432 char* output = NULL; | 502 char* output = NULL; |
| 433 int ret = idna_to_unicode_8z8z(s, &output, 0); | 503 int ret = idna_to_unicode_8z8z(s, &output, 0); |
| 434 if (ret == IDNA_SUCCESS) { | 504 |
| 505 if(ret == IDNA_SUCCESS) { | |
| 435 lua_pushstring(L, output); | 506 lua_pushstring(L, output); |
| 436 idn_free(output); | 507 idn_free(output); |
| 437 return 1; | 508 return 1; |
| 438 } else { | 509 } else { |
| 439 lua_pushnil(L); | 510 lua_pushnil(L); |
| 441 return 1; /* TODO return error message */ | 512 return 1; /* TODO return error message */ |
| 442 } | 513 } |
| 443 } | 514 } |
| 444 #endif | 515 #endif |
| 445 | 516 |
| 446 static const luaL_Reg Reg_idna[] = | 517 static const luaL_Reg Reg_idna[] = { |
| 447 { | |
| 448 { "to_ascii", Lidna_to_ascii }, | 518 { "to_ascii", Lidna_to_ascii }, |
| 449 { "to_unicode", Lidna_to_unicode }, | 519 { "to_unicode", Lidna_to_unicode }, |
| 450 { NULL, NULL } | 520 { NULL, NULL } |
| 451 }; | 521 }; |
| 452 | 522 |
| 453 /***************** end *****************/ | 523 /***************** end *****************/ |
| 454 | 524 |
| 455 LUALIB_API int luaopen_util_encodings(lua_State *L) | 525 LUALIB_API int luaopen_util_encodings(lua_State* L) { |
| 456 { | |
| 457 #ifdef USE_STRINGPREP_ICU | 526 #ifdef USE_STRINGPREP_ICU |
| 458 init_icu(); | 527 init_icu(); |
| 459 #endif | 528 #endif |
| 460 lua_newtable(L); | 529 lua_newtable(L); |
| 461 | 530 |