Commit 2d4f7188 authored by unknown's avatar unknown

BUG#19459 (BINLOG RBR command does not lock tables correctly causing

crash for, e.g., NDB):
Submitting patch to base64_decode() adding extra parameter.


include/base64.h:
  Adding parameter to base64_decode() to return the position just after
  the string that was decoded.
mysys/base64.c:
  Adding comment to base64_decode().
  Adding parameter to base64_decode() to return the position just after
  the string that was decoded.
sql/share/errmsg.txt:
  Adding error message.
storage/ndb/src/mgmapi/mgmapi.cpp:
  Parameters to base64_decode() changed.
unittest/mysys/base64-t.c:
  Parameters to base64_decode() changed.
parent ee8a1a74
...@@ -39,7 +39,8 @@ int base64_encode(const void *src, size_t src_len, char *dst); ...@@ -39,7 +39,8 @@ int base64_encode(const void *src, size_t src_len, char *dst);
/* /*
Decode a base64 string into data Decode a base64 string into data
*/ */
int base64_decode(const char *src, size_t src_len, void *dst); int base64_decode(const char *src, size_t src_len,
void *dst, const char **end_ptr);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -125,44 +125,69 @@ pos(unsigned char c) ...@@ -125,44 +125,69 @@ pos(unsigned char c)
/* /*
Decode a base64 string Decode a base64 string
Note: We require that dst is pre-allocated to correct size. SYNOPSIS
See base64_needed_decoded_length(). base64_decode()
src Pointer to base64-encoded string
RETURN Number of bytes produced in dst or -1 in case of failure len Length of string at 'src'
dst Pointer to location where decoded data will be stored
end_ptr Pointer to variable that will refer to the character
after the end of the encoded data that were decoded. Can
be NULL.
DESCRIPTION
The base64-encoded data in the range ['src','*end_ptr') will be
decoded and stored starting at 'dst'. The decoding will stop
after 'len' characters have been read from 'src', or when padding
occurs in the base64-encoded data. In either case: if 'end_ptr' is
non-null, '*end_ptr' will be set to point to the character after
the last read character, even in the presence of error.
NOTE
We require that 'dst' is pre-allocated to correct size.
SEE ALSO
base64_needed_decoded_length().
RETURN VALUE
Number of bytes written at 'dst' or -1 in case of failure
*/ */
int int
base64_decode(const char *src, size_t size, void *dst) base64_decode(const char *const src_base, size_t const len,
void *dst, const char **end_ptr)
{ {
char b[3]; char b[3];
size_t i= 0; size_t i= 0;
char *dst_base= (char *)dst; char *dst_base= (char *)dst;
char const *src= src_base;
char *d= dst_base; char *d= dst_base;
size_t j; size_t j;
while (i < size) while (i < len)
{ {
unsigned c= 0; unsigned c= 0;
size_t mark= 0; size_t mark= 0;
SKIP_SPACE(src, i, size); SKIP_SPACE(src, i, len);
c += pos(*src++); c += pos(*src++);
c <<= 6; c <<= 6;
i++; i++;
SKIP_SPACE(src, i, size); SKIP_SPACE(src, i, len);
c += pos(*src++); c += pos(*src++);
c <<= 6; c <<= 6;
i++; i++;
SKIP_SPACE(src, i, size); SKIP_SPACE(src, i, len);
if (* src != '=') if (*src != '=')
c += pos(*src++); c += pos(*src++);
else else
{ {
i= size; src += 2; /* There should be two bytes padding */
i= len;
mark= 2; mark= 2;
c <<= 6; c <<= 6;
goto end; goto end;
...@@ -170,13 +195,14 @@ base64_decode(const char *src, size_t size, void *dst) ...@@ -170,13 +195,14 @@ base64_decode(const char *src, size_t size, void *dst)
c <<= 6; c <<= 6;
i++; i++;
SKIP_SPACE(src, i, size); SKIP_SPACE(src, i, len);
if (*src != '=') if (*src != '=')
c += pos(*src++); c += pos(*src++);
else else
{ {
i= size; src += 1; /* There should be one byte padding */
i= len;
mark= 1; mark= 1;
goto end; goto end;
} }
...@@ -191,11 +217,14 @@ base64_decode(const char *src, size_t size, void *dst) ...@@ -191,11 +217,14 @@ base64_decode(const char *src, size_t size, void *dst)
*d++= b[j]; *d++= b[j];
} }
if (i != size) if (end_ptr != NULL)
{ *end_ptr= src;
return -1;
} /*
return d - dst_base; The variable 'i' is set to 'len' when padding has been read, so it
does not actually reflect the number of bytes read from 'src'.
*/
return i != len ? -1 : d - dst_base;
} }
......
...@@ -5837,3 +5837,6 @@ ER_PARTITION_MERGE_ERROR ...@@ -5837,3 +5837,6 @@ ER_PARTITION_MERGE_ERROR
swe "%s kan inte anvndas i en partitionerad tabell" swe "%s kan inte anvndas i en partitionerad tabell"
ER_RBR_NOT_AVAILABLE ER_RBR_NOT_AVAILABLE
eng "The server was not built with row-based replication" eng "The server was not built with row-based replication"
ER_BASE64_DECODE_ERROR
eng "Decoding of base64 string failed"
swe "Avkodning av base64 strng misslyckades"
...@@ -1771,7 +1771,7 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { ...@@ -1771,7 +1771,7 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
break; break;
void *tmp_data = malloc(base64_needed_decoded_length((size_t) (len - 1))); void *tmp_data = malloc(base64_needed_decoded_length((size_t) (len - 1)));
const int res = base64_decode(buf64, len-1, tmp_data); const int res = base64_decode(buf64, len-1, tmp_data, NULL);
delete[] buf64; delete[] buf64;
UtilBuffer tmp; UtilBuffer tmp;
tmp.append((void *) tmp_data, res); tmp.append((void *) tmp_data, res);
......
...@@ -54,7 +54,7 @@ main(void) ...@@ -54,7 +54,7 @@ main(void)
/* Decode */ /* Decode */
dst= (char *) malloc(base64_needed_decoded_length(strlen(str))); dst= (char *) malloc(base64_needed_decoded_length(strlen(str)));
dst_len= base64_decode(str, strlen(str), dst); dst_len= base64_decode(str, strlen(str), dst, NULL);
ok(dst_len == src_len, "Comparing lengths"); ok(dst_len == src_len, "Comparing lengths");
cmp= memcmp(src, dst, src_len); cmp= memcmp(src, dst, src_len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment