Commit 33aceabe authored by Dan Torop's avatar Dan Torop

disk: don't modify filename pattern in dt_imageio_disk_t on store()

The filename pattern may be used by other calls to store() in the same
instance of this module. A pattern which needs fixing in one call to
store(), say if a variable expands to a null string, may not need
fixing in a later call to store().

This fixes #12098.

Also, be sure not to go into an infinite loop if there is no space to
append a filename to the pattern.
parent 56880c85
......@@ -208,25 +208,23 @@ int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, co
char filename[PATH_MAX] = { 0 };
char input_dir[PATH_MAX] = { 0 };
char pattern[DT_MAX_PATH_FOR_PARAMS];
g_strlcpy(pattern, d->filename, sizeof(pattern));
gboolean from_cache = FALSE;
dt_image_full_path(imgid, input_dir, sizeof(input_dir), &from_cache);
int fail = 0;
// we're potentially called in parallel. have sequence number synchronized:
// caching this allows to add "$(FILE_NAME)" to the end of the original string without caring
// about a potentially added "_$(SEQUENCE)"
char *original_filename = g_strdup(d->filename);
// avoid braindead export which is bound to overwrite at random:
if(total > 1 && !g_strrstr(d->filename, "$"))
if(total > 1 && !g_strrstr(pattern, "$"))
snprintf(d->filename + strlen(d->filename), sizeof(d->filename) - strlen(d->filename), "_$(SEQUENCE)");
snprintf(pattern + strlen(pattern), sizeof(pattern) - strlen(pattern), "_$(SEQUENCE)");
gchar *fixed_path = dt_util_fix_path(d->filename);
g_strlcpy(d->filename, fixed_path, sizeof(d->filename));
gchar *fixed_path = dt_util_fix_path(pattern);
g_strlcpy(pattern, fixed_path, sizeof(pattern));
d->vp->filename = input_dir;
......@@ -234,20 +232,25 @@ try_again:
d->vp->imgid = imgid;
d->vp->sequence = num;
gchar *result_filename = dt_variables_expand(d->vp, d->filename, TRUE);
gchar *result_filename = dt_variables_expand(d->vp, pattern, TRUE);
g_strlcpy(filename, result_filename, sizeof(filename));
// if filenamepattern is a directory just add ${FILE_NAME} as default..
// this can happen if the filename component of the pattern is an empty variable
char last_char = *(filename + strlen(filename) - 1);
if(last_char == '/' || last_char == '\\')
snprintf(d->filename, sizeof(d->filename), "%s" G_DIR_SEPARATOR_S "$(FILE_NAME)", original_filename);
goto try_again;
// don't loop forever if there's no room to add a filename
if(strlen(pattern)-sizeof(pattern) > strlen("/$(FILE_NAME)"))
// add to the end of the original pattern without caring about a
// potentially added "_$(SEQUENCE)"
snprintf(pattern, sizeof(pattern), "%s" G_DIR_SEPARATOR_S "$(FILE_NAME)", d->filename);
goto try_again;
char *output_dir = g_path_get_dirname(filename);
if(g_mkdir_with_parents(output_dir, 0755))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment