From 72d1549e8ba39a5939b7df8c4bc7beba7f7f1a18 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 21 Nov 2012 23:26:30 +0000 Subject: [PATCH] libs/lmo: canonize key strings before hashing them, fixes missing translations for original strings with line breaks or white spaces embedded --- libs/lmo/src/lmo_lualib.c | 41 ++++++++++++++++++++++++++++++++++----- libs/lmo/src/lmo_lualib.h | 3 ++- 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 59d88a15eb..ade8e01f72 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 + * Copyright (C) 2009-2012 Jo-Philipp Wich * * 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 6435117334..887889d045 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 + * Copyright (C) 2009-2012 Jo-Philipp Wich * * 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 #include #include +#include #include "lmo.h" diff --git a/libs/lmo/src/lmo_po2lmo.c b/libs/lmo/src/lmo_po2lmo.c index 380f18dd65..f6f3994232 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] != '"' ) -- 2.30.2