diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-12-09 12:38:02 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-12-09 12:38:02 +0100 |
commit | bec1d903d944acd5c28c3f4f2d22b84ddae63ea2 (patch) | |
tree | 8a903859333de1648f789a2985fd62e856ebfa05 /sql-common/pack.c | |
parent | 6ae5f0efea392e3fdb285afc1bafdae16888b96a (diff) | |
download | mariadb-git-bec1d903d944acd5c28c3f4f2d22b84ddae63ea2.tar.gz |
Do the partial merge of WL#5602 correctly:
Remove unused code (that should not have been merged)
Add protocol extension (that should have been merged)
Fix bugs (see pack.c)
Diffstat (limited to 'sql-common/pack.c')
-rw-r--r-- | sql-common/pack.c | 96 |
1 files changed, 81 insertions, 15 deletions
diff --git a/sql-common/pack.c b/sql-common/pack.c index 9c920279cf8..f0932e49617 100644 --- a/sql-common/pack.c +++ b/sql-common/pack.c @@ -48,7 +48,7 @@ ulong STDCALL net_field_length(uchar **packet) /* The same as above but returns longlong */ my_ulonglong net_field_length_ll(uchar **packet) { - reg1 uchar *pos= *packet; + uchar *pos= *packet; if (*pos < 251) { (*packet)++; @@ -69,12 +69,47 @@ my_ulonglong net_field_length_ll(uchar **packet) (*packet)+=4; return (my_ulonglong) uint3korr(pos+1); } + DBUG_ASSERT(*pos == 254); (*packet)+=9; /* Must be 254 when here */ -#ifdef NO_CLIENT_LONGLONG - return (my_ulonglong) uint4korr(pos+1); -#else return (my_ulonglong) uint8korr(pos+1); -#endif +} + +my_ulonglong safe_net_field_length_ll(uchar **packet, size_t packet_len) +{ + uchar *pos= *packet; + if (packet_len < 1) + goto err; + if (*pos < 251) + { + (*packet)++; + return (my_ulonglong) *pos; + } + if (*pos == 251) + { + (*packet)++; + return (my_ulonglong) NULL_LENGTH; + } + if (*pos == 252) + { + if (packet_len < 3) + goto err; + (*packet)+=3; + return (my_ulonglong) uint2korr(pos+1); + } + if (*pos == 253) + { + if (packet_len < 4) + goto err; + (*packet)+=4; + return (my_ulonglong) uint3korr(pos+1); + } + if (packet_len < 9 || *pos != 254) + goto err; + (*packet)+=9; + return (my_ulonglong) uint8korr(pos+1); +err: + *packet = NULL; + return 0; } /* @@ -82,38 +117,69 @@ my_ulonglong net_field_length_ll(uchar **packet) SYNOPSIS net_store_length() - pkg Store the packed integer here + packet Store the packed integer here length integers to store NOTES This is mostly used to store lengths of strings. - We have to cast the result for the LL() becasue of a bug in Forte CC - compiler. RETURN - Position in 'pkg' after the packed length + Position in 'packet' after the packed length */ uchar *net_store_length(uchar *packet, ulonglong length) { - if (length < (ulonglong) 251LL) + if (length < 251) + { + *packet= (uchar) length; + return packet+1; + } + /* 251 is reserved for NULL */ + if (length < 65536) + { + *packet++=252; + int2store(packet, (uint) length); + return packet+2; + } + if (length < 16777216) + { + *packet++=253; + int3store(packet, (ulong) length); + return packet+3; + } + *packet++=254; + int8store(packet,length); + return packet+8; +} + +uchar *safe_net_store_length(uchar *packet, size_t packet_len, ulonglong length) +{ + if (length < 251) { - *packet=(uchar) length; + if (packet_len < 1) + return NULL; + *packet= (uchar) length; return packet+1; } /* 251 is reserved for NULL */ - if (length < (ulonglong) 65536LL) + if (length < 65536) { + if (packet_len < 3) + return NULL; *packet++=252; - int2store(packet,(uint) length); + int2store(packet, (uint) length); return packet+2; } - if (length < (ulonglong) 16777216LL) + if (length < 16777216) { + if (packet_len < 4) + return NULL; *packet++=253; - int3store(packet,(ulong) length); + int3store(packet, (ulong) length); return packet+3; } + if (packet_len < 9) + return NULL; *packet++=254; int8store(packet,length); return packet+8; |