libs/lmo: canonize key strings before hashing them, fixes missing translations for...
authorJo-Philipp Wich <jow@openwrt.org>
Wed, 21 Nov 2012 23:26:30 +0000 (23:26 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Wed, 21 Nov 2012 23:26:30 +0000 (23:26 +0000)
libs/lmo/src/lmo_lualib.c
libs/lmo/src/lmo_lualib.h
libs/lmo/src/lmo_po2lmo.c

index 59d88a1..ade8e01 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lmo - Lua Machine Objects - Lua binding
  *
 /*
  * 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.
  *
  *  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;
 }
 
        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) {
 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;
 }
        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);
 
 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);
 }
 
        return _lmo_lookup(L, *ar, hash);
 }
 
index 6435117..887889d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lmo - Lua Machine Objects - Lua library header
  *
 /*
  * 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.
  *
  *  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 <lua.h>
 #include <lualib.h>
 #include <lauxlib.h>
+#include <ctype.h>
 
 #include "lmo.h"
 
 
 #include "lmo.h"
 
index 380f18d..f6f3994 100644 (file)
@@ -52,12 +52,19 @@ static int extract_string(const char *src, char *dest, int len)
                {
                        if( esc == 1 )
                        {
                {
                        if( esc == 1 )
                        {
+                               switch (src[pos])
+                               {
+                               case '"':
+                               case '\\':
+                                       off++;
+                                       break;
+                               }
                                dest[pos-off] = src[pos];
                                esc = 0;
                        }
                        else if( src[pos] == '\\' )
                        {
                                dest[pos-off] = src[pos];
                                esc = 0;
                        }
                        else if( src[pos] == '\\' )
                        {
-                               off++;
+                               dest[pos-off] = src[pos];
                                esc = 1;
                        }
                        else if( src[pos] != '"' )
                                esc = 1;
                        }
                        else if( src[pos] != '"' )