aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2022-10-07 22:13:04 -0700
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2022-10-07 22:13:04 -0700
commit444963e2690d0a2a05df62429379e633e1dfb1d4 (patch)
tree079031cea961a2f10275e6b076ae5eea88eb8eac
parent0cb4f025791f7c17f8ec09a1c12b0cb107518fad (diff)
downloadpugixml-444963e2690d0a2a05df62429379e633e1dfb1d4.zip
pugixml-444963e2690d0a2a05df62429379e633e1dfb1d4.tar.gz
pugixml-444963e2690d0a2a05df62429379e633e1dfb1d4.tar.bz2
Fix error handling in xml_document::save_file
There were two conditions under which xml_document::save_file could previously return true even though the saving failed: - The last write to the file was buffered in stdio buffer, and it's that last write that would fail due to lack of disk space - The data has been written correctly but fclose failed to update file metadata, which can result in truncated size / missing inode updates. This change fixes both by adjusting save_file to fflush before the check, and also checking fclose results. Note that while fflush here is technically redundant, because it's implied by fclose, we must check ferror explicitly anyway, and so it feels a little cleaner to do most of the error handling in save_file_impl, so that the changes of fclose() failing are very slim. Of course, neither change guarantees that the contents of the file are going to be safe on disk following a power failure.
-rw-r--r--src/pugixml.cpp6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 6b16dbb..7c84038 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -5070,7 +5070,7 @@ PUGI__NS_BEGIN
xml_writer_file writer(file);
doc.save(writer, indent, flags, encoding);
- return ferror(file) == 0;
+ return fflush(file) == 0 && ferror(file) == 0;
}
struct name_null_sentry
@@ -7423,7 +7423,7 @@ namespace pugi
using impl::auto_deleter; // MSVC7 workaround
auto_deleter<FILE> file(impl::open_file(path_, (flags & format_save_file_text) ? "w" : "wb"), impl::close_file);
- return impl::save_file_impl(*this, file.data, indent, flags, encoding);
+ return impl::save_file_impl(*this, file.data, indent, flags, encoding) && fclose(file.release()) == 0;
}
PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const
@@ -7431,7 +7431,7 @@ namespace pugi
using impl::auto_deleter; // MSVC7 workaround
auto_deleter<FILE> file(impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"), impl::close_file);
- return impl::save_file_impl(*this, file.data, indent, flags, encoding);
+ return impl::save_file_impl(*this, file.data, indent, flags, encoding) && fclose(file.release()) == 0;
}
PUGI__FN xml_node xml_document::document_element() const