diff options
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 7e75af2a882..57abeffab22 100644 --- a/sql-common/pack.c +++ b/sql-common/pack.c @@ -49,7 +49,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)++; @@ -70,12 +70,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; } /* @@ -83,38 +118,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) LL(251)) + 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) LL(65536)) + 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) LL(16777216)) + 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; |