History

fftools/textformat: Apply quality improvements

Perform multiple improvements to increase code robustness. In particular: - favor unsigned counters for loops - add missing checks - avoid possible leaks - move variable declarations to inner scopes when feasible - provide explicit type-casting when needed

softworkz committed 1 year ago

Commit 5f90eea1 parent 8f42d907 files · +82 −45Browse files

Showing the changes to fftools/textformat (7 of 7 files). Show all

Unified · Split

7 files
  1. fftools/textformat/avtextformat.c +55 −27
  2. fftools/textformat/avtextformat.h +2 −4
  3. fftools/textformat/tf_default.c +6 −2
  4. fftools/textformat/tf_ini.c +1 −1
  5. fftools/textformat/tf_json.c +10 −7
  6. fftools/textformat/tf_xml.c +0 −3
  7. fftools/textformat/tw_avio.c +8 −1
fftools/textformat/avtextformat.c+55−27
@@ -93,9 +93,8 @@ static const AVClass textcontext_class = { · 92 unmodified lines
9393
9494 static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
9595 {
96− int i;
9796 av_bprintf(bp, "0X");
98− for (i = 0; i < ubuf_size; i++)
97+ for (unsigned i = 0; i < ubuf_size; i++)
9998 av_bprintf(bp, "%02X", ubuf[i]);
10099 }
101100
@@ -137,6 +136,8 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form · 35 unmodified lines
137136 AVTextFormatContext *tctx;
138137 int i, ret = 0;
139138
139+ av_assert0(ptctx && formatter);
140+
140141 if (!(tctx = av_mallocz(sizeof(AVTextFormatContext)))) {
141142 ret = AVERROR(ENOMEM);
142143 goto fail;
@@ -215,8 +216,8 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form · 72 unmodified lines
215216
216217 /* validate replace string */
217218 {
218− const uint8_t *p = tctx->string_validation_replacement;
219− const uint8_t *endp = p + strlen(p);
219+ const uint8_t *p = (uint8_t *)tctx->string_validation_replacement;
220+ const uint8_t *endp = p + strlen((const char *)p);
220221 while (*p) {
221222 const uint8_t *p0 = p;
222223 int32_t code;
@@ -229,6 +230,7 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form · 6 unmodified lines
229230 "Invalid UTF8 sequence %s found in string validation replace '%s'\n",
230231 bp.str, tctx->string_validation_replacement);
231232 return ret;
233+ goto fail;
232234 }
233235 }
234236 }
@@ -256,6 +258,11 @@ static const char unit_bit_per_second_str[] = "bit/s"; · 21 unmodified lines
256258
257259 void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
258260 {
261+ if (section_id < 0 || section_id >= tctx->nb_sections) {
262+ av_log(tctx, AV_LOG_ERROR, "Invalid section_id for section_header: %d\n", section_id);
263+ return;
264+ }
265+
259266 tctx->level++;
260267 av_assert0(tctx->level < SECTION_MAX_NB_LEVELS);
261268
@@ -269,6 +276,11 @@ void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, in · 7 unmodified lines
269276
270277 void avtext_print_section_footer(AVTextFormatContext *tctx)
271278 {
279+ if (tctx->level < 0 || tctx->level >= SECTION_MAX_NB_LEVELS) {
280+ av_log(tctx, AV_LOG_ERROR, "Invalid level for section_footer: %d\n", tctx->level);
281+ return;
282+ }
283+
272284 int section_id = tctx->section[tctx->level]->id;
273285 int parent_section_id = tctx->level ?
274286 tctx->section[tctx->level - 1]->id : SECTION_ID_NONE;
@@ -285,7 +297,11 @@ void avtext_print_section_footer(AVTextFormatContext *tctx) · 10 unmodified lines
285297
286298 void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t val)
287299 {
288− const struct AVTextFormatSection *section = tctx->section[tctx->level];
300+ const AVTextFormatSection *section;
301+
302+ av_assert0(key && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
303+
304+ section = tctx->section[tctx->level];
289305
290306 if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
291307 tctx->formatter->print_integer(tctx, key, val);
@@ -354,17 +370,18 @@ struct unit_value { · 62 unmodified lines
354370 const char *unit;
355371 };
356372
357−static char *value_string(AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv)
373+static char *value_string(const AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv)
358374 {
359375 double vald;
360− int64_t vali;
376+ int64_t vali = 0;
361377 int show_float = 0;
362378
363379 if (uv.unit == unit_second_str) {
364380 vald = uv.val.d;
365381 show_float = 1;
366382 } else {
367− vald = vali = uv.val.i;
383+ vald = (double)uv.val.i;
384+ vali = uv.val.i;
368385 }
369386
370387 if (uv.unit == unit_second_str && tctx->use_value_sexagesimal_format) {
@@ -383,17 +400,17 @@ static char *value_string(AVTextFormatContext *tctx, char *buf, int buf_size, st · 12 unmodified lines
383400 int64_t index;
384401
385402 if (uv.unit == unit_byte_str && tctx->use_byte_value_binary_prefix) {
386− index = (int64_t) (log2(vald)) / 10;
387− index = av_clip(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1);
403+ index = (int64_t)(log2(vald) / 10);
404+ index = av_clip64(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1);
388405 vald /= si_prefixes[index].bin_val;
389406 prefix_string = si_prefixes[index].bin_str;
390407 } else {
391− index = (int64_t) (log10(vald)) / 3;
392− index = av_clip(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1);
408+ index = (int64_t)(log10(vald) / 3);
409+ index = av_clip64(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1);
393410 vald /= si_prefixes[index].dec_val;
394411 prefix_string = si_prefixes[index].dec_str;
395412 }
396− vali = vald;
413+ vali = (int64_t)vald;
397414 }
398415
399416 if (show_float || (tctx->use_value_prefix && vald != (int64_t)vald))
@@ -421,9 +438,13 @@ void avtext_print_unit_int(AVTextFormatContext *tctx, const char *key, int value · 21 unmodified lines
421438
422439 int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *val, int flags)
423440 {
424− const struct AVTextFormatSection *section = tctx->section[tctx->level];
441+ const AVTextFormatSection *section;
425442 int ret = 0;
426443
444+ av_assert0(key && val && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
445+
446+ section = tctx->section[tctx->level];
447+
427448 if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER ||
428449 (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO
429450 && (flags & AV_TEXTFORMAT_PRINT_STRING_OPTIONAL)
@@ -465,12 +486,11 @@ void avtext_print_rational(AVTextFormatContext *tctx, const char *key, AVRationa · 35 unmodified lines
465486 void avtext_print_time(AVTextFormatContext *tctx, const char *key,
466487 int64_t ts, const AVRational *time_base, int is_duration)
467488 {
468− char buf[128];
469−
470489 if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
471490 avtext_print_string(tctx, key, "N/A", AV_TEXTFORMAT_PRINT_STRING_OPTIONAL);
472491 } else {
473− double d = ts * av_q2d(*time_base);
492+ char buf[128];
493+ double d = av_q2d(*time_base) * ts;
474494 struct unit_value uv;
475495 uv.val.d = d;
476496 uv.unit = unit_second_str;
@@ -491,7 +511,8 @@ void avtext_print_data(AVTextFormatContext *tctx, const char *name, · 14 unmodified lines
491511 const uint8_t *data, int size)
492512 {
493513 AVBPrint bp;
494− int offset = 0, l, i;
514+ unsigned offset = 0;
515+ int l, i;
495516
496517 av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
497518 av_bprintf(&bp, "\n");
@@ -518,25 +539,29 @@ void avtext_print_data(AVTextFormatContext *tctx, const char *name, · 20 unmodified lines
518539 void avtext_print_data_hash(AVTextFormatContext *tctx, const char *name,
519540 const uint8_t *data, int size)
520541 {
521− char *p, buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
542+ char buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
543+ int len;
522544
523545 if (!tctx->hash)
524546 return;
525547
526548 av_hash_init(tctx->hash);
527549 av_hash_update(tctx->hash, data, size);
528− snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(tctx->hash));
529− p = buf + strlen(buf);
530− av_hash_final_hex(tctx->hash, p, buf + sizeof(buf) - p);
550+ len = snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(tctx->hash));
551+ av_hash_final_hex(tctx->hash, (uint8_t *)&buf[len], (int)sizeof(buf) - len);
531552 avtext_print_string(tctx, name, buf, 0);
532553 }
533554
534555 void avtext_print_integers(AVTextFormatContext *tctx, const char *name,
535− uint8_t *data, int size, const char *format,
536− int columns, int bytes, int offset_add)
556+ uint8_t *data, int size, const char *format,
557+ int columns, int bytes, int offset_add)
537558 {
538559 AVBPrint bp;
539− int offset = 0, l, i;
560+ unsigned offset = 0;
561+ int l, i;
562+
563+ if (!name || !data || !format || columns <= 0 || bytes <= 0)
564+ return;
540565
541566 av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
542567 av_bprintf(&bp, "\n");
@@ -602,12 +627,15 @@ int avtextwriter_context_open(AVTextWriterContext **pwctx, const AVTextWriter *w · 59 unmodified lines
602627 AVTextWriterContext *wctx;
603628 int ret = 0;
604629
605− if (!(wctx = av_mallocz(sizeof(AVTextWriterContext)))) {
630+ if (!pwctx || !writer)
631+ return AVERROR(EINVAL);
632+
633+ if (!((wctx = av_mallocz(sizeof(AVTextWriterContext))))) {
606634 ret = AVERROR(ENOMEM);
607635 goto fail;
608636 }
609637
610− if (!(wctx->priv = av_mallocz(writer->priv_size))) {
638+ if (writer->priv_size && !((wctx->priv = av_mallocz(writer->priv_size)))) {
611639 ret = AVERROR(ENOMEM);
612640 goto fail;
613641 }
fftools/textformat/avtextformat.h+2−4
@@ -21,9 +21,7 @@ · 20 unmodified lines
2121 #ifndef FFTOOLS_TEXTFORMAT_AVTEXTFORMAT_H
2222 #define FFTOOLS_TEXTFORMAT_AVTEXTFORMAT_H
2323
24−#include <stddef.h>
2524 #include <stdint.h>
26−#include "libavutil/attributes.h"
2725 #include "libavutil/dict.h"
2826 #include "libavformat/avio.h"
2927 #include "libavutil/bprint.h"
@@ -103,7 +101,7 @@ struct AVTextFormatContext { · 73 unmodified lines
103101 unsigned int nb_item_type[SECTION_MAX_NB_LEVELS][SECTION_MAX_NB_SECTIONS];
104102
105103 /** section per each level */
106− const struct AVTextFormatSection *section[SECTION_MAX_NB_LEVELS];
104+ const AVTextFormatSection *section[SECTION_MAX_NB_LEVELS];
107105 AVBPrint section_pbuf[SECTION_MAX_NB_LEVELS]; ///< generic print buffer dedicated to each section,
108106 /// used by various formatters
109107
@@ -124,7 +122,7 @@ struct AVTextFormatContext { · 14 unmodified lines
124122 #define AV_TEXTFORMAT_PRINT_STRING_VALIDATE 2
125123
126124 int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args,
127− const struct AVTextFormatSection *sections, int nb_sections,
125+ const AVTextFormatSection *sections, int nb_sections,
128126 int show_value_unit,
129127 int use_value_prefix,
130128 int use_byte_value_binary_prefix,
fftools/textformat/tf_default.c+6−2
@@ -68,9 +68,10 @@ DEFINE_FORMATTER_CLASS(default); · 67 unmodified lines
6868 /* lame uppercasing routine, assumes the string is lower case ASCII */
6969 static inline char *upcase_string(char *dst, size_t dst_size, const char *src)
7070 {
71− int i;
71+ unsigned i;
72+
7273 for (i = 0; src[i] && i < dst_size - 1; i++)
73− dst[i] = av_toupper(src[i]);
74+ dst[i] = (char)av_toupper(src[i]);
7475 dst[i] = 0;
7576 return dst;
7677 }
@@ -106,6 +107,9 @@ static void default_print_section_footer(AVTextFormatContext *wctx) · 29 unmodified lines
106107 const struct AVTextFormatSection *section = wctx->section[wctx->level];
107108 char buf[32];
108109
110+ if (!section)
111+ return;
112+
109113 if (def->noprint_wrappers || def->nested_section[wctx->level])
110114 return;
111115
fftools/textformat/tf_ini.c+1−1
@@ -91,7 +91,7 @@ static char *ini_escape_str(AVBPrint *dst, const char *src) · 90 unmodified lines
9191 /* fallthrough */
9292 default:
9393 if ((unsigned char)c < 32)
94− av_bprintf(dst, "\\x00%02x", c & 0xff);
94+ av_bprintf(dst, "\\x00%02x", (unsigned char)c);
9595 else
9696 av_bprint_chars(dst, c, 1);
9797 break;
fftools/textformat/tf_json.c+10−7
@@ -80,13 +80,18 @@ static const char *json_escape_str(AVBPrint *dst, const char *src, void *log_ctx · 79 unmodified lines
8080 static const char json_subst[] = { '"', '\\', 'b', 'f', 'n', 'r', 't', 0 };
8181 const char *p;
8282
83+ if (!src) {
84+ av_log(log_ctx, AV_LOG_WARNING, "Cannot escape NULL string, returning NULL\n");
85+ return NULL;
86+ }
87+
8388 for (p = src; *p; p++) {
8489 char *s = strchr(json_escape, *p);
8590 if (s) {
8691 av_bprint_chars(dst, '\\', 1);
8792 av_bprint_chars(dst, json_subst[s - json_escape], 1);
8893 } else if ((unsigned char)*p < 32) {
89− av_bprintf(dst, "\\u00%02x", *p & 0xff);
94+ av_bprintf(dst, "\\u00%02x", (unsigned char)*p);
9095 } else {
9196 av_bprint_chars(dst, *p, 1);
9297 }
@@ -100,11 +105,10 @@ static void json_print_section_header(AVTextFormatContext *wctx, const void *dat · 7 unmodified lines
100105 {
101106 JSONContext *json = wctx->priv;
102107 AVBPrint buf;
103− const struct AVTextFormatSection *section = wctx->section[wctx->level];
104− const struct AVTextFormatSection *parent_section = wctx->level ?
105− wctx->section[wctx->level-1] : NULL;
108+ const AVTextFormatSection *section = wctx->section[wctx->level];
109+ const AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level - 1] : NULL;
106110
107− if (wctx->level && wctx->nb_item[wctx->level-1])
111+ if (wctx->level && wctx->nb_item[wctx->level - 1])
108112 writer_put_str(wctx, ",\n");
109113
110114 if (section->flags & AV_TEXTFORMAT_SECTION_FLAG_IS_WRAPPER) {
@@ -185,8 +189,7 @@ static void json_print_str(AVTextFormatContext *wctx, const char *key, const cha · 74 unmodified lines
185189 static void json_print_int(AVTextFormatContext *wctx, const char *key, int64_t value)
186190 {
187191 JSONContext *json = wctx->priv;
188− const struct AVTextFormatSection *parent_section = wctx->level ?
189− wctx->section[wctx->level-1] : NULL;
192+ const AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level - 1] : NULL;
190193 AVBPrint buf;
191194
192195 if (wctx->nb_item[wctx->level] || (parent_section && parent_section->flags & AV_TEXTFORMAT_SECTION_FLAG_NUMBERING_BY_TYPE))
fftools/textformat/tf_xml.c+0−3
@@ -18,10 +18,7 @@ · 17 unmodified lines
1818 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1919 */
2020
21−#include <limits.h>
22−#include <stdarg.h>
2321 #include <stdint.h>
24−#include <stdio.h>
2522 #include <string.h>
2623
2724 #include "avtextformat.h"
fftools/textformat/tw_avio.c+8−1
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 #include <string.h>
2424
2525 #include "avtextwriters.h"
26+#include "libavutil/avassert.h"
2627
2728 #include "libavutil/error.h"
2829
@@ -53,7 +54,7 @@ static void io_w8(AVTextWriterContext *wctx, int b) · 24 unmodified lines
5354 static void io_put_str(AVTextWriterContext *wctx, const char *str)
5455 {
5556 IOWriterContext *ctx = wctx->priv;
56− avio_write(ctx->avio_context, str, strlen(str));
57+ avio_write(ctx->avio_context, (const unsigned char *)str, (int)strlen(str));
5758 }
5859
5960 static void io_printf(AVTextWriterContext *wctx, const char *fmt, ...)
@@ -81,6 +82,10 @@ int avtextwriter_create_file(AVTextWriterContext **pwctx, const char *output_fil · 21 unmodified lines
8182 IOWriterContext *ctx;
8283 int ret;
8384
85+ if (!output_filename || !output_filename[0]) {
86+ av_log(NULL, AV_LOG_ERROR, "The output_filename cannot be NULL or empty\n");
87+ return AVERROR(EINVAL);
88+ }
8489
8590 ret = avtextwriter_context_open(pwctx, &avtextwriter_avio);
8691 if (ret < 0)
@@ -106,6 +111,8 @@ int avtextwriter_create_avio(AVTextWriterContext **pwctx, AVIOContext *avio_ctx, · 19 unmodified lines
106111 IOWriterContext *ctx;
107112 int ret;
108113
114+ av_assert0(avio_ctx);
115+
109116 ret = avtextwriter_context_open(pwctx, &avtextwriter_avio);
110117 if (ret < 0)
111118 return ret;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t