BLI_path: remove FILE_MAX limit on BLI_path_frame{_range} functions

- Use BLI_str_replace_range to avoid a temporary string copy.
- Also add a buffer size argument to BLI_path_frame_range.
This commit is contained in:
Campbell Barton
2023-05-15 09:09:08 +10:00
parent 1d371706cf
commit 13a3dfd788
5 changed files with 36 additions and 24 deletions

View File

@@ -164,13 +164,13 @@ static void filepath_avi(char *filepath, const RenderData *rd, bool preview, con
if (rd->scemode & R_EXTENSION) {
if (!BLI_path_extension_check(filepath, ".avi")) {
BLI_path_frame_range(filepath, sfra, efra, 4);
BLI_path_frame_range(filepath, FILE_MAX, sfra, efra, 4);
BLI_strncat(filepath, ".avi", FILE_MAX);
}
}
else {
if (BLI_path_frame_check_chars(filepath)) {
BLI_path_frame_range(filepath, sfra, efra, 4);
BLI_path_frame_range(filepath, FILE_MAX, sfra, efra, 4);
}
}

View File

@@ -1406,7 +1406,7 @@ static void ffmpeg_filepath_get(FFMpegContext *context,
if (*fe == NULL) {
BLI_strncat(string, autosplit, FILE_MAX);
BLI_path_frame_range(string, sfra, efra, 4);
BLI_path_frame_range(string, FILE_MAX, sfra, efra, 4);
BLI_strncat(string, *exts, FILE_MAX);
}
else {
@@ -1417,7 +1417,7 @@ static void ffmpeg_filepath_get(FFMpegContext *context,
}
else {
if (BLI_path_frame_check_chars(string)) {
BLI_path_frame_range(string, sfra, efra, 4);
BLI_path_frame_range(string, FILE_MAX, sfra, efra, 4);
}
BLI_strncat(string, autosplit, FILE_MAX);

View File

@@ -446,7 +446,8 @@ bool BLI_path_frame(char *path, size_t path_maxncpy, int frame, int digits) ATTR
* with sta and end as decimal integers, with leading zeroes as necessary, to make digits
* digits each, with a hyphen in-between.
*/
bool BLI_path_frame_range(char *path, int sta, int end, int digits) ATTR_NONNULL(1);
bool BLI_path_frame_range(char *path, size_t path_maxncpy, int sta, int end, int digits)
ATTR_NONNULL(1);
/**
* Get the frame from a filename formatted by blender's frame scheme
*/

View File

@@ -45,6 +45,14 @@ static int BLI_path_unc_prefix_len(const char *path);
static bool BLI_path_is_abs_win32(const char *path);
#endif /* WIN32 */
/**
* The maximum number of `#` characters expanded for #BLI_path_frame & #BLI_path_frame_range
* Typically 12 is enough and even 16 is very large.
* Use a much larger value so hitting the upper limit is not an issue.
* Exceeding this limit won't fail either, it will just not insert so many leading zeros.
*/
#define FILENAME_FRAME_CHARS_MAX FILE_MAX
int BLI_path_sequence_decode(const char *path,
char *head,
const size_t head_maxncpy,
@@ -885,18 +893,19 @@ bool BLI_path_frame(char *path, size_t path_maxncpy, int frame, int digits)
ensure_digits(path, digits);
}
if (stringframe_chars(path, &ch_sta, &ch_end)) { /* Warning: `ch_end` is the last # +1. */
char tmp[FILE_MAX];
SNPRINTF(tmp, "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
BLI_strncpy(path, tmp, path_maxncpy);
if (stringframe_chars(path, &ch_sta, &ch_end)) {
char frame_str[FILENAME_FRAME_CHARS_MAX + 1]; /* One for null. */
const int ch_span = MIN2(ch_end - ch_sta, FILENAME_FRAME_CHARS_MAX);
BLI_snprintf(frame_str, sizeof(frame_str), "%.*d", ch_span, frame);
BLI_str_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str);
return true;
}
return false;
}
bool BLI_path_frame_range(char *path, int sta, int end, int digits)
bool BLI_path_frame_range(char *path, size_t path_maxncpy, int sta, int end, int digits)
{
BLI_string_debug_size_after_nil(path, FILE_MAX);
BLI_string_debug_size_after_nil(path, path_maxncpy);
int ch_sta, ch_end;
@@ -904,18 +913,11 @@ bool BLI_path_frame_range(char *path, int sta, int end, int digits)
ensure_digits(path, digits);
}
if (stringframe_chars(path, &ch_sta, &ch_end)) { /* Warning: `ch_end` is the last # +1. */
char tmp[FILE_MAX];
SNPRINTF(tmp,
"%.*s%.*d-%.*d%s",
ch_sta,
path,
ch_end - ch_sta,
sta,
ch_end - ch_sta,
end,
path + ch_end);
BLI_strncpy(path, tmp, FILE_MAX);
if (stringframe_chars(path, &ch_sta, &ch_end)) {
char frame_str[(FILENAME_FRAME_CHARS_MAX * 2) + 1 + 1]; /* One for null, one for the '-' */
const int ch_span = MIN2(ch_end - ch_sta, FILENAME_FRAME_CHARS_MAX);
BLI_snprintf(frame_str, sizeof(frame_str), "%.*d-%.*d", ch_span, sta, ch_span, end);
BLI_str_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str);
return true;
}
return false;

View File

@@ -638,6 +638,15 @@ TEST(path_util, Frame)
EXPECT_TRUE(ret);
EXPECT_STREQ(path, "test_-0100");
}
/* Ensure very large ranges work. */
{
char path[FILE_MAX * 2];
memset(path, '#', sizeof(path));
path[sizeof(path) - 1] = '\0';
ret = BLI_path_frame(path, sizeof(path), 123456789, 0);
EXPECT_TRUE(BLI_str_endswith(path, "0123456789"));
}
}
/** \} */
@@ -987,7 +996,7 @@ TEST(path_util, FrameCheckChars)
char path[FILE_MAX]; \
bool ret; \
STRNCPY(path, input_path); \
ret = BLI_path_frame_range(path, sta, end, digits); \
ret = BLI_path_frame_range(path, sizeof(path), sta, end, digits); \
if (expect_outpath == nullptr) { \
EXPECT_FALSE(ret); \
} \