I spotted a filename encoding error when using "delete on pool cleanup"
with svn_io_open_unique_file3(). I have not tested this, but I believe
this bug would fail to clean up the temp file if the UTF-8 encoding of
the directory path differs from its APR encoding.
How can I easily test this in my Ubuntu UTF-8 environment?
- Julian
Fix a filename encoding error when using "delete on pool cleanup" with
svn_io_open_unique_file3(). I have not tested this, but I believe this bug
would fail to clean up the temp file if the UTF-8 encoding of the directory
path differs from its APR encoding.
Also update doc strings and parameter names to identify the encoding more
clearly.
* subversion/libsvn_subr/io.c
(file_open): Rename the 'fname' parameter to 'fname_apr' and mention it in
the doc string.
(temp_file_cleanup_s): Rename the 'name' member to 'fname_apr' and
document it.
(temp_file_plain_cleanup_handler, svn_io_open_uniquely_named): Adjust.
(file_perms_set, svn_io_file_name_get): Mention that filename parameters
are in UTF-8, as these are otherwise basically wrappers around APR.
(svn_io_open_unique_file3): Convert the filename to APR encoding before
storing it in the pool-cleanup baton.
--This line, and those below, will be ignored--
Index: subversion/libsvn_subr/io.c
===================================================================
--- subversion/libsvn_subr/io.c (revision 955599)
+++ subversion/libsvn_subr/io.c (working copy)
@@ -243,20 +243,20 @@ io_check_path(const char *path,
}
-/* Wrapper for apr_file_open(). */
+/* Wrapper for apr_file_open(), taking an APR-encoded filename. */
static apr_status_t
file_open(apr_file_t **f,
- const char *fname,
+ const char *fname_apr,
apr_int32_t flag,
apr_fileperms_t perm,
svn_boolean_t retry_on_failure,
apr_pool_t *pool)
{
- apr_status_t status = apr_file_open(f, fname, flag, perm, pool);
+ apr_status_t status = apr_file_open(f, fname_apr, flag, perm, pool);
if (retry_on_failure)
{
- WIN32_RETRY_LOOP(status, apr_file_open(f, fname, flag, perm, pool));
+ WIN32_RETRY_LOOP(status, apr_file_open(f, fname_apr, flag, perm, pool));
}
return status;
}
@@ -292,7 +292,9 @@ svn_io_check_special_path(const char *pa
struct temp_file_cleanup_s
{
apr_pool_t *pool;
- const char *name;
+ /* The (APR-encoded) full path of the file to be removed, or NULL if
+ * nothing to do. */
+ const char *fname_apr;
};
@@ -302,10 +304,10 @@ temp_file_plain_cleanup_handler(void *ba
struct temp_file_cleanup_s *b = baton;
apr_status_t apr_err = APR_SUCCESS;
- if (b->name)
+ if (b->fname_apr)
{
- apr_err = apr_file_remove(b->name, b->pool);
- WIN32_RETRY_LOOP(apr_err, apr_file_remove(b->name, b->pool));
+ apr_err = apr_file_remove(b->fname_apr, b->pool);
+ WIN32_RETRY_LOOP(apr_err, apr_file_remove(b->fname_apr, b->pool));
}
return apr_err;
@@ -354,7 +356,7 @@ svn_io_open_uniquely_named(apr_file_t **
baton = apr_palloc(result_pool, sizeof(*baton));
baton->pool = result_pool;
- baton->name = NULL;
+ baton->fname_apr = NULL;
/* Because cleanups are run LIFO, we need to make sure to register
our cleanup before the apr_file_close cleanup:
@@ -447,7 +449,7 @@ svn_io_open_uniquely_named(apr_file_t **
else
{
if (delete_when == svn_io_file_del_on_pool_cleanup)
- baton->name = apr_pstrdup(result_pool, unique_name_apr);
+ baton->fname_apr = apr_pstrdup(result_pool, unique_name_apr);
if (file)
*file = try_file;
@@ -786,7 +788,7 @@ svn_io_copy_file(const char *src,
return svn_error_return(svn_io_file_rename(dst_tmp, dst, pool));
}
-/* Wrapper for apr_file_perms_set(). */
+/* Wrapper for apr_file_perms_set(), taking a UTF8-encoded filename. */
static svn_error_t *
file_perms_set(const char *fname, apr_fileperms_t perms,
apr_pool_t *pool)
@@ -3665,7 +3667,7 @@ temp_file_create(apr_file_t **new_file,
#endif
}
-/* Wrapper for apr_file_name_get(). */
+/* Wrapper for apr_file_name_get(), passing out a UTF8-encoded filename. */
svn_error_t *
svn_io_file_name_get(const char **filename,
apr_file_t *file,
@@ -3718,7 +3720,7 @@ svn_io_open_unique_file3(apr_file_t **fi
case svn_io_file_del_on_pool_cleanup:
baton = apr_palloc(result_pool, sizeof(*baton));
baton->pool = result_pool;
- baton->name = NULL;
+ baton->fname_apr = NULL;
/* Because cleanups are run LIFO, we need to make sure to register
our cleanup before the apr_file_close cleanup:
@@ -3763,12 +3765,7 @@ svn_io_open_unique_file3(apr_file_t **fi
*unique_path = tempname; /* Was allocated in result_pool */
if (baton)
- {
- if (unique_path)
- baton->name = *unique_path;
- else
- baton->name = tempname; /* Was allocated in result_pool */
- }
+ SVN_ERR(cstring_from_utf8(&baton->fname_apr, tempname, result_pool));
return SVN_NO_ERROR;
}