diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2012-11-21 23:26:30 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2012-11-21 23:26:30 +0000 |
commit | 72d1549e8ba39a5939b7df8c4bc7beba7f7f1a18 (patch) | |
tree | f290f34f97684c4c699da0fcca2e60e8a1533e43 | |
parent | 838c82fa9ea254c754f75f731c7698c82fa236e4 (diff) |
libs/lmo: canonize key strings before hashing them, fixes missing translations for original strings with line breaks or white spaces embedded
-rw-r--r-- | libs/lmo/src/lmo_lualib.c | 41 | ||||
-rw-r--r-- | libs/lmo/src/lmo_lualib.h | 3 | ||||
-rw-r--r-- | libs/lmo/src/lmo_po2lmo.c | 9 |
3 files changed, 46 insertions, 7 deletions
diff --git a/libs/lmo/src/lmo_lualib.c b/libs/lmo/src/lmo_lualib.c index 59d88a15e..ade8e01f7 100644 --- a/libs/lmo/src/lmo_lualib.c +++ b/libs/lmo/src/lmo_lualib.c @@ -1,7 +1,7 @@ /* * lmo - Lua Machine Objects - Lua binding * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> + * Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,9 +46,41 @@ static int lmo_L_open(lua_State *L) { return 2; } +static uint32_t _lmo_hash_string(lua_State *L, int n) { + size_t len; + const char *str = luaL_checklstring(L, n, &len); + char res[4096]; + char *ptr, prev; + + if (!str || len >= sizeof(res)) + return 0; + + while (*str && isspace(*str)) + str++; + + for (prev = 0, ptr = res; *str; prev = *str, str++) + { + if (isspace(*str)) + { + if (isspace(prev)) + continue; + + *ptr++ = ' '; + } + else + { + *ptr++ = *str; + } + } + + while ((ptr > res) && isspace(*ptr)) + ptr--; + + return sfh_hash(res, ptr - res); +} + static int lmo_L_hash(lua_State *L) { - const char *data = luaL_checkstring(L, 1); - uint32_t hash = sfh_hash(data, strlen(data)); + uint32_t hash = _lmo_hash_string(L, 1); lua_pushinteger(L, (lua_Integer)hash); return 1; } @@ -104,8 +136,7 @@ static int lmo_L_get(lua_State *L) { static int lmo_L_lookup(lua_State *L) { lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); - const char *key = luaL_checkstring(L, 2); - uint32_t hash = sfh_hash(key, strlen(key)); + uint32_t hash = _lmo_hash_string(L, 2); return _lmo_lookup(L, *ar, hash); } diff --git a/libs/lmo/src/lmo_lualib.h b/libs/lmo/src/lmo_lualib.h index 643511733..887889d04 100644 --- a/libs/lmo/src/lmo_lualib.h +++ b/libs/lmo/src/lmo_lualib.h @@ -1,7 +1,7 @@ /* * lmo - Lua Machine Objects - Lua library header * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> + * Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include <lua.h> #include <lualib.h> #include <lauxlib.h> +#include <ctype.h> #include "lmo.h" diff --git a/libs/lmo/src/lmo_po2lmo.c b/libs/lmo/src/lmo_po2lmo.c index 380f18dd6..f6f399423 100644 --- a/libs/lmo/src/lmo_po2lmo.c +++ b/libs/lmo/src/lmo_po2lmo.c @@ -52,12 +52,19 @@ static int extract_string(const char *src, char *dest, int len) { if( esc == 1 ) { + switch (src[pos]) + { + case '"': + case '\\': + off++; + break; + } dest[pos-off] = src[pos]; esc = 0; } else if( src[pos] == '\\' ) { - off++; + dest[pos-off] = src[pos]; esc = 1; } else if( src[pos] != '"' ) |