mod_proxy_ftp: NULL pointer dereference on error paths.
[Stefan Fritsch <sf fritsch.de>, Joe Orton]
+ *) mod_dav_fs: Don't delete the whole file if a PUT with content-range failed.
+ PR 42896. [Stefan Fritsch]
+
*) mod_dav_fs: Make PUT create files atomically and no longer destroy the
old file if the transfer aborted. PR 39815. [Paul Querna, Stefan Fritsch]
apr_file_t *f;
const char *pathname; /* we may need to remove it at close time */
const char *temppath;
+ int unlink_on_error;
};
/* returns an appropriate HTTP status code given an APR status code for a
ds->p = p;
ds->pathname = resource->info->pathname;
ds->temppath = NULL;
+ ds->unlink_on_error = 0;
if (mode == DAV_MODE_WRITE_TRUNC) {
ds->temppath = apr_pstrcat(p, ap_make_dirstr_parent(p, ds->pathname),
apr_pool_cleanup_register(p, ds, tmpfile_cleanup,
apr_pool_cleanup_null);
}
+ else if (mode == DAV_MODE_WRITE_SEEKABLE) {
+ rv = apr_file_open(&ds->f, ds->pathname, flags | APR_FOPEN_EXCL,
+ APR_OS_DEFAULT, ds->p);
+ if (rv == APR_SUCCESS) {
+ /* we have created a new file */
+ ds->unlink_on_error = 1;
+ }
+ else if (APR_STATUS_IS_EEXIST(rv)) {
+ rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT,
+ ds->p);
+ }
+ }
else {
rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
}
if (stream->temppath) {
apr_pool_cleanup_run(stream->p, stream, tmpfile_cleanup);
}
- else {
+ else if (stream->unlink_on_error) {
if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) {
/* ### use a better description? */
return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,