]> source.dussan.org Git - rspamd.git/commitdiff
Handle invalid IP addresses.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 29 Mar 2014 23:13:45 +0000 (16:13 -0700)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 3 Apr 2014 10:40:30 +0000 (11:40 +0100)
src/lua/lua_common.h
src/lua/lua_ip.c

index ec5215edf152002e23da4907d8615c1b45c1956f..0dd5349ea8469775aff99b50daabea7c8d17bfca 100644 (file)
@@ -137,6 +137,7 @@ struct rspamd_lua_ip {
                struct in_addr ip4;
        } data;
        int af;
+       gboolean is_valid;
 };
 
 /**
index daf5a03ce0f52c8e8e94986033f08fcb97c98ee1..4706af9ee0fd1a80f1aaa79c6ced48721a5ec6b9 100644 (file)
@@ -32,6 +32,7 @@ LUA_FUNCTION_DEF (ip, inversed_str_octets);
 LUA_FUNCTION_DEF (ip, from_string);
 LUA_FUNCTION_DEF (ip, destroy);
 LUA_FUNCTION_DEF (ip, get_version);
+LUA_FUNCTION_DEF (ip, is_valid);
 
 static const struct luaL_reg    iplib_m[] = {
        LUA_INTERFACE_DEF (ip, to_string),
@@ -40,6 +41,7 @@ static const struct luaL_reg    iplib_m[] = {
        LUA_INTERFACE_DEF (ip, str_octets),
        LUA_INTERFACE_DEF (ip, inversed_str_octets),
        LUA_INTERFACE_DEF (ip, get_version),
+       LUA_INTERFACE_DEF (ip, is_valid),
        {"__tostring", lua_ip_to_string},
        {"__gc", lua_ip_destroy},
        {NULL, NULL}
@@ -67,7 +69,7 @@ lua_ip_to_table (lua_State *L)
        int max, i;
        guint8 *ptr;
 
-       if (ip != NULL) {
+       if (ip != NULL && ip->is_valid) {
                lua_newtable (L);
                if (ip->af == AF_INET) {
                        max = 32 / 8;
@@ -96,7 +98,7 @@ lua_ip_str_octets (lua_State *L)
        guint8 *ptr;
        char numbuf[8];
 
-       if (ip != NULL) {
+       if (ip != NULL && ip->is_valid) {
                lua_newtable (L);
                if (ip->af == AF_INET) {
                        max = 32 / 8;
@@ -136,7 +138,7 @@ lua_ip_inversed_str_octets (lua_State *L)
        guint8 *ptr;
        char numbuf[4];
 
-       if (ip != NULL) {
+       if (ip != NULL && ip->is_valid) {
                lua_newtable (L);
                if (ip->af == AF_INET) {
                        max = 32 / 8;
@@ -175,7 +177,7 @@ lua_ip_to_string (lua_State *L)
        struct rspamd_lua_ip *ip = lua_check_ip (L, 1);
        gchar dst[INET6_ADDRSTRLEN + 1];
 
-       if (ip != NULL) {
+       if (ip != NULL && ip->is_valid) {
                lua_pushstring (L, inet_ntop (ip->af, &ip->data, dst, sizeof (dst)));
        }
        else {
@@ -196,14 +198,14 @@ lua_ip_from_string (lua_State *L)
                ip = g_slice_alloc (sizeof (struct rspamd_lua_ip));
                if (inet_pton (AF_INET, ip_str, &ip->data.ip4) == 1) {
                        ip->af = AF_INET;
+                       ip->is_valid = TRUE;
                }
                else if (inet_pton (AF_INET6, ip_str, &ip->data.ip6) == 1) {
                        ip->af = AF_INET6;
+                       ip->is_valid = TRUE;
                }
                else {
-                       g_slice_free1 (sizeof (struct rspamd_lua_ip), ip);
-                       lua_pushnil (L);
-                       return 1;
+                       ip->is_valid = FALSE;
                }
                pip = lua_newuserdata (L, sizeof (struct rspamd_lua_ip *));
                lua_setclass (L, "rspamd{ip}", -1);
@@ -222,7 +224,7 @@ lua_ip_to_number (lua_State *L)
        struct rspamd_lua_ip *ip = lua_check_ip (L, 1);
        guint32 dst[4], i;
 
-       if (ip != NULL) {
+       if (ip != NULL && ip->is_valid) {
                if (ip->af == AF_INET) {
                        /* One integer in host byte order */
                        lua_pushinteger (L, ntohl (ip->data.ip4.s_addr));
