[MPlayer-dev-eng] [PATCH 1/4] String handling audit/cleanup take 2

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Sat Mar 3 15:21:55 CET 2007


Hello,
On Fri, Mar 02, 2007 at 05:28:54PM -0500, Nicholas Kain wrote:
> --- asxparser.c.orig	2007-03-02 02:21:30.000000000 -0500
> +++ asxparser.c	2007-03-02 16:08:57.000000000 -0500
> @@ -118,13 +118,16 @@ asx_warning_attrib_invalid(ASX_Parser_t*
>      len += strlen(ptr[0]);
>      len += ((ptr[1] == NULL) ? 4 : 2);
>    }
> -  str = vals = malloc(len);
> -  vals += sprintf(vals,"%s",valid_vals[0]);
> +  str = malloc(len);
> +  strlcpy(str, valid_vals[0],len);
>    for(ptr = valid_vals + 1 ; ptr[0] != NULL ; ptr++) {
> -    if(ptr[1] == NULL)
> -      vals += sprintf(vals," or %s",ptr[0]);
> -    else
> -      vals += sprintf(vals,", %s",ptr[0]);
> +    if(ptr[1] == NULL) {
> +      strlcat(str, " or ", len);
> +      strlcat(str, ptr[0], len);
> +    } else {
> +      strlcat(str, ", ", len);
> +      strlcat(str, ptr[0], len);
> +    }

Now, this IMO is an example of a good change. But not of the best
possible solution because
1) output of "remote" content in the end should preferably be filtered,
I think there are some console escape sequences that can do some really
non-nice things

>    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"at line %d : attribute %s of element %s is invalid (%s). Valid values are %s",
>  	      parser->line,attrib,elem,val,str);

2) We could just avoid all this string handling problems by splitting
this mp_msg and call mp_msg instead of sprintf in the loop.

Greetings,
Reimar Döffinger
> --- command.c.orig	2007-03-02 05:32:44.000000000 -0500
> +++ command.c	2007-03-02 13:27:51.000000000 -0500
> @@ -290,11 +290,11 @@ static int mp_property_length(m_option_t
>  	    s -= m * 60;
>  	    *(char **) arg = malloc(20);
>  	    if (h > 0)
> -		sprintf(*(char **) arg, "%d:%02d:%02d", h, m, s);
> +		snprintf(*(char **) arg, 20, "%d:%02d:%02d", h, m, s);
>  	    else if (m > 0)
> -		sprintf(*(char **) arg, "%d:%02d", m, s);
> +		snprintf(*(char **) arg, 20, "%d:%02d", m, s);
>  	    else
> -		sprintf(*(char **) arg, "%d", s);
> +		snprintf(*(char **) arg, 20, "%d", s);

Probably a good example for why we should consider asprintf + our own
implementation of it in osdep for systems where it's not available.
Or just doing malloc(100) and not have to think about it further.

> @@ -973,7 +973,6 @@ static int mp_property_sub(m_option_t * 
>  	if (!arg)
>  	    return M_PROPERTY_ERROR;
>  	*(char **) arg = malloc(64);
> -	(*(char **) arg)[63] = 0;
>  	sub_name = 0;
>  	if (subdata)
>  	    sub_name = subdata->filename;
> @@ -987,7 +986,7 @@ static int mp_property_sub(m_option_t * 
>  	    if ((tmp2 = strrchr(tmp, '/')))
>  		tmp = tmp2 + 1;
>  
> -	    snprintf(*(char **) arg, 63, "(%d) %s%s",
> +	    snprintf(*(char **) arg, 64, "(%d) %s%s",
>  		     mpctx->set_of_sub_pos + 1,
>  		     strlen(tmp) < 20 ? "" : "...",
>  		     strlen(tmp) < 20 ? tmp : tmp + strlen(tmp) - 19);
> @@ -998,7 +997,7 @@ static int mp_property_sub(m_option_t * 
>  	    if (vo_spudec && dvdsub_id >= 0) {
>  		unsigned char lang[3];
>  		if (dvdnav_lang_from_sid(mpctx->stream, dvdsub_id, lang)) {
> -		    snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, lang);
> +		    snprintf(*(char **) arg, 64, "(%d) %s", dvdsub_id, lang);
>  		    return M_PROPERTY_OK;
>  		}
>  	    }
> @@ -1008,7 +1007,7 @@ static int mp_property_sub(m_option_t * 
>  	if (mpctx->demuxer->type == DEMUXER_TYPE_MATROSKA && dvdsub_id >= 0) {
>  	    char lang[40] = MSGTR_Unknown;
>  	    demux_mkv_get_sub_lang(mpctx->demuxer, dvdsub_id, lang, 9);
> -	    snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, lang);
> +	    snprintf(*(char **) arg, 64, "(%d) %s", dvdsub_id, lang);
>  	    return M_PROPERTY_OK;
>  	}
>  #ifdef HAVE_OGGVORBIS
> @@ -1016,14 +1015,14 @@ static int mp_property_sub(m_option_t * 
>  	    char *lang = demux_ogg_sub_lang(mpctx->demuxer, dvdsub_id);
>  	    if (!lang)
>  		lang = MSGTR_Unknown;
> -	    snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, lang);
> +	    snprintf(*(char **) arg, 64, "(%d) %s", dvdsub_id, lang);
>  	    return M_PROPERTY_OK;
>  	}
>  #endif
>  	if (vo_vobsub && vobsub_id >= 0) {
>  	    const char *language = MSGTR_Unknown;
>  	    language = vobsub_get_id(vo_vobsub, (unsigned int) vobsub_id);
> -	    snprintf(*(char **) arg, 63, "(%d) %s",
> +	    snprintf(*(char **) arg, 64, "(%d) %s",
>  		     vobsub_id, language ? language : MSGTR_Unknown);
>  	    return M_PROPERTY_OK;
>  	}
> @@ -1035,15 +1034,15 @@ static int mp_property_sub(m_option_t * 
>  	    lang[0] = code >> 8;
>  	    lang[1] = code;
>  	    lang[2] = 0;
> -	    snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, lang);
> +	    snprintf(*(char **) arg, 64, "(%d) %s", dvdsub_id, lang);
>  	    return M_PROPERTY_OK;
>  	}
>  #endif
>  	if (dvdsub_id >= 0) {
> -	    snprintf(*(char **) arg, 63, "(%d) %s", dvdsub_id, MSGTR_Unknown);
> +	    snprintf(*(char **) arg, 64, "(%d) %s", dvdsub_id, MSGTR_Unknown);
>  	    return M_PROPERTY_OK;
>  	}
> -	snprintf(*(char **) arg, 63, MSGTR_Disabled);
> +	snprintf(*(char **) arg, 64, MSGTR_Disabled);
>  	return M_PROPERTY_OK;

Looks fine, code based on confusion of snprintf vs. strncpy behaviour.

I guess I should go about applying those I indicated, any objections to
these?

Greetings,
Reimar Döffinger



More information about the MPlayer-dev-eng mailing list