Tarantool development patches archive
 help / color / mirror / Atom feed
From: Nikita Pettik <korablev@tarantool.org>
To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Cc: tarantool-patches@dev.tarantool.org
Subject: Re: [Tarantool-patches] [PATCH v2 10/10] iproto: support error stacked diagnostic area
Date: Fri, 3 Apr 2020 02:16:47 +0000	[thread overview]
Message-ID: <20200403021647.GD946@tarantool.org> (raw)
In-Reply-To: <cde3f2ec-757a-aabf-f0f6-c28b71a10daa@tarantool.org>

On 03 Apr 00:20, Vladislav Shpilevoy wrote:
> Thanks for the fixes!
> 
> See 2 comments below.
> 
> > diff --git a/src/box/error.cc b/src/box/error.cc
> > index 8e77c2e9e..897aa9261 100644
> > --- a/src/box/error.cc
> > +++ b/src/box/error.cc
> > @@ -102,6 +102,23 @@ box_error_new(const char *file, unsigned line, uint32_t code,
> >  	return e;
> >  }
> >  
> > +int
> > +box_error_add(const char *file, unsigned line, uint32_t code,
> > +	      const char *fmt, ...)
> > +{
> > +	struct error *e = BuildClientError(file, line, ER_UNKNOWN);
> > +	ClientError *client_error = type_cast(ClientError, e);
> > +	if (client_error) {
> > +		client_error->m_errcode = code;
> > +		va_list ap;
> > +		va_start(ap, fmt);
> > +		error_vformat_msg(e, fmt, ap);
> > +		va_end(ap);
> > +	}
> > +	diag_add_error(&fiber()->diag, e);
> > +	return -1;
> 
> 1. Why do we return -1 instead of the new error object?
> box_error_new() returns an error, and this function does not.
> Seems inconsistent.

box_error_new() is supposed to return new error according to
its name (to be more precise - '_new' suffix). It allocates and
fills in error struct. On the other hand, box_error_add() creates
error and adds it to the diagnostic area. It is simply meaningless
to return error, which is already set to diag.
 
> >>> diff --git a/test/unit/xrow.cc b/test/unit/xrow.cc
> >>> index 68a334239..954f22f16 100644
> >>> --- a/test/unit/xrow.cc
> >>> +++ b/test/unit/xrow.cc
> > @@ -372,6 +375,26 @@ test_xrow_error_stack_decode()
> >         isnt(last, NULL, "xrow_decode succeed: diag has been set");
> >         is(strcmp(last->errmsg, ""), 0, "xrow_decode corrupted stack: "
> >            "stack's map wrong value type");
> > +
> > +       /* Bad key in the packet. */
> > +       pos = mp_encode_map(buffer, 1);
> > +       pos = mp_encode_uint(pos, IPROTO_ERROR_STACK);
> > +       pos = mp_encode_array(pos, 1);
> > +       pos = mp_encode_map(pos, 2);
> > +       pos = mp_encode_uint(pos, 0xff000000 | IPROTO_ERROR_CODE);
> > +       pos = mp_encode_uint(pos, 159);
> > +       pos = mp_encode_uint(pos, IPROTO_ERROR_MESSAGE);
> > +       pos = mp_encode_str(pos, "test msg", strlen("test msg"));
> > +       header.body[0].iov_base = buffer;
> > +       header.body[0].iov_len = pos - buffer;
> > +
> > +       diag_clear(diag_get());
> > +       xrow_decode_error(&header);
> > +       last = diag_last_error(diag_get());
> > +       isnt(last, NULL, "xrow_decode succeed: diag has been set");
> > +       is(strcmp(last->errmsg, "test msg"), 0, "xrow_decode corrupted stack: "
> > +          "stack's map wrong key");
> > +
> >         check_plan();
> >  }
> > 
> > Diag won't be empty since error will be set anyway - with default
> > (i.e. wrong) error code (0), but correct message.
> 
> 2. I added box_error_code() check to ensure this.
> 
> But more importantly that the original bug I was referring to
> still is here. About overflows and integer truncation. I fixed it
> and added tests. See them below and on the branch in a separate
> commit.

Oops, seems like I forgot to pop diff out from stash...

