summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2020-03-16 16:53:10 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2020-04-01 11:34:32 +0200
commitcb4da5da74b7a6f2e7c4f4ed1b0e5affe45fe2a2 (patch)
treefdeecd66c05478818479deb89a5dd0cabd99956a /strings
parenta1846b7a642dd5b5b36f3d4f0099cb7c0149f859 (diff)
downloadmariadb-git-cb4da5da74b7a6f2e7c4f4ed1b0e5affe45fe2a2.tar.gz
MDEV-20604: Duplicate key value is silently truncated to 64 characters in print_keydup_error
Added indication of truncated string for "s" and "M" formats
Diffstat (limited to 'strings')
-rw-r--r--strings/my_vsnprintf.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c
index ad3517e4252..fa2cd494dc0 100644
--- a/strings/my_vsnprintf.c
+++ b/strings/my_vsnprintf.c
@@ -153,12 +153,15 @@ static const char *check_longlong(const char *fmt, uint *have_longlong)
*/
static char *backtick_string(CHARSET_INFO *cs, char *to, const char *end,
- char *par, size_t par_len, char quote_char)
+ char *par, size_t par_len, char quote_char,
+ my_bool cut)
{
+ char *last[3]= {0,0,0};
uint char_len;
char *start= to;
char *par_end= par + par_len;
size_t buff_length= (size_t) (end - to);
+ uint index= 0;
if (buff_length <= par_len)
goto err;
@@ -167,6 +170,11 @@ static char *backtick_string(CHARSET_INFO *cs, char *to, const char *end,
for ( ; par < par_end; par+= char_len)
{
uchar c= *(uchar *) par;
+ if (cut)
+ {
+ last[index]= start;
+ index= (index + 1) % 3;
+ }
char_len= my_charlen_fix(cs, par, par_end);
if (char_len == 1 && c == (uchar) quote_char )
{
@@ -178,9 +186,30 @@ static char *backtick_string(CHARSET_INFO *cs, char *to, const char *end,
goto err;
start= strnmov(start, par, char_len);
}
-
+
if (start + 1 >= end)
goto err;
+
+ if (cut)
+ {
+ uint dots= 0;
+ start= NULL;
+ for (; dots < 3; dots++)
+ {
+ if (index == 0)
+ index= 2;
+ else
+ index--;
+ if (!last[index])
+ break;
+ start= last[index];
+ }
+ if (start == NULL)
+ goto err; // there was no characters at all
+ for (; dots; dots--)
+ *start++= '.';
+
+ }
*start++= quote_char;
return start;
@@ -198,18 +227,45 @@ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end,
size_t width, char *par, uint print_type)
{
int well_formed_error;
- size_t plen, left_len= (size_t) (end - to) + 1;
+ uint dots= 0;
+ size_t plen, left_len= (size_t) (end - to) + 1, slen=0;
if (!par)
par = (char*) "(null)";
- plen= strnlen(par, width);
+ plen= slen= strnlen(par, width + 1);
+ if (plen > width)
+ plen= width;
if (left_len <= plen)
plen = left_len - 1;
+ if ((slen > plen))
+ {
+ if (plen < 3)
+ {
+ dots= (uint) plen;
+ plen= 0;
+ }
+ else
+ {
+ dots= 3;
+ plen-= 3;
+ }
+ }
+
plen= my_well_formed_length(cs, par, par + plen, width, &well_formed_error);
if (print_type & ESCAPED_ARG)
- to= backtick_string(cs, to, end, par, plen, '`');
+ {
+ to= backtick_string(cs, to, end, par, plen + dots, '`', MY_TEST(dots));
+ dots= 0;
+ }
else
to= strnmov(to,par,plen);
+
+ if (dots)
+ {
+ for (; dots; dots--)
+ *(to++)= '.';
+ *(to)= 0;
+ }
return to;
}