aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2023-04-21 12:52:17 -0700
committerGitHub <noreply@github.com>2023-04-21 12:52:17 -0700
commitf4b89469b341bf2c1c156838cf162172430267d3 (patch)
tree3881b8318a450c9bbf63c12cec55b51a3fa2f888
parente383ce5d823a21bd82511ab9c10aa916fcc8cebd (diff)
parenta13b5cc08dab4763f8e780558bb3f5a0b6187a37 (diff)
downloadpugixml-f4b89469b341bf2c1c156838cf162172430267d3.zip
pugixml-f4b89469b341bf2c1c156838cf162172430267d3.tar.gz
pugixml-f4b89469b341bf2c1c156838cf162172430267d3.tar.bz2
Merge pull request #561 from zeux/file-size
Fix get_file_size behavior inconsistency for folders
-rw-r--r--src/pugixml.cpp17
-rw-r--r--tests/test_document.cpp2
2 files changed, 17 insertions, 2 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 2f15073..3d2f582 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -40,6 +40,11 @@
// For placement new
#include <new>
+// For load_file
+#if defined(__linux__) || defined(__APPLE__)
+#include <sys/stat.h>
+#endif
+
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
@@ -4759,7 +4764,17 @@ PUGI_IMPL_NS_BEGIN
// we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick
PUGI_IMPL_FN xml_parse_status get_file_size(FILE* file, size_t& out_result)
{
- #if defined(PUGI_IMPL_MSVC_CRT_VERSION) && PUGI_IMPL_MSVC_CRT_VERSION >= 1400
+ #if defined(__linux__) || defined(__APPLE__)
+ // this simultaneously retrieves the file size and file mode (to guard against loading non-files)
+ struct stat st;
+ if (fstat(fileno(file), &st) != 0) return status_io_error;
+
+ // anything that's not a regular file doesn't have a coherent length
+ if (!S_ISREG(st.st_mode)) return status_io_error;
+
+ typedef off_t length_type;
+ length_type length = st.st_size;
+ #elif defined(PUGI_IMPL_MSVC_CRT_VERSION) && PUGI_IMPL_MSVC_CRT_VERSION >= 1400
// there are 64-bit versions of fseek/ftell, let's use them
typedef __int64 length_type;
diff --git a/tests/test_document.cpp b/tests/test_document.cpp
index 2e2904d..2226177 100644
--- a/tests/test_document.cpp
+++ b/tests/test_document.cpp
@@ -589,7 +589,7 @@ TEST(document_load_file_wide_out_of_memory)
CHECK(result.status == status_out_of_memory || result.status == status_file_not_found);
}
-#if defined(__APPLE__)
+#if defined(__linux__) || defined(__APPLE__)
TEST(document_load_file_special_folder)
{
xml_document doc;