From e411b74a16a12f95c52f0c7a4c9c4f0ab1a3bc8d Mon Sep 17 00:00:00 2001 From: Matthias Stock Date: Mon, 18 Nov 2024 18:10:17 +0100 Subject: [PATCH] Use explicit file protocol for AVIO AVIO expects a `url` to locate a resource. Use the file protocol to handle filenames containing colons. Fixes #5487 PR #5499 Signed-off-by: Romain Vimont --- app/src/recorder.c | 10 ++++++++-- app/src/util/str.c | 20 ++++++++++++++++++++ app/src/util/str.h | 9 +++++++++ app/tests/test_str.c | 11 +++++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/app/src/recorder.c b/app/src/recorder.c index 9e0b3395..15f27157 100644 --- a/app/src/recorder.c +++ b/app/src/recorder.c @@ -143,8 +143,14 @@ sc_recorder_open_output_file(struct sc_recorder *recorder) { return false; } - int ret = avio_open(&recorder->ctx->pb, recorder->filename, - AVIO_FLAG_WRITE); + char *file_url = sc_str_concat("file:", recorder->filename); + if (!file_url) { + avformat_free_context(recorder->ctx); + return false; + } + + int ret = avio_open(&recorder->ctx->pb, file_url, AVIO_FLAG_WRITE); + free(file_url); if (ret < 0) { LOGE("Failed to open output file: %s", recorder->filename); avformat_free_context(recorder->ctx); diff --git a/app/src/util/str.c b/app/src/util/str.c index 755369d8..304cd302 100644 --- a/app/src/util/str.c +++ b/app/src/util/str.c @@ -64,6 +64,26 @@ sc_str_quote(const char *src) { return quoted; } +char * +sc_str_concat(const char *start, const char *end) { + assert(start); + assert(end); + + size_t start_len = strlen(start); + size_t end_len = strlen(end); + + char *result = malloc(start_len + end_len + 1); + if (!result) { + LOG_OOM(); + return NULL; + } + + memcpy(result, start, start_len); + memcpy(result + start_len, end, end_len + 1); + + return result; +} + bool sc_str_parse_integer(const char *s, long *out) { char *endptr; diff --git a/app/src/util/str.h b/app/src/util/str.h index 20da26f0..d20f1b28 100644 --- a/app/src/util/str.h +++ b/app/src/util/str.h @@ -38,6 +38,15 @@ sc_str_join(char *dst, const char *const tokens[], char sep, size_t n); char * sc_str_quote(const char *src); +/** + * Concat two strings + * + * Return a new allocated string, contanining the concatenation of the two + * input strings. + */ +char * +sc_str_concat(const char *start, const char *end); + /** * Parse `s` as an integer into `out` * diff --git a/app/tests/test_str.c b/app/tests/test_str.c index 5d365ef5..4a906d92 100644 --- a/app/tests/test_str.c +++ b/app/tests/test_str.c @@ -141,6 +141,16 @@ static void test_quote(void) { free(out); } +static void test_concat(void) { + const char *s = "2024:11"; + char *out = sc_str_concat("my-prefix:", s); + + // contains the concat + assert(!strcmp("my-prefix:2024:11", out)); + + free(out); +} + static void test_utf8_truncate(void) { const char *s = "aÉbÔc"; assert(strlen(s) == 7); // É and Ô are 2 bytes-wide @@ -389,6 +399,7 @@ int main(int argc, char *argv[]) { test_join_truncated_before_sep(); test_join_truncated_after_sep(); test_quote(); + test_concat(); test_utf8_truncate(); test_parse_integer(); test_parse_integers();