mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
BUG/MEDIUM: lua: the function txn_done() from sample fetches can crash
The function txn_done() ends a transaction. It does not make sense to call this function from a lua sample-fetch wrapper, because the role of a sample-fetch is not to terminate a transaction. This patch modify the role of the fucntion txn_done() if it is called from a sample-fetch wrapper, now it just ends the execution of the Lua code like the done() function. Must be backported in 1.6
This commit is contained in:
parent
8ab79420ba
commit
ab00df6cf6
@ -1460,6 +1460,11 @@ TXN class
|
|||||||
session. It can be used when a critical error is detected or to terminate
|
session. It can be used when a critical error is detected or to terminate
|
||||||
processing after some data have been returned to the client (eg: a redirect).
|
processing after some data have been returned to the client (eg: a redirect).
|
||||||
|
|
||||||
|
*Warning*: It not make sense to call this function from sample-fetches. In
|
||||||
|
this case the behaviour of this one is the same than core.done(): it quit
|
||||||
|
the Lua execution. The transaction is really aborted only from an action
|
||||||
|
registered function.
|
||||||
|
|
||||||
:param class_txn txn: The class txn object containing the data.
|
:param class_txn txn: The class txn object containing the data.
|
||||||
|
|
||||||
.. js:function:: TXN.set_loglevel(txn, loglevel)
|
.. js:function:: TXN.set_loglevel(txn, loglevel)
|
||||||
|
@ -35,6 +35,8 @@ struct stream;
|
|||||||
#define HLUA_F_AS_STRING 0x01
|
#define HLUA_F_AS_STRING 0x01
|
||||||
#define HLUA_F_MAY_USE_HTTP 0x02
|
#define HLUA_F_MAY_USE_HTTP 0x02
|
||||||
|
|
||||||
|
#define HLUA_TXN_NOTERM 0x00000001
|
||||||
|
|
||||||
#define HLUA_CONCAT_BLOCSZ 2048
|
#define HLUA_CONCAT_BLOCSZ 2048
|
||||||
|
|
||||||
enum hlua_exec {
|
enum hlua_exec {
|
||||||
@ -109,6 +111,7 @@ struct hlua_txn {
|
|||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct proxy *p;
|
struct proxy *p;
|
||||||
int dir; /* SMP_OPT_DIR_{REQ,RES} */
|
int dir; /* SMP_OPT_DIR_{REQ,RES} */
|
||||||
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This struct contains the applet context. */
|
/* This struct contains the applet context. */
|
||||||
|
17
src/hlua.c
17
src/hlua.c
@ -4601,7 +4601,7 @@ __LJMP static int hlua_get_priv(lua_State *L)
|
|||||||
* return 0 if the stack does not contains free slots,
|
* return 0 if the stack does not contains free slots,
|
||||||
* otherwise it returns 1.
|
* otherwise it returns 1.
|
||||||
*/
|
*/
|
||||||
static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, int dir)
|
static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, int dir, int flags)
|
||||||
{
|
{
|
||||||
struct hlua_txn *htxn;
|
struct hlua_txn *htxn;
|
||||||
|
|
||||||
@ -4621,6 +4621,7 @@ static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, int dir
|
|||||||
htxn->s = s;
|
htxn->s = s;
|
||||||
htxn->p = p;
|
htxn->p = p;
|
||||||
htxn->dir = dir;
|
htxn->dir = dir;
|
||||||
|
htxn->flags = flags;
|
||||||
|
|
||||||
/* Create the "f" field that contains a list of fetches. */
|
/* Create the "f" field that contains a list of fetches. */
|
||||||
lua_pushstring(L, "f");
|
lua_pushstring(L, "f");
|
||||||
@ -4814,6 +4815,15 @@ __LJMP static int hlua_txn_done(lua_State *L)
|
|||||||
MAY_LJMP(check_args(L, 1, "close"));
|
MAY_LJMP(check_args(L, 1, "close"));
|
||||||
htxn = MAY_LJMP(hlua_checktxn(L, 1));
|
htxn = MAY_LJMP(hlua_checktxn(L, 1));
|
||||||
|
|
||||||
|
/* If the flags NOTERM is set, we cannot terminate the http
|
||||||
|
* session, so we just end the execution of the current
|
||||||
|
* lua code.
|
||||||
|
*/
|
||||||
|
if (htxn->flags & HLUA_TXN_NOTERM) {
|
||||||
|
WILL_LJMP(hlua_done(L));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ic = &htxn->s->req;
|
ic = &htxn->s->req;
|
||||||
oc = &htxn->s->res;
|
oc = &htxn->s->res;
|
||||||
|
|
||||||
@ -5265,7 +5275,8 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp
|
|||||||
lua_rawgeti(stream->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
|
lua_rawgeti(stream->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
|
||||||
|
|
||||||
/* push arguments in the stack. */
|
/* push arguments in the stack. */
|
||||||
if (!hlua_txn_new(stream->hlua.T, stream, smp->px, smp->opt & SMP_OPT_DIR)) {
|
if (!hlua_txn_new(stream->hlua.T, stream, smp->px, smp->opt & SMP_OPT_DIR,
|
||||||
|
HLUA_TXN_NOTERM)) {
|
||||||
SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
|
SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua.T);
|
||||||
return 0;
|
return 0;
|
||||||
@ -5511,7 +5522,7 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px,
|
|||||||
lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn.function_ref);
|
lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn.function_ref);
|
||||||
|
|
||||||
/* Create and and push object stream in the stack. */
|
/* Create and and push object stream in the stack. */
|
||||||
if (!hlua_txn_new(s->hlua.T, s, px, dir)) {
|
if (!hlua_txn_new(s->hlua.T, s, px, dir, 0)) {
|
||||||
SEND_ERR(px, "Lua function '%s': full stack.\n",
|
SEND_ERR(px, "Lua function '%s': full stack.\n",
|
||||||
rule->arg.hlua_rule->fcn.name);
|
rule->arg.hlua_rule->fcn.name);
|
||||||
RESET_SAFE_LJMP(s->hlua.T);
|
RESET_SAFE_LJMP(s->hlua.T);
|
||||||
|
Loading…
Reference in New Issue
Block a user