@@ -1171,8 +1171,9 @@ static void print_tab_data(MYSQL_RES *result);
11711171static void print_table_data_vertically (MYSQL_RES *result);
11721172static void print_warnings (void );
11731173static void print_last_query_cost (void );
1174- static void end_timer (ulonglong start_time, char *buff);
1175- static void nice_time (double sec,char *buff,bool part_second);
1174+ static void end_timer (ulonglong start_time, char *buff, size_t buff_size);
1175+ static void nice_time (double sec, char *buff, size_t buff_size,
1176+ bool part_second);
11761177extern " C" sig_handler mysql_end (int sig) __attribute__ ((noreturn));
11771178extern " C" sig_handler handle_sigint (int sig);
11781179#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
@@ -1442,18 +1443,20 @@ int main(int argc,char *argv[])
14421443 histfile=my_strdup (PSI_NOT_INSTRUMENTED , histfile, MYF (MY_WME ));
14431444 else if ((home= getenv (" HOME" )))
14441445 {
1446+ size_t histfile_size=
1447+ strlen (home) + strlen (" /.mysql_history" ) + 2 ;
14451448 histfile=(char *) my_malloc (PSI_NOT_INSTRUMENTED ,
1446- strlen (home) + strlen ( " /.mariadb_history " )+ 2 , MYF (MY_WME ));
1449+ histfile_size , MYF (MY_WME ));
14471450 if (histfile)
14481451 {
1449- sprintf (histfile," %s/.mariadb_history" , home);
1452+ snprintf (histfile, histfile_size, " %s/.mariadb_history" , home);
14501453 if (my_access (histfile, F_OK ))
14511454 {
14521455 /* no .mariadb_history, look for historical name and use if present */
1453- sprintf (histfile," %s/.mysql_history" , home);
1456+ snprintf (histfile, histfile_size, " %s/.mysql_history" , home);
14541457 /* and go back to original if not found */
14551458 if (my_access (histfile, F_OK ))
1456- sprintf (histfile," %s/.mariadb_history" , home);
1459+ snprintf (histfile, histfile_size, " %s/.mariadb_history" , home);
14571460 }
14581461 char link_name[FN_REFLEN ];
14591462 if (my_readlink (link_name, histfile, 0 ) == 0 &&
@@ -1499,7 +1502,7 @@ int main(int argc,char *argv[])
14991502
15001503#endif
15011504
1502- sprintf (buff, " %s" ,
1505+ snprintf (buff, sizeof (buff) , " %s" ,
15031506 " Type 'help;' or '\\ h' for help. Type '\\ c' to clear the current input statement.\n " );
15041507 put_info (buff,INFO_INFO );
15051508 status.exit_status = read_and_execute (!status.batch );
@@ -1670,7 +1673,7 @@ bool kill_query(const char *reason)
16701673 interrupted_query= 2 ;
16711674
16721675 /* kill_buffer is always big enough because max length of %lu is 15 */
1673- sprintf (kill_buffer, " KILL %s%lu" ,
1676+ snprintf (kill_buffer, sizeof (kill_buffer) , " KILL %s%lu" ,
16741677 (interrupted_query == 1 ) ? " QUERY " : " " ,
16751678 mysql_thread_id (&mysql));
16761679 if (verbose)
@@ -2734,7 +2737,7 @@ static bool add_line(String &buffer, char *line, size_t line_length,
27342737 }
27352738 else
27362739 {
2737- sprintf (buff," Unknown command '\\ %c'." ,inchar);
2740+ snprintf (buff, sizeof (buff), " Unknown command '\\ %c'." , inchar);
27382741 if (put_info (buff,INFO_ERROR ) > 0 )
27392742 DBUG_RETURN (1 );
27402743 *out++=' \\ ' ;
@@ -3263,7 +3266,7 @@ You can turn off this feature to get a quicker startup with -A\n\n");
32633266 j=0 ;
32643267 while ((sql_field=mysql_fetch_field (fields)))
32653268 {
3266- sprintf (buf," %.64s.%.64s" ,table_row[0 ],sql_field->name );
3269+ snprintf (buf, sizeof (buf), " %.64s.%.64s" ,table_row[0 ], sql_field->name );
32673270 field_names[i][j] = strdup_root (&hash_mem_root,buf);
32683271 add_word (&ht,field_names[i][j]);
32693272 field_names[i][num_fields+j] = strdup_root (&hash_mem_root,
@@ -3707,7 +3710,7 @@ static int com_go(String *buffer, char *)
37073710
37083711 report_progress_end ();
37093712 if (verbose >= 3 || !opt_silent)
3710- end_timer (timer, time_buff);
3713+ end_timer (timer, time_buff, sizeof (time_buff) );
37113714 else
37123715 time_buff[0 ]= ' \0 ' ;
37133716
@@ -3743,9 +3746,9 @@ static int com_go(String *buffer, char *)
37433746 print_tab_data (result);
37443747 else
37453748 print_table_data (result);
3746- sprintf (buff," %ld %s in set" ,
3747- (long ) mysql_num_rows (result),
3748- ( long ) mysql_num_rows (result) == 1 ? " row" : " rows" );
3749+ snprintf (buff, sizeof (buff), " %llu %s in set" ,
3750+ (unsigned long long ) mysql_num_rows (result),
3751+ mysql_num_rows (result) == 1 ? " row" : " rows" );
37493752 end_pager ();
37503753 if (mysql_errno (&mysql))
37513754 {
@@ -3758,9 +3761,9 @@ static int com_go(String *buffer, char *)
37583761 else if (mysql_affected_rows (&mysql) == ~(ulonglong) 0 )
37593762 strmov (buff," Query OK" );
37603763 else
3761- sprintf (buff," Query OK, %ld %s affected" ,
3762- (long ) mysql_affected_rows (&mysql),
3763- ( long ) mysql_affected_rows (&mysql) == 1 ? " row" : " rows" );
3764+ snprintf (buff, sizeof (buff), " Query OK, %llu %s affected" ,
3765+ (unsigned long long ) mysql_affected_rows (&mysql),
3766+ mysql_affected_rows (&mysql) == 1 ? " row" : " rows" );
37643767
37653768 pos=strend (buff);
37663769 if ((warnings= mysql_warning_count (&mysql)))
@@ -3938,7 +3941,7 @@ static char *fieldflags2str(uint f) {
39383941 ff2s_check_flag (ON_UPDATE_NOW );
39393942#undef ff2s_check_flag
39403943 if (f)
3941- sprintf (s, " unknows =0x%04x" , f);
3944+ snprintf (s, sizeof (buf) - ( size_t )(s - buf), " unknown =0x%04x" , f);
39423945 return buf;
39433946}
39443947
@@ -4689,8 +4692,10 @@ com_edit(String *buffer,char *)
46894692 strxmov (buff,editor," " ,filename,NullS);
46904693 if ((error= system (buff)))
46914694 {
4692- char errmsg[100 ];
4693- sprintf (errmsg, " Command '%.40s' failed" , buff);
4695+ #define EDITOR_FAIL_MSG " Command '%.40s' failed"
4696+ char errmsg[sizeof (EDITOR_FAIL_MSG ) - 1 + 40 ];
4697+ snprintf (errmsg, sizeof (errmsg), EDITOR_FAIL_MSG , buff);
4698+ #undef EDITOR_FAIL_MSG
46944699 put_info (errmsg, INFO_ERROR , 0 , NullS);
46954700 goto err;
46964701 }
@@ -4836,9 +4841,9 @@ static int com_connect(String *buffer, char *line)
48364841
48374842 if (connected)
48384843 {
4839- sprintf (buff," Connection id: %lu" ,mysql_thread_id (&mysql));
4844+ snprintf (buff, sizeof (buff), " Connection id: %lu" ,mysql_thread_id (&mysql));
48404845 put_info (buff,INFO_INFO );
4841- sprintf (buff," Current database: %.128s\n " ,
4846+ snprintf (buff, sizeof (buff), " Current database: %.128s\n " ,
48424847 current_db ? current_db : " *** NONE ***" );
48434848 put_info (buff,INFO_INFO );
48444849 }
@@ -5190,7 +5195,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
51905195 if (safe_updates)
51915196 {
51925197 char init_command[100 ];
5193- sprintf (init_command,
5198+ snprintf (init_command, sizeof (init_command) ,
51945199 " SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=%lu,MAX_JOIN_SIZE=%lu" ,
51955200 select_limit,max_join_size);
51965201 mysql_options (&mysql, MYSQL_INIT_COMMAND , init_command);
@@ -5386,7 +5391,7 @@ static int com_status(String *, char *)
53865391 tee_fprintf (stdout, " %.*s\t\t\t " , (int ) (pos-status_str), status_str);
53875392 if ((status_str= str2int (pos,10 ,0 ,LONG_MAX ,(long *) &sec)))
53885393 {
5389- nice_time ((double ) sec,buff,0 );
5394+ nice_time ((double ) sec,buff, sizeof (buff), 0 );
53905395 tee_puts (buff, stdout); /* print nice time */
53915396 while (*status_str == ' ' )
53925397 status_str++; /* to next info */
@@ -5605,8 +5610,10 @@ void tee_putc(int c, FILE *file)
56055610
56065611 len("4294967296 days, 23 hours, 59 minutes, 60.000 seconds") -> 53
56075612*/
5608- static void nice_time (double sec, char *buff, bool part_second)
5613+ static void nice_time (double sec, char *buff, size_t buff_size,
5614+ bool part_second)
56095615{
5616+ char *buff_end= buff + buff_size;
56105617 ulong tmp;
56115618 if (sec >= 3600.0 *24 )
56125619 {
@@ -5630,21 +5637,23 @@ static void nice_time(double sec, char *buff, bool part_second)
56305637 buff=strmov (buff," min " );
56315638 }
56325639 if (part_second)
5633- sprintf (buff," %.3f sec" ,sec);
5640+ snprintf (buff, buff_end - buff, " %.3f sec" , sec);
56345641 else
5635- sprintf (buff," %d sec" ,(int ) sec);
5642+ snprintf (buff, buff_end - buff, " %d sec" , (int ) sec);
56365643}
56375644
56385645
5639- static void end_timer (ulonglong start_time, char *buff)
5646+ static void end_timer (ulonglong start_time, char *buff, size_t buff_size )
56405647{
56415648 double sec;
56425649
5650+ if (buff_size < 4 )
5651+ return ;
56435652 buff[0 ]=' ' ;
56445653 buff[1 ]=' (' ;
56455654 sec= (microsecond_interval_timer () - start_time) / (double ) (1000 * 1000 );
5646- nice_time (sec, buff + 2 , 1 );
5647- strmov (strend (buff)," )" );
5655+ nice_time (sec, buff + 2 , buff_size - 2 , 1 );
5656+ snprintf (strend (buff), buff_size - ( strend (buff) - buff), " )" );
56485657}
56495658
56505659static const char *construct_prompt ()
0 commit comments