1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Bug#25340722 - PRINT BINARY DATA AS HEX IN THE MYSQL

CLIENT (CONTRIBUTION)

DESCRIPTION:
============
Binary data should be printed as hex in the mysql client
when the option binary-as-hex is enabled.

ANALYSIS:
=========
The fix deals only with mysql command line client.
It does not change, at all, the data sent to the
applications. Printing binary data as hex also
allows to use the output in the where clause
of the query.

FIX:
====
A new option 'binary-as-hex' is introduced to print the
binary contents as hex in the mysql client. The option
is disabled by default. When the option is enabled, we
convert the binary data to hex before printing the
contents irrespective of whether it is in tabular,
xml or html format.
This commit is contained in:
Anushree Prakash B
2017-05-03 15:16:08 +00:00
parent 65ea61fe58
commit 756b00d80a
3 changed files with 268 additions and 13 deletions

View File

@@ -142,7 +142,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0,
default_pager_set= 0, opt_sigint_ignore= 0,
auto_vertical_output= 0,
show_warnings= 0, executing_query= 0, interrupted_query= 0,
ignore_spaces= 0;
ignore_spaces= 0, opt_binhex= 0;
static my_bool debug_info_flag, debug_check_flag;
static my_bool column_types_flag;
static my_bool preserve_comments= 0;
@@ -1392,6 +1392,8 @@ static struct my_option my_long_options[] =
{"batch", 'B',
"Don't use history file. Disable interactive behavior. (Enables --silent.)",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"binary-as-hex", 'b', "Print binary data as hex", &opt_binhex, &opt_binhex,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -3101,7 +3103,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
print_table_data_html(result);
else if (opt_xml)
print_table_data_xml(result);
else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
else if (vertical || (auto_vertical_output &&
(terminal_width < get_result_width(result))))
print_table_data_vertically(result);
else if (opt_silent && verbose <= 2 && !output_tables)
print_tab_data(result);
@@ -3320,6 +3323,41 @@ print_field_types(MYSQL_RES *result)
}
/* Used to determine if we should invoke print_as_hex for this field */
static bool
is_binary_field(MYSQL_FIELD *field)
{
if ((field->charsetnr == 63) &&
(field->type == MYSQL_TYPE_BIT ||
field->type == MYSQL_TYPE_BLOB ||
field->type == MYSQL_TYPE_LONG_BLOB ||
field->type == MYSQL_TYPE_MEDIUM_BLOB ||
field->type == MYSQL_TYPE_TINY_BLOB ||
field->type == MYSQL_TYPE_VAR_STRING ||
field->type == MYSQL_TYPE_STRING ||
field->type == MYSQL_TYPE_VARCHAR ||
field->type == MYSQL_TYPE_GEOMETRY))
return 1;
return 0;
}
/* Print binary value as hex literal (0x ...) */
static void
print_as_hex(FILE *output_file, const char *str, ulong len, ulong total_bytes_to_send)
{
const char *ptr= str, *end= ptr+len;
ulong i;
fprintf(output_file, "0x");
for(; ptr < end; ptr++)
fprintf(output_file, "%02X", *((uchar*)ptr));
for (i= 2*len+2; i < total_bytes_to_send; i++)
tee_putc((int)' ', output_file);
}
static void
print_table_data(MYSQL_RES *result)
{
@@ -3346,6 +3384,8 @@ print_table_data(MYSQL_RES *result)
length=max(length,field->max_length);
if (length < 4 && !IS_NOT_NULL(field->flags))
length=4; // Room for "NULL"
if (opt_binhex && is_binary_field(field))
length= 2 + length * 2;
field->max_length=length;
separator.fill(separator.length()+length+2,'-');
separator.append('+');
@@ -3415,7 +3455,9 @@ print_table_data(MYSQL_RES *result)
visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
extra_padding= data_length - visible_length;
if (field_max_length > MAX_COLUMN_LENGTH)
if (opt_binhex && is_binary_field(field))
print_as_hex(PAGER, cur[off], lengths[off], field_max_length);
else if (field_max_length > MAX_COLUMN_LENGTH)
tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
else
{
@@ -3548,11 +3590,15 @@ print_table_data_html(MYSQL_RES *result)
if (interrupted_query)
break;
ulong *lengths=mysql_fetch_lengths(result);
field= mysql_fetch_fields(result);
(void) tee_fputs("<TR>", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
{
(void) tee_fputs("<TD>", PAGER);
xmlencode_print(cur[i], lengths[i]);
if (opt_binhex && is_binary_field(&field[i]))
print_as_hex(PAGER, cur[i], lengths[i], lengths[i]);
else
xmlencode_print(cur[i], lengths[i]);
(void) tee_fputs("</TD>", PAGER);
}
(void) tee_fputs("</TR>", PAGER);
@@ -3588,7 +3634,10 @@ print_table_data_xml(MYSQL_RES *result)
if (cur[i])
{
tee_fprintf(PAGER, "\">");
xmlencode_print(cur[i], lengths[i]);
if (opt_binhex && is_binary_field(&fields[i]))
print_as_hex(PAGER, cur[i], lengths[i], lengths[i]);
else
xmlencode_print(cur[i], lengths[i]);
tee_fprintf(PAGER, "</field>\n");
}
else
@@ -3635,23 +3684,28 @@ print_table_data_vertically(MYSQL_RES *result)
{
unsigned int i;
const char *p;
if (opt_binhex && is_binary_field(field))
fprintf(PAGER, "0x");
for (i= 0, p= cur[off]; i < lengths[off]; i+= 1, p+= 1)
{
if (*p == '\0')
tee_putc((int)' ', PAGER);
if (opt_binhex && is_binary_field(field))
fprintf(PAGER, "%02X", *((uchar*)p));
else
tee_putc((int)*p, PAGER);
{
if (*p == '\0')
tee_putc((int)' ', PAGER);
else
tee_putc((int)*p, PAGER);
}
}
tee_putc('\n', PAGER);
}
else
else
tee_fprintf(PAGER, "NULL\n");
}
}
}
/* print_warnings should be called right after executing a statement */
static void print_warnings()
@@ -3788,11 +3842,19 @@ print_tab_data(MYSQL_RES *result)
while ((cur = mysql_fetch_row(result)))
{
lengths=mysql_fetch_lengths(result);
safe_put_field(cur[0],lengths[0]);
field= mysql_fetch_fields(result);
if (opt_binhex && is_binary_field(&field[0]))
print_as_hex(PAGER, cur[0], lengths[0], lengths[0]);
else
safe_put_field(cur[0],lengths[0]);
for (uint off=1 ; off < mysql_num_fields(result); off++)
{
(void) tee_fputs("\t", PAGER);
safe_put_field(cur[off], lengths[off]);
if (opt_binhex && field && is_binary_field(&field[off]))
print_as_hex(PAGER, cur[off], lengths[off], lengths[off]);
else
safe_put_field(cur[off], lengths[off]);
}
(void) tee_fputs("\n", PAGER);
}