@@ -402,38 +402,46 @@ static bool send_prep_stmt(Prepared_statement *stmt,
402402static ulong get_param_length (uchar **packet, ulong len)
403403{
404404 uchar *pos= *packet;
405+ ulong length;
406+
405407 if (len < 1 )
406408 return 0 ;
407409 if (*pos < 251 )
408410 {
409411 (*packet)++;
410- return (ulong) *pos;
412+ length= *pos;
411413 }
412- if (len < 3 )
413- return 0 ;
414- if (*pos == 252 )
414+ else if (*pos == 252 )
415415 {
416+ if (len < 3 )
417+ return 0 ;
416418 (*packet)+=3 ;
417- return (ulong) uint2korr (pos+1 );
419+ length= uint2korr (pos+1 );
418420 }
419- if (len < 4 )
420- return 0 ;
421- if (*pos == 253 )
421+ else if (*pos == 253 )
422422 {
423+ if (len < 4 )
424+ return 0 ;
423425 (*packet)+=4 ;
424- return (ulong) uint3korr (pos+1 );
426+ length= uint3korr (pos+1 );
427+ }
428+ else
429+ {
430+ if (len < 9 )
431+ return 0 ;
432+ (*packet)+=9 ; // Must be 254 when here
433+ /*
434+ In our client-server protocol all numbers bigger than 2^24
435+ stored as 8 bytes with uint8korr. Here we always know that
436+ parameter length is less than 2^32 so don't look at the second
437+ 4 bytes. But still we need to obey the protocol hence 9 in the
438+ assignment above.
439+ */
440+ length= uint4korr (pos+1 );
425441 }
426- if (len < 5 )
442+ if (pos + len < *packet + length )
427443 return 0 ;
428- (*packet)+=9 ; // Must be 254 when here
429- /*
430- In our client-server protocol all numbers bigger than 2^24
431- stored as 8 bytes with uint8korr. Here we always know that
432- parameter length is less than 2^4 so don't look at the second
433- 4 bytes. But still we need to obey the protocol hence 9 in the
434- assignment above.
435- */
436- return (ulong) uint4korr (pos+1 );
444+ return length;
437445}
438446#else
439447#define get_param_length (packet, len ) len
@@ -648,7 +656,12 @@ void Item_param::set_param_date(uchar **pos, ulong len)
648656*/
649657void Item_param::set_param_time (uchar **pos, ulong len)
650658{
651- MYSQL_TIME tm= *((MYSQL_TIME *)*pos);
659+ MYSQL_TIME tm;
660+ if (len >= sizeof (MYSQL_TIME ))
661+ tm= *((MYSQL_TIME *)*pos);
662+ else
663+ set_zero_time (&tm, MYSQL_TIMESTAMP_TIME );
664+
652665 tm.hour += tm.day * 24 ;
653666 tm.day = tm.year = tm.month = 0 ;
654667 if (tm.hour > 838 )
@@ -663,15 +676,23 @@ void Item_param::set_param_time(uchar **pos, ulong len)
663676
664677void Item_param::set_param_datetime (uchar **pos, ulong len)
665678{
666- MYSQL_TIME tm= *((MYSQL_TIME *)*pos);
679+ MYSQL_TIME tm;
680+ if (len >= sizeof (MYSQL_TIME ))
681+ tm= *((MYSQL_TIME *)*pos);
682+ else
683+ set_zero_time (&tm, MYSQL_TIMESTAMP_DATETIME );
667684 tm.neg = 0 ;
668685 set_time (&tm, MYSQL_TIMESTAMP_DATETIME , MAX_DATETIME_WIDTH );
669686}
670687
671688void Item_param::set_param_date (uchar **pos, ulong len)
672689{
673- MYSQL_TIME *to= (MYSQL_TIME *)*pos;
674- set_time (to, MYSQL_TIMESTAMP_DATE , MAX_DATE_WIDTH );
690+ MYSQL_TIME tm;
691+ if (len >= sizeof (MYSQL_TIME ))
692+ tm= *((MYSQL_TIME *)*pos);
693+ else
694+ set_zero_time (&tm, MYSQL_TIMESTAMP_DATE );
695+ set_time (&tm, MYSQL_TIMESTAMP_DATE , MAX_DATE_WIDTH );
675696}
676697#endif /* !EMBEDDED_LIBRARY*/
677698
@@ -683,8 +704,6 @@ void Item_param::set_param_str(uchar **pos, ulong len)
683704 set_null ();
684705 else
685706 {
686- if (length > len)
687- length= len;
688707 /*
689708 We use &my_charset_bin here. Conversion and setting real character
690709 sets will be done in Item_param::convert_str_value(), after the
@@ -1610,13 +1629,15 @@ static int mysql_test_select(Prepared_statement *stmt,
16101629
16111630 lex->first_select_lex ()->context .resolve_in_select_list = TRUE ;
16121631
1613- privilege_t privilege (lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL );
1632+ if (lex->exchange && check_global_access (thd, FILE_ACL , false ))
1633+ goto error;
1634+
16141635 if (tables)
16151636 {
1616- if (check_table_access (thd, privilege , tables, FALSE , UINT_MAX , FALSE ))
1637+ if (check_table_access (thd, SELECT_ACL , tables, FALSE , UINT_MAX , FALSE ))
16171638 goto error;
16181639 }
1619- else if (check_access (thd, privilege , any_db.str , NULL , NULL , 0 , 0 ))
1640+ else if (check_access (thd, SELECT_ACL , any_db.str , NULL , NULL , 0 , 0 ))
16201641 goto error;
16211642
16221643 if (!lex->result && !(lex->result = new (stmt->mem_root ) select_send (thd)))
0 commit comments