@@ -539,22 +539,31 @@ parse_option(struct cliopts_priv *ctx,
539539 return WANT_VALUE ;
540540}
541541
542+ static size_t bytes_left (const char * buf , size_t capacity )
543+ {
544+ size_t len = strlen (buf );
545+ if (len >= capacity - 1 ) {
546+ return 0 ;
547+ }
548+ return capacity - len ;
549+ }
550+
542551static char *
543- get_option_name (cliopts_entry * entry , char * buf )
552+ get_option_name (cliopts_entry * entry , char * buf , size_t capacity )
544553{
545554 /* [-s,--option] */
546555 char * bufp = buf ;
547- bufp += sprintf (buf , "[" );
556+ bufp += snprintf (buf , bytes_left ( buf , capacity ) , "[" );
548557 if (entry -> kshort ) {
549- bufp += sprintf (bufp , "-%c" , entry -> kshort );
558+ bufp += snprintf (bufp , bytes_left ( buf , capacity ) , "-%c" , entry -> kshort );
550559 }
551560 if (entry -> klong ) {
552561 if (entry -> kshort ) {
553- bufp += sprintf (bufp , "," );
562+ bufp += snprintf (bufp , bytes_left ( buf , capacity ) , "," );
554563 }
555- bufp += sprintf (bufp , "--%s" , entry -> klong );
564+ bufp += snprintf (bufp , bytes_left ( buf , capacity ) , "--%s" , entry -> klong );
556565 }
557- sprintf (bufp , "]" );
566+ snprintf (bufp , bytes_left ( buf , capacity ) , "]" );
558567 return buf ;
559568}
560569
@@ -576,12 +585,12 @@ static int get_terminal_width(void)
576585
577586static char *
578587format_option_help (cliopts_entry * entry ,
579- char * buf ,
588+ char * buf , size_t capacity ,
580589 struct cliopts_extra_settings * settings )
581590{
582591 char * bufp = buf ;
583592 if (entry -> kshort ) {
584- bufp += sprintf (bufp , " -%c " , entry -> kshort );
593+ bufp += snprintf (bufp , bytes_left ( buf , capacity ) , " -%c " , entry -> kshort );
585594 }
586595
587596#define _advance_margin (offset ) \
@@ -595,11 +604,11 @@ format_option_help(cliopts_entry *entry,
595604 _advance_margin (4 )
596605
597606 if (entry -> klong ) {
598- bufp += sprintf (bufp , " --%s " , entry -> klong );
607+ bufp += snprintf (bufp , bytes_left ( buf , capacity ) , " --%s " , entry -> klong );
599608 }
600609
601610 if (entry -> vdesc ) {
602- bufp += sprintf (bufp , " <%s> " , entry -> vdesc );
611+ bufp += snprintf (bufp , bytes_left ( buf , capacity ) , " <%s> " , entry -> vdesc );
603612 }
604613
605614 _advance_margin (35 )
@@ -664,7 +673,7 @@ print_help(struct cliopts_priv *ctx, struct cliopts_extra_settings *settings)
664673 }
665674
666675 memset (helpbuf , 0 , sizeof (helpbuf ));
667- format_option_help (cur , helpbuf , settings );
676+ format_option_help (cur , helpbuf , sizeof ( helpbuf ), settings );
668677 fprintf (stderr , INDENT "%s" , helpbuf );
669678
670679
@@ -728,7 +737,7 @@ print_help(struct cliopts_priv *ctx, struct cliopts_extra_settings *settings)
728737 }
729738 memset (helpbuf , 0 , sizeof (helpbuf ));
730739 fprintf (stderr , INDENT "%s\n" ,
731- format_option_help (& helpent , helpbuf , settings ));
740+ format_option_help (& helpent , helpbuf , sizeof ( helpbuf ), settings ));
732741
733742}
734743
@@ -747,7 +756,7 @@ dump_error(struct cliopts_priv *ctx)
747756 } else if (ctx -> errnum == CLIOPTS_ERR_ISSWITCH ) {
748757 char optbuf [64 ] = { 0 };
749758 fprintf (stderr , "Option %s takes no arguments" ,
750- get_option_name (ctx -> prev , optbuf ));
759+ get_option_name (ctx -> prev , optbuf , sizeof ( optbuf ) ));
751760 }
752761 fprintf (stderr , "\n" );
753762
@@ -865,7 +874,7 @@ cliopts_parse_options(cliopts_entry *entries,
865874 }
866875
867876 fprintf (stderr , "Required option %s missing\n" ,
868- get_option_name (cur_ent , entbuf ));
877+ get_option_name (cur_ent , entbuf , sizeof ( entbuf ) ));
869878 }
870879 }
871880
0 commit comments