]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: lua: warn when registering action, conv, sf, cli or applet multiple times
authorThierry Fournier <thierry.fournier@ozon.io>
Sat, 28 Nov 2020 19:41:07 +0000 (20:41 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 2 Dec 2020 08:45:18 +0000 (09:45 +0100)
Lua allows registering multiple sample-fetches, converters, action, cli,
applet/services with the same name. This is absolutely useless since only
the first registration will be used. This patch sends a warning if the case
is encountered.

This pach could be backported until 1.8, with the 3 associated patches:
 - MINOR: actions: Export actions lookup functions
 - MINOR: actions: add a function returning a service pointer from its name
 - MINOR: cli: add a function to look up a CLI service description

src/hlua.c

index 43a9745e453dd743d19950605ff3cd62edd6cf3d..1829e87b6ecade08590982bb58f2e085b12bfa4a 100644 (file)
@@ -6571,6 +6571,8 @@ __LJMP static int hlua_register_converters(lua_State *L)
        int ref;
        int len;
        struct hlua_function *fcn;
+       struct sample_conv *sc;
+       struct buffer *trash;
 
        MAY_LJMP(check_args(L, 2, "register_converters"));
 
@@ -6580,6 +6582,15 @@ __LJMP static int hlua_register_converters(lua_State *L)
        /* Second argument : lua function. */
        ref = MAY_LJMP(hlua_checkfunction(L, 2));
 
+       /* Check if the converter is already registered */
+       trash = get_trash_chunk();
+       chunk_printf(trash, "lua.%s", name);
+       sc = find_sample_conv(trash->area, trash->data);
+       if (sc != NULL) {
+               ha_warning("Trying to register converter 'lua.%s' more than once. "
+                          "This will become a hard error in version 2.5.\n", name);
+       }
+
        /* Allocate and fill the sample fetch keyword struct. */
        sck = calloc(1, sizeof(*sck) + sizeof(struct sample_conv) * 2);
        if (!sck)
@@ -6628,6 +6639,8 @@ __LJMP static int hlua_register_fetches(lua_State *L)
        int len;
        struct sample_fetch_kw_list *sfk;
        struct hlua_function *fcn;
+       struct sample_fetch *sf;
+       struct buffer *trash;
 
        MAY_LJMP(check_args(L, 2, "register_fetches"));
 
@@ -6637,6 +6650,15 @@ __LJMP static int hlua_register_fetches(lua_State *L)
        /* Second argument : lua function. */
        ref = MAY_LJMP(hlua_checkfunction(L, 2));
 
+       /* Check if the sample-fetch is already registered */
+       trash = get_trash_chunk();
+       chunk_printf(trash, "lua.%s", name);
+       sf = find_sample_fetch(trash->area, trash->data);
+       if (sf != NULL) {
+               ha_warning("Trying to register sample-fetch 'lua.%s' more than once. "
+                          "This will become a hard error in version 2.5.\n", name);
+       }
+
        /* Allocate and fill the sample fetch keyword struct. */
        sfk = calloc(1, sizeof(*sfk) + sizeof(struct sample_fetch) * 2);
        if (!sfk)
@@ -7447,6 +7469,8 @@ __LJMP static int hlua_register_action(lua_State *L)
        int len;
        struct hlua_function *fcn;
        int nargs;
+       struct buffer *trash;
+       struct action_kw *akw;
 
        /* Initialise the number of expected arguments at 0. */
        nargs = 0;
@@ -7474,6 +7498,25 @@ __LJMP static int hlua_register_action(lua_State *L)
                if (lua_type(L, -1) != LUA_TSTRING)
                        WILL_LJMP(luaL_error(L, "register_action: second argument must be a table of strings"));
 
+               /* Check if action exists */
+               trash = get_trash_chunk();
+               chunk_printf(trash, "lua.%s", name);
+               if (strcmp(lua_tostring(L, -1), "tcp-req") == 0) {
+                       akw = tcp_req_cont_action(trash->area);
+               } else if (strcmp(lua_tostring(L, -1), "tcp-res") == 0) {
+                       akw = tcp_res_cont_action(trash->area);
+               } else if (strcmp(lua_tostring(L, -1), "http-req") == 0) {
+                       akw = action_http_req_custom(trash->area);
+               } else if (strcmp(lua_tostring(L, -1), "http-res") == 0) {
+                       akw = action_http_res_custom(trash->area);
+               } else {
+                       akw = NULL;
+               }
+               if (akw != NULL) {
+                       ha_warning("Trying to register action 'lua.%s' more than once. "
+                                  "This will become a hard error in version 2.5.\n", name);
+               }
+
                /* Check required environment. Only accepted "http" or "tcp". */
                /* Allocate and fill the sample fetch keyword struct. */
                akl = calloc(1, sizeof(*akl) + sizeof(struct action_kw) * 2);
@@ -7573,6 +7616,8 @@ __LJMP static int hlua_register_service(lua_State *L)
        int ref;
        int len;
        struct hlua_function *fcn;
+       struct buffer *trash;
+       struct action_kw *akw;
 
        MAY_LJMP(check_args(L, 3, "register_service"));
 
@@ -7585,6 +7630,15 @@ __LJMP static int hlua_register_service(lua_State *L)
        /* Third argument : lua function. */
        ref = MAY_LJMP(hlua_checkfunction(L, 3));
 
+       /* Check for service already registered */
+       trash = get_trash_chunk();
+       chunk_printf(trash, "lua.%s", name);
+       akw = service_find(trash->area);
+       if (akw != NULL) {
+               ha_warning("Trying to register service 'lua.%s' more than once. "
+                          "This will become a hard error in version 2.5.\n", name);
+       }
+
        /* Allocate and fill the sample fetch keyword struct. */
        akl = calloc(1, sizeof(*akl) + sizeof(struct action_kw) * 2);
        if (!akl)
@@ -7817,6 +7871,9 @@ __LJMP static int hlua_register_cli(lua_State *L)
        struct hlua_function *fcn;
        int index;
        int i;
+       struct buffer *trash;
+       const char *kw[5];
+       struct cli_kw *cli_kw;
 
        MAY_LJMP(check_args(L, 3, "register_cli"));
 
@@ -7830,6 +7887,30 @@ __LJMP static int hlua_register_cli(lua_State *L)
        /* Third and fourth argument : lua function. */
        ref_io = MAY_LJMP(hlua_checkfunction(L, 3));
 
+       /* Check for CLI service already registered */
+       trash = get_trash_chunk();
+       index = 0;
+       lua_pushnil(L);
+       memset(kw, 0, sizeof(kw));
+       while (lua_next(L, 1) != 0) {
+               if (index >= CLI_PREFIX_KW_NB)
+                       WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table with a maximum of 5 entries"));
+               if (lua_type(L, -1) != LUA_TSTRING)
+                       WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table filled with strings"));
+               kw[index] = lua_tostring(L, -1);
+               if (index == 0)
+                       chunk_printf(trash, "%s", kw[index]);
+               else
+                       chunk_appendf(trash, " %s", kw[index]);
+               index++;
+               lua_pop(L, 1);
+       }
+       cli_kw = cli_find_kw_exact((char **)kw);
+       if (cli_kw != NULL) {
+               ha_warning("Trying to register CLI keyword 'lua.%s' more than once. "
+                          "This will become a hard error in version 2.5.\n", trash->area);
+       }
+
        /* Allocate and fill the sample fetch keyword struct. */
        cli_kws = calloc(1, sizeof(*cli_kws) + sizeof(struct cli_kw) * 2);
        if (!cli_kws)