summaryrefslogtreecommitdiff
path: root/sql-common/pack.c
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-12-09 12:38:02 +0100
committerSergei Golubchik <sergii@pisem.net>2013-12-09 12:38:02 +0100
commitbec1d903d944acd5c28c3f4f2d22b84ddae63ea2 (patch)
tree8a903859333de1648f789a2985fd62e856ebfa05 /sql-common/pack.c
parent6ae5f0efea392e3fdb285afc1bafdae16888b96a (diff)
downloadmariadb-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.c96
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;