|
|
@@ -100,6 +100,20 @@ distribution.
|
|
|
#define TIXML_SSCANF sscanf
|
|
|
#endif
|
|
|
|
|
|
+#if defined(_WIN64)
|
|
|
+ #define TIXML_FSEEK _fseeki64
|
|
|
+ #define TIXML_FTELL _ftelli64
|
|
|
+#elif defined(__APPLE__)
|
|
|
+ #define TIXML_FSEEK fseeko
|
|
|
+ #define TIXML_FTELL ftello
|
|
|
+#elif defined(__x86_64__)
|
|
|
+ #define TIXML_FSEEK fseeko64
|
|
|
+ #define TIXML_FTELL ftello64
|
|
|
+#else
|
|
|
+ #define TIXML_FSEEK fseek
|
|
|
+ #define TIXML_FTELL ftell
|
|
|
+#endif
|
|
|
+
|
|
|
|
|
|
static const char LINE_FEED = static_cast<char>(0x0a); // all line endings are normalized to LF
|
|
|
static const char LF = LINE_FEED;
|
|
|
@@ -2286,49 +2300,34 @@ XMLError XMLDocument::LoadFile( const char* filename )
|
|
|
return _errorID;
|
|
|
}
|
|
|
|
|
|
-// This is likely overengineered template art to have a check that unsigned long value incremented
|
|
|
-// by one still fits into size_t. If size_t type is larger than unsigned long type
|
|
|
-// (x86_64-w64-mingw32 target) then the check is redundant and gcc and clang emit
|
|
|
-// -Wtype-limits warning. This piece makes the compiler select code with a check when a check
|
|
|
-// is useful and code with no check when a check is redundant depending on how size_t and unsigned long
|
|
|
-// types sizes relate to each other.
|
|
|
-template
|
|
|
-<bool = (sizeof(unsigned long) >= sizeof(size_t))>
|
|
|
-struct LongFitsIntoSizeTMinusOne {
|
|
|
- static bool Fits( unsigned long value )
|
|
|
- {
|
|
|
- return value < static_cast<size_t>(-1);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-template <>
|
|
|
-struct LongFitsIntoSizeTMinusOne<false> {
|
|
|
- static bool Fits( unsigned long )
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
XMLError XMLDocument::LoadFile( FILE* fp )
|
|
|
{
|
|
|
Clear();
|
|
|
|
|
|
- fseek( fp, 0, SEEK_SET );
|
|
|
+ TIXML_FSEEK( fp, 0, SEEK_SET );
|
|
|
if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) {
|
|
|
SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
|
|
|
return _errorID;
|
|
|
}
|
|
|
|
|
|
- fseek( fp, 0, SEEK_END );
|
|
|
- const long filelength = ftell( fp );
|
|
|
- fseek( fp, 0, SEEK_SET );
|
|
|
- if ( filelength == -1L ) {
|
|
|
- SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
|
|
|
- return _errorID;
|
|
|
+ TIXML_FSEEK( fp, 0, SEEK_END );
|
|
|
+
|
|
|
+ unsigned long long filelength;
|
|
|
+ {
|
|
|
+ const long long fileLengthSigned = TIXML_FTELL( fp );
|
|
|
+ TIXML_FSEEK( fp, 0, SEEK_SET );
|
|
|
+ if ( fileLengthSigned == -1L ) {
|
|
|
+ SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
|
|
|
+ return _errorID;
|
|
|
+ }
|
|
|
+ TIXMLASSERT( fileLengthSigned >= 0 );
|
|
|
+ filelength = static_cast<unsigned long long>(fileLengthSigned);
|
|
|
}
|
|
|
- TIXMLASSERT( filelength >= 0 );
|
|
|
|
|
|
- if ( !LongFitsIntoSizeTMinusOne<>::Fits( filelength ) ) {
|
|
|
+ const size_t maxSizeT = static_cast<size_t>(-1);
|
|
|
+ // We'll do the comparison as an unsigned long long, because that's guaranteed to be at
|
|
|
+ // least 8 bytes, even on a 32-bit platform.
|
|
|
+ if ( filelength >= static_cast<unsigned long long>(maxSizeT) ) {
|
|
|
// Cannot handle files which won't fit in buffer together with null terminator
|
|
|
SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
|
|
|
return _errorID;
|
|
|
@@ -2339,7 +2338,7 @@ XMLError XMLDocument::LoadFile( FILE* fp )
|
|
|
return _errorID;
|
|
|
}
|
|
|
|
|
|
- const size_t size = filelength;
|
|
|
+ const size_t size = static_cast<size_t>(filelength);
|
|
|
TIXMLASSERT( _charBuffer == 0 );
|
|
|
_charBuffer = new char[size+1];
|
|
|
const size_t read = fread( _charBuffer, 1, size, fp );
|