summaryrefslogtreecommitdiff
path: root/ext/mysql/libmysql/libmysql.c
diff options
context:
space:
mode:
authorGeorg Richter <georg@php.net>2002-12-11 08:28:41 +0000
committerGeorg Richter <georg@php.net>2002-12-11 08:28:41 +0000
commit230f4ebb065accb9a08076fff06125fd63280529 (patch)
treee18b99097d5686cae79dfa8ffc2d8f2ad868dade /ext/mysql/libmysql/libmysql.c
parent52d0f1c143fe52ca6a59392329bf6e7372e5279e (diff)
downloadphp-git-230f4ebb065accb9a08076fff06125fd63280529.tar.gz
Security fix (merged from 3.23.54)
Diffstat (limited to 'ext/mysql/libmysql/libmysql.c')
-rw-r--r--ext/mysql/libmysql/libmysql.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/ext/mysql/libmysql/libmysql.c b/ext/mysql/libmysql/libmysql.c
index cd74ceb2a0..05558cf3ee 100644
--- a/ext/mysql/libmysql/libmysql.c
+++ b/ext/mysql/libmysql/libmysql.c
@@ -872,7 +872,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
uint field,pkt_len;
ulong len;
uchar *cp;
- char *to;
+ char *to, *end_to;
MYSQL_DATA *result;
MYSQL_ROWS **prev_ptr,*cur;
NET *net = &mysql->net;
@@ -910,6 +910,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
*prev_ptr=cur;
prev_ptr= &cur->next;
to= (char*) (cur->data+fields+1);
+ end_to = to + pkt_len - 1;
for (field=0 ; field < fields ; field++)
{
if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
@@ -919,6 +920,13 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
else
{
cur->data[field] = to;
+ if (len > end_to - to)
+ {
+ free_rows(result);
+ net->last_errno = CR_UNKNOWN_ERROR;
+ strmov(net->last_error, ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
memcpy(to,(char*) cp,len); to[len]=0;
to+=len+1;
cp+=len;
@@ -953,7 +961,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
{
uint field;
ulong pkt_len,len;
- uchar *pos,*prev_pos;
+ uchar *pos,*prev_pos,*end_pos;
if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error)
return -1;
@@ -961,6 +969,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
return 1; /* End of data */
prev_pos= 0; /* allowed to write at packet[-1] */
pos=mysql->net.read_pos;
+ end_pos=pos+pkt_len;
for (field=0 ; field < fields ; field++)
{
if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
@@ -970,6 +979,12 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
}
else
{
+ if (len > end_pos - pos)
+ {
+ mysql->net.last_errno=CR_UNKNOWN_ERROR;
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno));
+ return -1;
+ }
row[field] = (char*) pos;
pos+=len;
*lengths++=len;