From: Jaroslav Kysela Date: Thu, 1 Oct 2015 19:52:13 +0000 (+0200) Subject: htsstr_substitute: use temporary string buffer on stack instead static one X-Git-Tag: v4.2.1~2001 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=19d3b902d176f69e6a13d481d624ef7a3e038caf;p=thirdparty%2Ftvheadend.git htsstr_substitute: use temporary string buffer on stack instead static one --- diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 09d92ac52..e55465e9e 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -267,57 +267,61 @@ cleanup_filename(dvr_config_t *cfg, char *s, int dosubs) /** * */ -static char dvrbuf[MAX(PATH_MAX, 512)]; - -static char *dvr_clean_directory_separator(char *s) +static char * +dvr_clean_directory_separator(char *s, char *tmp, size_t tmplen) { char *p, *end; - if (s != dvrbuf) { - end = dvrbuf + sizeof(dvrbuf) - 1; + if (s != tmp) { + end = tmp + tmplen - 1; /* replace directory separator */ - for (p = dvrbuf; *s && p != end; s++, p++) + for (p = tmp; *s && p != end; s++, p++) *p = *s == '/' ? '-' : *s; *p = '\0'; - return dvrbuf; + return tmp; } else { for (; *s; s++) if (*s == '/') *s = '-'; - return dvrbuf; + return tmp; } } -static const char *dvr_do_prefix(const char *id, const char *s) +static const char * +dvr_do_prefix(const char *id, const char *s, char *tmp, size_t tmplen) { if (s == NULL) { - dvrbuf[0] = '\0'; + tmp[0] = '\0'; } else if (s[0] && !isalpha(id[0])) { - snprintf(dvrbuf, sizeof(dvrbuf), "%c%s", id[0], s); + snprintf(tmp, tmplen, "%c%s", id[0], s); } else { - strncpy(dvrbuf, s, sizeof(dvrbuf)-1); - dvrbuf[sizeof(dvrbuf)-1] = '\0'; + strncpy(tmp, s, tmplen-1); + tmp[tmplen-1] = '\0'; } - return dvr_clean_directory_separator(dvrbuf); + return dvr_clean_directory_separator(tmp, tmp, tmplen); } -static const char *dvr_sub_title(const char *id, const void *aux) +static const char * +dvr_sub_title(const char *id, const void *aux, char *tmp, size_t tmplen) { - return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_title, NULL)); + return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_title, NULL), tmp, tmplen); } -static const char *dvr_sub_subtitle(const char *id, const void *aux) +static const char * +dvr_sub_subtitle(const char *id, const void *aux, char *tmp, size_t tmplen) { - return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_subtitle, NULL)); + return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_subtitle, NULL), tmp, tmplen); } -static const char *dvr_sub_description(const char *id, const void *aux) +static const char * +dvr_sub_description(const char *id, const void *aux, char *tmp, size_t tmplen) { - return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_desc, NULL)); + return dvr_do_prefix(id, lang_str_get(((dvr_entry_t *)aux)->de_desc, NULL), tmp, tmplen); } -static const char *dvr_sub_episode(const char *id, const void *aux) +static const char * +dvr_sub_episode(const char *id, const void *aux, char *tmp, size_t tmplen) { const dvr_entry_t *de = aux; char buf[64]; @@ -327,41 +331,47 @@ static const char *dvr_sub_episode(const char *id, const void *aux) epg_episode_number_format(de->de_bcast->episode, buf, sizeof(buf), ".", "S%02d", NULL, "E%02d", NULL); - return dvr_do_prefix(id, buf); + return dvr_do_prefix(id, buf, tmp, tmplen); } -static const char *dvr_sub_channel(const char *id, const void *aux) +static const char * +dvr_sub_channel(const char *id, const void *aux, char *tmp, size_t tmplen) { - return dvr_do_prefix(id, DVR_CH_NAME((dvr_entry_t *)aux)); + return dvr_do_prefix(id, DVR_CH_NAME((dvr_entry_t *)aux), tmp, tmplen); } -static const char *dvr_sub_owner(const char *id, const void *aux) +static const char * +dvr_sub_owner(const char *id, const void *aux, char *tmp, size_t tmplen) { - return dvr_do_prefix(id, ((dvr_entry_t *)aux)->de_owner); + return dvr_do_prefix(id, ((dvr_entry_t *)aux)->de_owner, tmp, tmplen); } -static const char *dvr_sub_creator(const char *id, const void *aux) +static const char * +dvr_sub_creator(const char *id, const void *aux, char *tmp, size_t tmplen) { - return dvr_do_prefix(id, ((dvr_entry_t *)aux)->de_creator); + return dvr_do_prefix(id, ((dvr_entry_t *)aux)->de_creator, tmp, tmplen); } -static const char *dvr_sub_last_error(const char *id, const void *aux) +static const char * +dvr_sub_last_error(const char *id, const void *aux, char *tmp, size_t tmplen) { - return dvr_do_prefix(id, streaming_code2txt(((dvr_entry_t *)aux)->de_last_error)); + return dvr_do_prefix(id, streaming_code2txt(((dvr_entry_t *)aux)->de_last_error), tmp, tmplen); } -static const char *dvr_sub_start(const char *id, const void *aux) +static const char * +dvr_sub_start(const char *id, const void *aux, char *tmp, size_t tmplen) { char buf[16]; snprintf(buf, sizeof(buf), "%"PRItime_t, (time_t)dvr_entry_get_start_time((dvr_entry_t *)aux)); - return dvr_do_prefix(id, buf); + return dvr_do_prefix(id, buf, tmp, tmplen); } -static const char *dvr_sub_stop(const char *id, const void *aux) +static const char * +dvr_sub_stop(const char *id, const void *aux, char *tmp, size_t tmplen) { char buf[16]; snprintf(buf, sizeof(buf), "%"PRItime_t, (time_t)dvr_entry_get_stop_time((dvr_entry_t *)aux)); - return dvr_do_prefix(id, buf); + return dvr_do_prefix(id, buf, tmp, tmplen); } static htsstr_substitute_t dvr_subs_entry[] = { @@ -396,15 +406,16 @@ static htsstr_substitute_t dvr_subs_entry[] = { { .id = NULL, .getval = NULL } }; -static const char *dvr_sub_strftime(const char *id, const void *aux) +static const char * +dvr_sub_strftime(const char *id, const void *aux, char *tmp, size_t tmplen) { char fid[8], *p; snprintf(fid, sizeof(fid), "%%%s", id); - strftime(dvrbuf, sizeof(dvrbuf), fid, (struct tm *)aux); - for (p = dvrbuf; *p; p++) + strftime(tmp, tmplen, fid, (struct tm *)aux); + for (p = tmp; *p; p++) if (*p == ':') *p = '-'; - return dvr_clean_directory_separator(dvrbuf); + return dvr_clean_directory_separator(tmp, tmp, tmplen); } static htsstr_substitute_t dvr_subs_time[] = { @@ -472,16 +483,18 @@ static htsstr_substitute_t dvr_subs_time[] = { { .id = NULL, .getval = NULL } }; -static const char *dvr_sub_str(const char *id, const void *aux) +static const char * +dvr_sub_str(const char *id, const void *aux, char *tmp, size_t tmplen) { return (const char *)aux; } -static const char *dvr_sub_str_separator(const char *id, const void *aux) +static const char * +dvr_sub_str_separator(const char *id, const void *aux, char *tmp, size_t tmplen) { - strncpy(dvrbuf, (const char *)aux, sizeof(dvrbuf)-1); - dvrbuf[sizeof(dvrbuf)-1] = '\0'; - return dvr_clean_directory_separator(dvrbuf); + strncpy(tmp, (const char *)aux, tmplen-1); + tmp[tmplen-1] = '\0'; + return dvr_clean_directory_separator(tmp, tmp, tmplen); } static htsstr_substitute_t dvr_subs_extension[] = { @@ -508,11 +521,12 @@ static htsstr_substitute_t dvr_subs_postproc_entry[] = { { .id = NULL, .getval = NULL } }; -static const char *dvr_sub_basename(const char *id, const void *aux) +static const char * +dvr_sub_basename(const char *id, const void *aux, char *tmp, size_t tmplen) { - strncpy(dvrbuf, (const char *)aux, sizeof(dvrbuf)); - dvrbuf[sizeof(dvrbuf)-1] = '\0'; - return basename(dvrbuf); + strncpy(tmp, (const char *)aux, tmplen); + tmp[tmplen-1] = '\0'; + return basename(tmp); } static htsstr_substitute_t dvr_subs_postproc_filename[] = { @@ -521,7 +535,8 @@ static htsstr_substitute_t dvr_subs_postproc_filename[] = { { .id = NULL, .getval = NULL } }; -static const char *dvr_sub_basic_info(const char *id, const void *aux) +static const char * +dvr_sub_basic_info(const char *id, const void *aux, char *tmp, size_t tmplen) { htsmsg_t *info = (htsmsg_t *)aux, *e; htsmsg_field_t *f; @@ -533,13 +548,13 @@ static const char *dvr_sub_basic_info(const char *id, const void *aux) if (!info) return ""; - dvrbuf[0] = '\0'; + tmp[0] = '\0'; HTSMSG_FOREACH(f, info) { if (!(e = htsmsg_field_get_map(f))) continue; if ((s = htsmsg_get_str(e, "type")) != NULL) continue; - tvh_strlcatf(dvrbuf, sizeof(dvrbuf), l, "%s%s", l > 0 ? "," : "", s); + tvh_strlcatf(tmp, tmplen, l, "%s%s", l > 0 ? "," : "", s); } - return dvrbuf; + return tmp; } static htsstr_substitute_t dvr_subs_postproc_info[] = { @@ -589,6 +604,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) char path[PATH_MAX]; char ptmp[PATH_MAX]; char number[16]; + char tmp[MAX(PATH_MAX, 512)]; char *lastpath = NULL; int tally = 0; struct stat st; @@ -634,7 +650,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) fmtstr++; /* Substitute DVR entry formatters */ - htsstr_substitute(fmtstr, path + l, sizeof(path) - l, '$', dvr_subs_entry, de); + htsstr_substitute(fmtstr, path + l, sizeof(path) - l, '$', dvr_subs_entry, de, tmp, sizeof(tmp)); /* Own directory? */ if (de->de_directory) { @@ -644,7 +660,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) else strcpy(filename, path + l); if (dir_dosubs) { - htsstr_substitute(de->de_directory+2, ptmp, sizeof(ptmp), '$', dvr_subs_entry, de); + htsstr_substitute(de->de_directory+2, ptmp, sizeof(ptmp), '$', dvr_subs_entry, de, tmp, sizeof(tmp)); } else { strncpy(ptmp, de->de_directory, sizeof(ptmp)-1); ptmp[sizeof(ptmp)-1] = '\0'; @@ -661,11 +677,11 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) } /* Substitute time formatters */ - htsstr_substitute(path + l, filename, sizeof(filename), '%', dvr_subs_time, &tm); + htsstr_substitute(path + l, filename, sizeof(filename), '%', dvr_subs_time, &tm, tmp, sizeof(tmp)); /* Substitute extension */ htsstr_substitute(filename, path + l, sizeof(path) - l, '$', dvr_subs_extension, - muxer_suffix(de->de_chain->prch_muxer, ss) ?: ""); + muxer_suffix(de->de_chain->prch_muxer, ss) ?: "", tmp, sizeof(tmp)); /* Cleanup all directory names */ x = path + l; @@ -727,7 +743,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) filename[l] = '\0'; } - htsstr_substitute(filename + j, ptmp, sizeof(ptmp), '$', dvr_subs_tally, number); + htsstr_substitute(filename + j, ptmp, sizeof(ptmp), '$', dvr_subs_tally, number, tmp, sizeof(tmp)); s = cleanup_filename(cfg, ptmp, 1); if (s == NULL) { free(lastpath); @@ -1200,6 +1216,7 @@ static void dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc) { char buf1[2048], *buf2; + char tmp[MAX(PATH_MAX, 512)]; const char *filename; htsmsg_t *info, *e; htsmsg_field_t *f; @@ -1216,12 +1233,12 @@ dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc) } /* Substitute DVR entry formatters */ - htsstr_substitute(dvr_postproc, buf1, sizeof(buf1), '%', dvr_subs_postproc_entry, de); + htsstr_substitute(dvr_postproc, buf1, sizeof(buf1), '%', dvr_subs_postproc_entry, de, tmp, sizeof(tmp)); buf2 = tvh_strdupa(buf1); /* Substitute filename formatters */ - htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_filename, filename); + htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_filename, filename, tmp, sizeof(tmp)); /* Substitute info formatters */ - htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_info, info); + htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_info, info, tmp, sizeof(tmp)); args = htsstr_argsplit(buf1); /* no arguments at all */ diff --git a/src/htsstr.c b/src/htsstr.c index 923bfedbc..3fc157bad 100644 --- a/src/htsstr.c +++ b/src/htsstr.c @@ -187,7 +187,8 @@ htsstr_argsplit_free(char **argv) { char * htsstr_substitute(const char *src, char *dst, size_t dstlen, - int first, htsstr_substitute_t *sub, const void *aux) + int first, htsstr_substitute_t *sub, const void *aux, + char *tmp, size_t tmplen) { htsstr_substitute_t *s; const char *p, *x, *v; @@ -219,7 +220,7 @@ htsstr_substitute(const char *src, char *dst, size_t dstlen, if (*p == '\0') { src = x; if ((l = dstlen) > 0) { - v = s->getval(s->id, aux); + v = s->getval(s->id, aux, tmp, tmplen); strncpy(dst, v, l); l = MIN(strlen(v), l); dst += l; diff --git a/src/htsstr.h b/src/htsstr.h index f943522e7..24a9ff4e0 100644 --- a/src/htsstr.h +++ b/src/htsstr.h @@ -33,11 +33,12 @@ void htsstr_argsplit_free(char **argv); typedef struct { const char *id; - const char *(*getval)(const char *id, const void *aux); + const char *(*getval)(const char *id, const void *aux, char *tmp, size_t tmplen); } htsstr_substitute_t; char * htsstr_substitute(const char *src, char *dst, size_t dstlen, - int first, htsstr_substitute_t *sub, const void *aux); + int first, htsstr_substitute_t *sub, const void *aux, + char *tmp, size_t tmplen); #endif /* HTSSTR_H__ */