1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-22545: my_vsnprintf behaves not as in C standard

Added parameter %T for string which should be visibly truncated.
This commit is contained in:
Oleksandr Byelkin
2020-05-20 13:34:51 +02:00
parent d8e2fa0c49
commit cf52dd174e
10 changed files with 267 additions and 223 deletions

View File

@ -224,7 +224,8 @@ err:
*/
static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end,
size_t width, char *par, uint print_type)
size_t width, char *par, uint print_type,
my_bool nice_cut)
{
int well_formed_error;
uint dots= 0;
@ -232,24 +233,34 @@ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end,
if (!par)
par = (char*) "(null)";
plen= slen= strnlen(par, width + 1);
if (plen > width)
plen= width;
if (left_len <= plen)
plen = left_len - 1;
if ((slen > plen))
if (nice_cut)
{
if (plen < 3)
plen= slen= strnlen(par, width + 1);
if (plen > width)
plen= width;
if (left_len <= plen)
plen = left_len - 1;
if ((slen > plen))
{
dots= (uint) plen;
plen= 0;
}
else
{
dots= 3;
plen-= 3;
if (plen < 3)
{
dots= (uint) plen;
plen= 0;
}
else
{
dots= 3;
plen-= 3;
}
}
}
else
{
plen= slen= strnlen(par, width);
dots= 0;
if (left_len <= plen)
plen = left_len - 1;
}
plen= my_well_formed_length(cs, par, par + plen, width, &well_formed_error);
if (print_type & ESCAPED_ARG)
@ -446,6 +457,7 @@ start:
switch (args_arr[i].arg_type) {
case 's':
case 'b':
case 'T':
args_arr[i].str_arg= va_arg(ap, char *);
break;
case 'f':
@ -480,12 +492,14 @@ start:
size_t width= 0, length= 0;
switch (print_arr[i].arg_type) {
case 's':
case 'T':
{
char *par= args_arr[print_arr[i].arg_idx].str_arg;
width= (print_arr[i].flags & WIDTH_ARG)
? (size_t)args_arr[print_arr[i].width].longlong_arg
: print_arr[i].width;
to= process_str_arg(cs, to, end, width, par, print_arr[i].flags);
to= process_str_arg(cs, to, end, width, par, print_arr[i].flags,
(print_arr[i].arg_type == 'T'));
break;
}
case 'b':
@ -552,7 +566,7 @@ start:
*to++= '"';
my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg);
to= process_str_arg(cs, to, real_end, width, errmsg_buff,
print_arr[i].flags);
print_arr[i].flags, 1);
if (real_end > to) *to++= '"';
}
break;
@ -676,10 +690,10 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
fmt= check_longlong(fmt, &have_longlong);
if (*fmt == 's') /* String parameter */
if (*fmt == 's' || *fmt == 'T') /* String parameter */
{
reg2 char *par= va_arg(ap, char *);
to= process_str_arg(cs, to, end, width, par, print_type);
to= process_str_arg(cs, to, end, width, par, print_type, (*fmt == 'T'));
continue;
}
else if (*fmt == 'b') /* Buffer parameter */
@ -731,7 +745,8 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
*to++= ' ';
*to++= '"';
my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg);
to= process_str_arg(cs, to, real_end, width, errmsg_buff, print_type);
to= process_str_arg(cs, to, real_end, width, errmsg_buff,
print_type, 1);
if (real_end > to) *to++= '"';
}
continue;