> diff --git a/src/box/xrow.c b/src/box/xrow.c
> index 9d30bcaf9..be026a43c 100644
> --- a/src/box/xrow.c
> +++ b/src/box/xrow.c
> @@ -1105,11 +1105,13 @@ iproto_decode_error_stack(const char **pos)
>  		for (uint32_t key_idx = 0; key_idx < map_sz; key_idx++) {
>  			if (mp_typeof(**pos) != MP_UINT)
>  				return -1;
> -			uint32_t key = mp_decode_uint(pos);
> +			uint64_t key = mp_decode_uint(pos);
>  			if (key == IPROTO_ERROR_CODE) {
>  				if (mp_typeof(**pos) != MP_UINT)
>  					return -1;
>  				code = mp_decode_uint(pos);
> +				if (code > UINT32_MAX)
> +					return -1;
>  			} else if (key == IPROTO_ERROR_MESSAGE) {
>  				if (mp_typeof(**pos) != MP_STR)
>  					return -1;

Applied.

> diff --git a/test/unit/xrow.cc b/test/unit/xrow.cc
> index ae45f18b0..718ef15a2 100644
> --- a/test/unit/xrow.cc
> +++ b/test/unit/xrow.cc
> @@ -32,6 +32,7 @@ extern "C" {
>  #include "unit.h"
>  } /* extern "C" */
>  #include "trivia/util.h"
> +#include "box/error.h"
>  #include "box/xrow.h"
>  #include "box/iproto_constants.h"
>  #include "uuid/tt_uuid.h"
> @@ -255,7 +256,7 @@ error_stack_entry_encode(char *pos, const char *err_str)
>  void
>  test_xrow_error_stack_decode()
>  {
> -	plan(17);
> +	plan(24);
>  	char buffer[2048];
>  	/*
>  	 * To start with, let's test the simplest and obsolete
> @@ -392,9 +393,51 @@ test_xrow_error_stack_decode()
>  	xrow_decode_error(&header);
>  	last = diag_last_error(diag_get());
>  	isnt(last, NULL, "xrow_decode succeed: diag has been set");
> +	is(box_error_code(last), 0, "xrow_decode last error code is default 0");
>  	is(strcmp(last->errmsg, "test msg"), 0, "xrow_decode corrupted stack: "
>  	   "stack's map wrong key");
>  
> +	/* Overflow error code. */
> +	pos = mp_encode_map(buffer, 1);
> +	pos = mp_encode_uint(pos, IPROTO_ERROR_STACK);
> +	pos = mp_encode_array(pos, 1);
> +	pos = mp_encode_map(pos, 2);
> +	pos = mp_encode_uint(pos, IPROTO_ERROR_CODE);
> +	pos = mp_encode_uint(pos, (uint64_t)1 << 40);
> +	pos = mp_encode_uint(pos, IPROTO_ERROR_MESSAGE);
> +	pos = mp_encode_str(pos, "test msg", strlen("test msg"));
> +	header.body[0].iov_base = buffer;
> +	header.body[0].iov_len = pos - buffer;
> +
> +	diag_clear(diag_get());
> +	xrow_decode_error(&header);
> +	last = diag_last_error(diag_get());
> +	isnt(last, NULL, "xrow_decode succeed: diag has been set");
> +	is(box_error_code(last), 159, "xrow_decode failed, took code from "
> +	   "header");
> +	is(strcmp(last->errmsg, ""), 0, "xrow_decode failed, message is not "
> +	   "decoded");
> +
> +	/* Overflow error key. */
> +	pos = mp_encode_map(buffer, 1);
> +	pos = mp_encode_uint(pos, IPROTO_ERROR_STACK);
> +	pos = mp_encode_array(pos, 1);
> +	pos = mp_encode_map(pos, 2);
> +	pos = mp_encode_uint(pos, 0xff00000000 | IPROTO_ERROR_CODE);
> +	pos = mp_encode_uint(pos, 159);
> +	pos = mp_encode_uint(pos, IPROTO_ERROR_MESSAGE);
> +	pos = mp_encode_str(pos, "test msg", strlen("test msg"));
> +	header.body[0].iov_base = buffer;
> +	header.body[0].iov_len = pos - buffer;
> +
> +	diag_clear(diag_get());
> +	xrow_decode_error(&header);
> +	last = diag_last_error(diag_get());
> +	isnt(last, NULL, "xrow_decode succeed: diag has been set");
> +	is(box_error_code(last), 0, "xrow_decode last error code is default 0");
> +	is(strcmp(last->errmsg, "test msg"), 0, "xrow_decode message is fine "
> +	   "even without the code");

It is likely to be the same as "Bad key in the packet.". At least it
seems to cover the same execution path.

Squashed both patches on the top of branch.

  reply	other threads:[~2020-04-03  2:16 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-25  1:42 [Tarantool-patches] [PATCH v2 00/10] Stacked diagnostics Nikita Pettik
2020-03-25  1:42 ` [Tarantool-patches] [PATCH v2 01/10] box: rfc for stacked diagnostic area Nikita Pettik
2020-03-25  8:27   ` Konstantin Osipov
2020-03-25 14:08     ` Nikita Pettik
2020-03-25  1:42 ` [Tarantool-patches] [PATCH v2 02/10] box: rename diag_add_error to diag_set_error Nikita Pettik
2020-03-25  8:27   ` Konstantin Osipov
2020-03-26  0:22   ` Vladislav Shpilevoy
2020-03-26 12:31     ` Nikita Pettik
2020-03-25  1:42 ` [Tarantool-patches] [PATCH v2 03/10] test: move box.error tests to box/error.test.lua Nikita Pettik
2020-03-25  8:28   ` Konstantin Osipov
2020-03-26  0:22   ` Vladislav Shpilevoy
2020-03-26 12:31     ` Nikita Pettik
2020-03-25  1:43 ` [Tarantool-patches] [PATCH v2 04/10] box/error: introduce box.error.set() method Nikita Pettik
2020-03-25  8:33   ` Konstantin Osipov
2020-03-25 17:41     ` Nikita Pettik
2020-03-26  0:22   ` Vladislav Shpilevoy
2020-03-26 12:31     ` Nikita Pettik
2020-03-25  1:43 ` [Tarantool-patches] [PATCH v2 05/10] box/error: don't set error created via box.error.new to diag Nikita Pettik
2020-03-26 16:50   ` Konstantin Osipov
2020-03-26 17:59     ` Nikita Pettik
2020-03-26 18:06       ` Nikita Pettik
2020-03-26 18:07       ` Alexander Turenko
2020-03-27  0:19   ` Vladislav Shpilevoy
2020-03-27 13:09     ` Nikita Pettik
2020-03-25  1:43 ` [Tarantool-patches] [PATCH v2 06/10] box: introduce stacked diagnostic area Nikita Pettik
2020-03-26 16:54   ` Konstantin Osipov
2020-03-26 18:03     ` Nikita Pettik
2020-03-26 18:08       ` Konstantin Osipov
2020-03-28 18:40   ` Vladislav Shpilevoy
2020-04-01 16:09     ` Nikita Pettik
2020-04-02  0:29       ` Vladislav Shpilevoy
2020-04-02 17:42         ` Nikita Pettik
2020-04-02 22:20           ` Vladislav Shpilevoy
2020-04-03  1:54             ` Nikita Pettik
2020-04-03 23:17               ` Vladislav Shpilevoy
2020-03-28 18:59   ` Vladislav Shpilevoy
2020-03-31 17:44     ` Nikita Pettik
2020-04-02  0:29       ` Vladislav Shpilevoy
2020-04-02 14:16         ` Nikita Pettik
2020-03-25  1:43 ` [Tarantool-patches] [PATCH v2 07/10] box: use stacked diagnostic area for functional indexes Nikita Pettik
2020-03-30 23:24   ` Vladislav Shpilevoy
2020-04-01 15:53     ` Nikita Pettik
2020-03-25  1:43 ` [Tarantool-patches] [PATCH v2 08/10] box/error: clarify purpose of reference counting in struct error Nikita Pettik
2020-03-30 23:24   ` Vladislav Shpilevoy
2020-03-25  1:43 ` [Tarantool-patches] [PATCH v2 09/10] iproto: refactor error encoding with mpstream Nikita Pettik
2020-03-30 23:24   ` Vladislav Shpilevoy
2020-04-01 15:54     ` Nikita Pettik
2020-03-25  1:43 ` [Tarantool-patches] [PATCH v2 10/10] iproto: support error stacked diagnostic area Nikita Pettik
2020-03-30 23:24   ` Vladislav Shpilevoy
2020-04-01 16:26     ` Nikita Pettik
2020-04-01 22:24       ` Nikita Pettik
2020-04-02  0:29         ` Vladislav Shpilevoy
2020-04-02 14:01           ` Nikita Pettik
2020-04-02 22:20             ` Vladislav Shpilevoy
2020-04-03  2:16               ` Nikita Pettik [this message]
2020-04-03 23:17                 ` Vladislav Shpilevoy
2020-04-06 11:07                   ` Nikita Pettik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200403021647.GD946@tarantool.org \
    --to=korablev@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH v2 10/10] iproto: support error stacked diagnostic area' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox