]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Lua_http: Preallocate body when parsing tables
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 28 Oct 2019 11:01:19 +0000 (11:01 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 28 Oct 2019 11:01:19 +0000 (11:01 +0000)
src/lua/lua_http.c

index d73bd7281803bf7ac2174a9ef55c8ecdc9e35b6c..a980403705c4d0bb21d3fdf05e27a5f9b5db540b 100644 (file)
@@ -749,25 +749,27 @@ lua_http_request (lua_State *L)
                        }
                }
                else if (lua_type (L, -1) == LUA_TTABLE) {
-                       body = rspamd_fstring_new ();
+                       gsize total_len = 0, nelts = rspamd_lua_table_size (L, -1);
+
+                       /* Calculate length and check types */
+                       for (gsize i = 0; i < nelts; i ++) {
+                               lua_rawgeti (L, -1, i + 1);
 
-                       for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
                                if (lua_type (L, -1) == LUA_TSTRING) {
-                                       lua_body = lua_tolstring (L, -1, &bodylen);
-                                       body = rspamd_fstring_append (body, lua_body, bodylen);
+#if LUA_VERSION_NUM >= 502
+                                       total_len += lua_rawlen (L, -1);
+#else
+                                       total_len += lua_objlen (L, -1);
+#endif
                                }
                                else if (lua_type (L, -1) == LUA_TUSERDATA) {
                                        t = lua_check_text (L, -1);
 
                                        if (t) {
-                                               body = rspamd_fstring_append (body, t->start, t->len);
+                                               total_len += t->len;
                                        }
                                        else {
                                                rspamd_http_message_unref (msg);
-                                               if (body) {
-                                                       rspamd_fstring_free (body);
-                                               }
-
                                                if (mime_type) {
                                                        g_free (mime_type);
                                                }
@@ -778,13 +780,44 @@ lua_http_request (lua_State *L)
                                }
                                else {
                                        rspamd_http_message_unref (msg);
-                                       if (body) {
-                                               rspamd_fstring_free (body);
+                                       if (mime_type) {
+                                               g_free (mime_type);
                                        }
 
                                        return luaL_error (L, "invalid body argument type: %s",
                                                        lua_typename (L, lua_type (L, -1)));
                                }
+
+                               lua_pop (L, 1);
+                       }
+
+                       /* Preallocate body */
+                       if (total_len > 0) {
+                               body = rspamd_fstring_sized_new (total_len);
+                       }
+                       else {
+                               rspamd_http_message_unref (msg);
+                               if (mime_type) {
+                                       g_free (mime_type);
+                               }
+
+                               return luaL_error (L, "empty body specified");
+                       }
+
+                       /* Fill elements */
+                       for (gsize i = 0; i < nelts; i ++) {
+                               lua_rawgeti (L, -1, i + 1);
+
+                               if (lua_type (L, -1) == LUA_TSTRING) {
+                                       lua_body = lua_tolstring (L, -1, &bodylen);
+                                       body = rspamd_fstring_append (body, lua_body, bodylen);
+                               }
+                               else {
+                                       t = lua_check_text (L, -1);
+                                       body = rspamd_fstring_append (body, t->start, t->len);
+                               }
+
+                               lua_pop (L, 1);
                        }
                }
                else if (lua_type (L, -1) != LUA_TNONE && lua_type (L, -1) != LUA_TNIL) {