The expression ``const int newAllocated = cap * 2;`` easily causes
overflow, as soon as the input is 1.0 GiB. This goes unnoticed because
release builds of tinyxml2 do not have active assertions.
The change in commit 9.0.0-20-g8fd6cc6 did not do anything useful;
the signed multiplication overflow (and thus undefined behavior)
still occurs.
Using ``int`` in this class is really archaic, because it limits the
class to a gigabyte even on 64-bit platforms.
The multiplication overflow check also needs to include sizeof(T),
otherwise you can run into unsigned multiplication overflow (defined,
but undesirable) in the memcpy() call.
testcase:
int main()
{
tinyxml2::XMLDocument doc;
doc.InsertEndChild(doc.NewDeclaration());
auto root = doc.NewElement("root");
size_t sz = 0x80000001;
auto blank = new char[sz];
memset(blank, ' ', sz);
blank[sz-1]='\0';
root->SetText(blank);
doc.InsertEndChild(root);
tinyxml2::XMLPrinter printer(nullptr);
doc.Print(&printer);
}
In the XMLUtil::ToStr( uint64_t v, char* buffer, int bufferSize ) function, the format specifier %llu was used with a signed long long argument. This caused a type mismatch warning. The argument has been changed to unsigned long long to match the format specifier, resolving the warning.
The format "%x" is treated as an unsigned int by the GCC compiler. Use static_cast to cast the error to an unsigned int to match the "%x" type. Additionally, replace int(error) with static_cast<int>(error) to avoid the old-style cast warning.
Musl 1.2.4 made the LFS64 interfaces only available when
_LARGEFILE64_SOURCE is defined, and they will be removed altogether in
Musl 1.2.5. This commit replaces the LFS64 calls with their non-LFS64
versions and defines _FILE_OFFSET_BITS=64, which makes all interfaces
64-bit.
Bug: https://bugs.gentoo.org/905999
Added the ChildElementCount function that was initially suggested by msteiger on sourceforge for the original tinyxml. Modified to work with TinyXML-2.
I compiled tinyxml2 with the following changes to CMakeLists.txt:
-------------------------------------------------- ------------------------------------------
set (CMAKE_C_COMPILER "/ usr / local / bin / clang10")
set (CMAKE_CXX_COMPILER "/ usr / local / bin / clang ++ 10")
add_compile_options (-g)
add_compile_options (-fsanitize = address, undefined, integer, alignment, bool, builtin, bounds, enum, function, nonnull-attribute, null, object-size, pointer-overflow, return, returns-nonnull-attribute, unreachable, vla-bound , vptr)
set_source_files_properties (tinyxml2.cpp tinyxml2.h
PROPERTIES COMPILE_FLAGS -fsanitize = address, undefined, integer, alignment, bool, builtin, bounds, enum, function, nonnull-attribute, null, object-size, pointer-overflow, return, returns-nonnull-attribute, unreachable, vla-bound , vptr)
TARGET_LINK_LIBRARIES (tinyxml2 /usr/local/llvm10/lib/clang/10.0.0/lib/freebsd/libclang_rt.asan-x86_64.a /usr/local/llvm10/lib/clang/10.0.0/lib/freebsd/libang asan_cxx-x86_64.a /usr/local/llvm10/lib/clang/10.0.0/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a /usr/local/llvm10/lib/clang/10.0.0/lib/freebsd/ libclang_rt.ubsan_standalone_cxx-x86_64.a -lpthread)
-------------------------------------------------- ------------------------------------------
(Sorry for the dirty code.)
And launched the xmltest utility:
-------------------------------------------------- ------------------------------------------
/home/qqq/17_tinyxml2/tinyxml2-master/tinyxml2.cpp:237:37: runtime error: implicit conversion from type 'char' of value -48 (8-bit, signed) to type 'unsigned char' changed the value to 208 (8-bit, unsigned)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/qqq/17_tinyxml2/tinyxml2-master/tinyxml2.cpp:237:37 in
/home/qqq/17_tinyxml2/tinyxml2-master/tinyxml2.cpp:243:40: runtime error: implicit conversion from type 'char' of value -96 (8-bit, signed) to type 'unsigned char' changed the value to 160 (8-bit, unsigned)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/qqq/17_tinyxml2/tinyxml2-master/tinyxml2.cpp:243:40 in
/home/qqq/17_tinyxml2/tinyxml2-master/tinyxml2.cpp:1912:39: runtime error: implicit conversion from type 'char' of value -48 (8-bit, signed) to type 'unsigned char' changed the value to 208 (8-bit, unsigned)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/qqq/17_tinyxml2/tinyxml2-master/tinyxml2.cpp:1912:39 in
-------------------------------------------------- ------------------------------------------
Also, the comparison between size_t max and the actual file size is done
as an unsigned long long, since that type is guaranteed to be at least
64 bits, even on a 32-bit architecture.