@@ -255,6 +257,7 @@ lua_ip_from_number (lua_State *L)
                ip = g_slice_alloc (sizeof (struct rspamd_lua_ip));
                src[0] = lua_tointeger (L, 1);
                ip->af = AF_INET;
+               ip->is_valid = TRUE;
                ip->data.ip4.s_addr = htonl (src[0]);
                pip = lua_newuserdata (L, sizeof (struct rspamd_lua_ip *));
                lua_setclass (L, "rspamd{ip}", -1);
@@ -268,6 +271,7 @@ lua_ip_from_number (lua_State *L)
                G_STATIC_ASSERT (sizeof (ip->data) >= sizeof (src));
                ip = g_slice_alloc (sizeof (struct rspamd_lua_ip));
                ip->af = AF_INET6;
+               ip->is_valid = TRUE;
                memcpy (&ip->data, src, sizeof (src));
                pip = lua_newuserdata (L, sizeof (struct rspamd_lua_ip *));
                lua_setclass (L, "rspamd{ip}", -1);
@@ -297,7 +301,7 @@ lua_ip_get_version (lua_State *L)
 {
        struct rspamd_lua_ip *ip = lua_check_ip (L, 1);
 
-       if (ip) {
+       if (ip && ip->is_valid) {
                lua_pushnumber (L, ip->af == AF_INET6 ? 6 : 4);
        }
        else {
@@ -307,17 +311,33 @@ lua_ip_get_version (lua_State *L)
        return 1;
 }
 
+static gint
+lua_ip_is_valid (lua_State *L)
+{
+       struct rspamd_lua_ip *ip = lua_check_ip (L, 1);
+
+       if (ip) {
+               lua_pushboolean (L, ip->is_valid);
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
 void
 lua_ip_push (lua_State *L, int af, gpointer data)
 {
        struct rspamd_lua_ip *ip, **pip;
 
+       ip = g_slice_alloc (sizeof (struct rspamd_lua_ip));
+
        if (!rspamd_ip_is_valid (data, af)) {
-               lua_pushnil (L);
+               ip->is_valid = FALSE;
        }
        else {
-               ip = g_slice_alloc (sizeof (struct rspamd_lua_ip));
-
+               ip->is_valid = TRUE;
                ip->af = af;
                if (af == AF_INET6) {
                        memcpy (&ip->data, data, sizeof (struct in6_addr));
@@ -325,10 +345,11 @@ lua_ip_push (lua_State *L, int af, gpointer data)
                else {
                        memcpy (&ip->data, data, sizeof (struct in_addr));
                }
-               pip = lua_newuserdata (L, sizeof (struct rspamd_lua_ip *));
-               lua_setclass (L, "rspamd{ip}", -1);
-               *pip = ip;
+
        }
+       pip = lua_newuserdata (L, sizeof (struct rspamd_lua_ip *));
+       lua_setclass (L, "rspamd{ip}", -1);
+       *pip = ip;
 }
 
 void
@@ -341,6 +362,7 @@ lua_ip_push_fromstring (lua_State *L, const gchar *ip_str)
        }
        else {
                ip = g_slice_alloc (sizeof (struct rspamd_lua_ip));
+               ip->is_valid = TRUE;
                if (inet_pton (AF_INET, ip_str, &ip->data.ip4) == 1) {
                        ip->af = AF_INET;
                }
@@ -348,9 +370,7 @@ lua_ip_push_fromstring (lua_State *L, const gchar *ip_str)
                        ip->af = AF_INET6;
                }
                else {
-                       g_slice_free1 (sizeof (struct rspamd_lua_ip), ip);
-                       lua_pushnil (L);
-                       return;
+                       ip->is_valid = FALSE;
                }
 
                pip = lua_newuserdata (L, sizeof (struct rspamd_lua_ip *));