diff options
author | Tobias Markmann <tm@ayena.de> | 2010-12-14 15:03:37 +0100 |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2010-12-14 15:03:37 +0100 |
commit | 93b0dcf56a5b0460abeb1f5d542e5a77178f779d (patch) | |
tree | 085dcfa23c53f3e2303430d9940ba85fe140cc55 /util-src | |
parent | d1d5bb6d1c37e09ed16ed65556fc1d072f26cf9c (diff) | |
download | prosody-93b0dcf56a5b0460abeb1f5d542e5a77178f779d.tar.gz prosody-93b0dcf56a5b0460abeb1f5d542e5a77178f779d.zip |
util.encodings: Support for ICU for IDNA operations.
Diffstat (limited to 'util-src')
-rw-r--r-- | util-src/Makefile | 8 | ||||
-rw-r--r-- | util-src/encodings.cpp (renamed from util-src/encodings.c) | 140 |
2 files changed, 143 insertions, 5 deletions
diff --git a/util-src/Makefile b/util-src/Makefile index d28ffe81..008a1934 100644 --- a/util-src/Makefile +++ b/util-src/Makefile @@ -7,10 +7,18 @@ LUA_LIB?=lua$(LUA_SUFFIX) IDN_LIB?=idn OPENSSL_LIB?=crypto CC?=gcc +CXX?=g++ LD?=gcc .SUFFIXES: .c .o .so +encodings.o: + $(CXX) $(CFLAGS) -I$(LUA_INCDIR) -c -o encodings.o encodings.cpp + +encodings.so: encodings.o + MACOSX_DEPLOYMENT_TARGET="10.3"; export MACOSX_DEPLOYMENT_TARGET; + $(CXX) $(LDFLAGS) $(IDNA_LIBS) -o encodings.so encodings.o -lcrypto + .c.o: $(CC) $(CFLAGS) -I$(LUA_INCDIR) -c -o $@ $< diff --git a/util-src/encodings.c b/util-src/encodings.cpp index f2109d0c..da2d10bb 100644 --- a/util-src/encodings.c +++ b/util-src/encodings.cpp @@ -15,14 +15,16 @@ // Newer MSVC compilers deprecate strcpy as unsafe, but we use it in a safe way #define _CRT_SECURE_NO_DEPRECATE +extern "C" { #include <string.h> #include <stdlib.h> - #include "lua.h" #include "lauxlib.h" - +} /***************** BASE64 *****************/ +#define LUALIB_API extern "C" + static const char code[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -118,7 +120,8 @@ static const luaL_Reg Reg_base64[] = }; /***************** STRINGPREP *****************/ - +#ifndef USE_STRINGPREP_ICU +/****************** libidn ********************/ #include <stringprep.h> static int stringprep_prep(lua_State *L, const Stringprep_profile *profile) @@ -164,11 +167,83 @@ static const luaL_Reg Reg_stringprep[] = { NULL, NULL } }; -/***************** IDNA *****************/ +#else +#include <unicode/usprep.h> +//#include <unicode/stringpiece.h> +#include <unicode/unistr.h> +#include <unicode/utrace.h> +static int icu_stringprep_prep(lua_State *L, const UStringPrepProfile *profile) +{ + size_t len; + const char *s; + UnicodeString ustr; + UErrorCode err = U_ZERO_ERROR; + UChar dest[1024]; + char output[1024]; + if(!lua_isstring(L, 1)) { + lua_pushnil(L); + return 1; + } + s = lua_tolstring(L, 1, &len); + if (len >= 1024) { + lua_pushnil(L); + return 1; // TODO return error message + } + ustr = UnicodeString::fromUTF8(s); + len = usprep_prepare(profile, ustr.getBuffer(), ustr.length(), dest, 1024, 0, NULL, &err); + if (U_FAILURE(err)) { + lua_pushnil(L); + return 1; + } else { + CheckedArrayByteSink output_sink(output, 1024); + UnicodeString dest_str(TRUE, dest, len); + dest_str.toUTF8(output_sink); + lua_pushstring(L, output); + return 1; + } +} + +UStringPrepProfile *icu_nameprep; +UStringPrepProfile *icu_nodeprep; +UStringPrepProfile *icu_resourceprep; +UStringPrepProfile *icu_saslprep; + +/* initialize global ICU stringprep profiles */ +void init_icu() +{ + UErrorCode err = U_ZERO_ERROR; + utrace_setLevel(UTRACE_VERBOSE); + icu_nameprep = usprep_openByType(USPREP_RFC3491_NAMEPREP, &err); + icu_nodeprep = usprep_openByType(USPREP_RFC3920_NODEPREP, &err); + icu_resourceprep = usprep_openByType(USPREP_RFC3920_RESOURCEPREP, &err); + icu_saslprep = usprep_openByType(USPREP_RFC4013_SASLPREP, &err); + if (U_FAILURE(err)) fprintf(stderr, "[c] util.encodings: error: %s\n", u_errorName((UErrorCode)err)); +} + +#define MAKE_PREP_FUNC(myFunc, prep) \ +static int myFunc(lua_State *L) { return icu_stringprep_prep(L, prep); } + +MAKE_PREP_FUNC(Lstringprep_nameprep, icu_nameprep) /** stringprep.nameprep(s) */ +MAKE_PREP_FUNC(Lstringprep_nodeprep, icu_nodeprep) /** stringprep.nodeprep(s) */ +MAKE_PREP_FUNC(Lstringprep_resourceprep, icu_resourceprep) /** stringprep.resourceprep(s) */ +MAKE_PREP_FUNC(Lstringprep_saslprep, icu_saslprep) /** stringprep.saslprep(s) */ + +static const luaL_Reg Reg_stringprep[] = +{ + { "nameprep", Lstringprep_nameprep }, + { "nodeprep", Lstringprep_nodeprep }, + { "resourceprep", Lstringprep_resourceprep }, + { "saslprep", Lstringprep_saslprep }, + { NULL, NULL } +}; +#endif + +/***************** IDNA *****************/ +#ifndef USE_STRINGPREP_ICU +/****************** libidn ********************/ #include <idna.h> #include <idn-free.h> - static int Lidna_to_ascii(lua_State *L) /** idna.to_ascii(s) */ { size_t len; @@ -202,6 +277,58 @@ static int Lidna_to_unicode(lua_State *L) /** idna.to_unicode(s) */ return 1; // TODO return error message } } +#else +#include <unicode/ustdio.h> +#include <unicode/uidna.h> +/* IDNA2003 or IDNA2008 ? ? ? */ +static int Lidna_to_ascii(lua_State *L) /** idna.to_ascii(s) */ +{ + size_t len; + int32_t out_len; + const char *s = luaL_checklstring(L, 1, &len); + UnicodeString ustr; + UErrorCode err = U_ZERO_ERROR; + UChar dest[1024]; + char output[1024]; + + ustr = UnicodeString::fromUTF8(s); + out_len = uidna_IDNToASCII(ustr.getBuffer(), ustr.length(), dest, 1024, UIDNA_USE_STD3_RULES, NULL, &err); + if (U_FAILURE(err)) { + lua_pushnil(L); + return 1; + } else { + CheckedArrayByteSink output_sink(output, 1024); + UnicodeString dest_str(TRUE, dest, out_len); + dest_str.toUTF8(output_sink); + lua_pushstring(L, output); + return 1; + } +} + +static int Lidna_to_unicode(lua_State *L) /** idna.to_unicode(s) */ +{ + size_t len; + int32_t out_len; + const char *s = luaL_checklstring(L, 1, &len); + UnicodeString ustr; + UErrorCode err = U_ZERO_ERROR; + UChar dest[1024]; + char output[1024]; + + ustr = UnicodeString::fromUTF8(s); + out_len = uidna_IDNToUnicode(ustr.getBuffer(), ustr.length(), dest, 1024, UIDNA_USE_STD3_RULES, NULL, &err); + if (U_FAILURE(err)) { + lua_pushnil(L); + return 1; + } else { + CheckedArrayByteSink output_sink(output, 1024); + UnicodeString dest_str(TRUE, dest, out_len); + dest_str.toUTF8(output_sink); + lua_pushstring(L, output); + return 1; + } +} +#endif static const luaL_Reg Reg_idna[] = { @@ -219,6 +346,9 @@ static const luaL_Reg Reg[] = LUALIB_API int luaopen_util_encodings(lua_State *L) { +#ifdef USE_STRINGPREP_ICU + init_icu(); +#endif luaL_register(L, "encodings", Reg); lua_pushliteral(L, "base64"); |