Bug Summary

File:rootdir/src/SafeFile.cpp
Warning:line 580, column 4
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name SafeFile.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/src -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -D USE_WX_EXTENSIONS -I /usr/lib/x86_64-linux-gnu/wx/include/gtk3-unicode-3.2 -I /usr/include/wx-3.2 -D _FILE_OFFSET_BITS=64 -D WXUSINGDLL -D __WXGTK__ -D wxUSE_GUI=0 -I ./libs -I ./include -I /usr/include/upnp -D ENABLE_UPNP=1 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-register -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-01-14-161821-17216-1 -x c++ SafeFile.cpp
1//
2// This file is part of the aMule Project.
3//
4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6//
7// Any parts of this program derived from the xMule, lMule or eMule project,
8// or contributed by third-party developers are copyrighted by their
9// respective authors.
10//
11// This program is free software; you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation; either version 2 of the License, or
14// (at your option) any later version.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24//
25
26#include "SafeFile.h" // Interface declarations.
27#include "MD4Hash.h" // Needed for CMD4Hash
28#include "kademlia/utils/UInt128.h" // Needed for CUInt128
29#include "ScopedPtr.h" // Needed for CScopedPtr and CScopedArray
30#include "Logger.h"
31#include <common/Format.h> // Needed for CFormat
32#include "CompilerSpecific.h" // Needed for __FUNCTION__
33
34
35#define CHECK_BOM(size, x)((size >= 3) && (x[0] == (char)0xEF) && (x
[1] == (char)0xBB) && (x[2] == (char)0xBF))
((size >= 3) && (x[0] == (char)0xEF) && (x[1] == (char)0xBB) && (x[2] == (char)0xBF))
36
37const char BOMHeader[3] = { '\xEF', '\xBB', '\xBF'};
38
39
40CSafeIOException::CSafeIOException(const wxString& type, const wxString& desc)
41 : CMuleException(wxT("SafeIO::")L"SafeIO::" + type, desc) {}
42
43
44CEOFException::CEOFException(const wxString& desc)
45 : CSafeIOException(wxT("EOF")L"EOF", desc) {}
46
47
48CIOFailureException::CIOFailureException(const wxString& desc)
49 : CSafeIOException(wxT("IOFailure")L"IOFailure", desc) {}
50
51CIOFailureException::CIOFailureException(const wxString& type, const wxString& desc)
52 : CSafeIOException(wxT("IOFailure::")L"IOFailure::" + type, desc) {}
53
54
55///////////////////////////////////////////////////////////////////////////////
56// CFileDataIO
57
58
59CFileDataIO::~CFileDataIO()
60{
61}
62
63
64bool CFileDataIO::Eof() const
65{
66 return GetPosition() >= GetLength();
67}
68
69
70void CFileDataIO::Read(void *buffer, size_t count) const
71{
72 MULE_VALIDATE_PARAMS(buffer, wxT("Attempting to write to NULL buffer."))do { if (!(((buffer)))) { do { if ( wxTheAssertHandler &&
(wxOnAssert("SafeFile.cpp", 72, __FUNCTION__, "\"Assert failure\""
, L"((buffer))"), wxTrapInAssert) ) { wxTrapInAssert = false;
asm volatile ("int $3"); } } while ( (void)0, 0 ); throw CInvalidParamsEx
(((L"Attempting to write to NULL buffer."))); } } while (false
)
;
73
74 // Check that we read everything we wanted.
75 if (doRead(buffer, count) == (signed)count) {
76 return;
77 }
78
79 // To reduce potential system calls, we only do EOF checks when reads fail.
80 if (Eof()) {
81 throw CEOFException(wxT("Attempt to read past end of file.")L"Attempt to read past end of file.");
82 } else {
83 throw CIOFailureException(wxT("Read error, failed to read from file.")L"Read error, failed to read from file.");
84 }
85}
86
87
88void CFileDataIO::Write(const void* buffer, size_t count)
89{
90 MULE_VALIDATE_PARAMS(buffer, wxT("Attempting to read from NULL buffer."))do { if (!(((buffer)))) { do { if ( wxTheAssertHandler &&
(wxOnAssert("SafeFile.cpp", 90, __FUNCTION__, "\"Assert failure\""
, L"((buffer))"), wxTrapInAssert) ) { wxTrapInAssert = false;
asm volatile ("int $3"); } } while ( (void)0, 0 ); throw CInvalidParamsEx
(((L"Attempting to read from NULL buffer."))); } } while (false
)
;
91
92 if (doWrite(buffer, count) != (signed)count) {
93 throw CIOFailureException(wxT("Write error, failed to write to file.")L"Write error, failed to write to file.");
94 }
95}
96
97
98uint64 CFileDataIO::Seek(sint64 offset, wxSeekMode from) const
99{
100 sint64 newpos = 0;
101 switch (from) {
102 case wxFromStart:
103 newpos = offset;
104 break;
105
106 case wxFromCurrent:
107 newpos = GetPosition() + offset;
108 break;
109
110 case wxFromEnd:
111 newpos = GetLength() + offset;
112 break;
113
114 default:
115 MULE_VALIDATE_PARAMS(false, wxT("Invalid seek-mode specified."))do { if (!(((false)))) { do { if ( wxTheAssertHandler &&
(wxOnAssert("SafeFile.cpp", 115, __FUNCTION__, "\"Assert failure\""
, L"((false))"), wxTrapInAssert) ) { wxTrapInAssert = false; asm
volatile ("int $3"); } } while ( (void)0, 0 ); throw CInvalidParamsEx
(((L"Invalid seek-mode specified."))); } } while (false)
;
116 }
117
118 MULE_VALIDATE_PARAMS(newpos >= 0, wxT("Position after seeking would be less than zero!"))do { if (!(((newpos >= 0)))) { do { if ( wxTheAssertHandler
&& (wxOnAssert("SafeFile.cpp", 118, __FUNCTION__, "\"Assert failure\""
, L"((newpos >= 0))"), wxTrapInAssert) ) { wxTrapInAssert =
false; asm volatile ("int $3"); } } while ( (void)0, 0 ); throw
CInvalidParamsEx(((L"Position after seeking would be less than zero!"
))); } } while (false)
;
119
120 sint64 result = doSeek(newpos);
121 MULE_VALIDATE_STATE(result >= 0, wxT("Seeking resulted in invalid offset."))do { if (!(((result >= 0)))) { do { if ( wxTheAssertHandler
&& (wxOnAssert("SafeFile.cpp", 121, __FUNCTION__, "\"Assert failure\""
, L"((result >= 0))"), wxTrapInAssert) ) { wxTrapInAssert =
false; asm volatile ("int $3"); } } while ( (void)0, 0 ); throw
CInvalidStateEx(((L"Seeking resulted in invalid offset.")));
} } while (false)
;
122 MULE_VALIDATE_STATE(result == newpos, wxT("Target position and actual position disagree."))do { if (!(((result == newpos)))) { do { if ( wxTheAssertHandler
&& (wxOnAssert("SafeFile.cpp", 122, __FUNCTION__, "\"Assert failure\""
, L"((result == newpos))"), wxTrapInAssert) ) { wxTrapInAssert
= false; asm volatile ("int $3"); } } while ( (void)0, 0 ); throw
CInvalidStateEx(((L"Target position and actual position disagree."
))); } } while (false)
;
123
124 return result;
125}
126
127
128uint8 CFileDataIO::ReadUInt8() const
129{
130 uint8 value = 0;
131 Read(&value, sizeof(uint8));
132
133 return value;
134}
135
136
137uint16 CFileDataIO::ReadUInt16() const
138{
139 uint16 value = 0;
140 Read(&value, sizeof(uint16));
141
142 return ENDIAN_SWAP_16(value)((value));
143}
144
145
146uint32 CFileDataIO::ReadUInt32() const
147{
148 uint32 value = 0;
149 Read(&value, sizeof(uint32));
150
151 return ENDIAN_SWAP_32(value)((value));
152}
153
154
155uint64 CFileDataIO::ReadUInt64() const
156{
157 uint64 value = 0;
158 Read(&value, sizeof(uint64));
159
160 return ENDIAN_SWAP_64(value)((value));
161}
162
163
164// UInt128 values are stored a little weird way...
165// Four little-endian 32-bit numbers, stored in
166// big-endian order
167CUInt128 CFileDataIO::ReadUInt128() const
168{
169 CUInt128 value;
170 for (int i = 0; i < 4; i++) {
171 // Four 32bits chunks
172 value.Set32BitChunk(i, ReadUInt32());
173 }
174
175 return value;
176}
177
178
179CMD4Hash CFileDataIO::ReadHash() const
180{
181 CMD4Hash value;
182 Read(value.GetHash(), MD4HASH_LENGTH);
183
184 return value;
185}
186
187
188float CFileDataIO::ReadFloat() const
189{
190 float retVal;
191 Read(&retVal, sizeof(float));
192 return retVal;
193}
194
195
196unsigned char* CFileDataIO::ReadBsob(uint8* puSize) const
197{
198 MULE_VALIDATE_PARAMS(puSize, wxT("NULL pointer argument in ReadBsob"))do { if (!(((puSize)))) { do { if ( wxTheAssertHandler &&
(wxOnAssert("SafeFile.cpp", 198, __FUNCTION__, "\"Assert failure\""
, L"((puSize))"), wxTrapInAssert) ) { wxTrapInAssert = false;
asm volatile ("int $3"); } } while ( (void)0, 0 ); throw CInvalidParamsEx
(((L"NULL pointer argument in ReadBsob"))); } } while (false)
;
199
200 *puSize = ReadUInt8();
201
202 CScopedArray<unsigned char> bsob(*puSize);
203 Read(bsob.get(), *puSize);
204
205 return bsob.release();
206}
207
208
209wxString CFileDataIO::ReadString(bool bOptUTF8, uint8 SizeLen, bool SafeRead) const
210{
211 uint32 readLen;
212 switch (SizeLen) {
213 case sizeof(uint16): readLen = ReadUInt16(); break;
214 case sizeof(uint32): readLen = ReadUInt32(); break;
215
216 default:
217 MULE_VALIDATE_PARAMS(false, wxT("Invalid SizeLen value in ReadString"))do { if (!(((false)))) { do { if ( wxTheAssertHandler &&
(wxOnAssert("SafeFile.cpp", 217, __FUNCTION__, "\"Assert failure\""
, L"((false))"), wxTrapInAssert) ) { wxTrapInAssert = false; asm
volatile ("int $3"); } } while ( (void)0, 0 ); throw CInvalidParamsEx
(((L"Invalid SizeLen value in ReadString"))); } } while (false
)
;
218 }
219
220 if (SafeRead) {
221 readLen = std::min<uint64>(readLen, GetLength() - GetPosition());
222 }
223
224 return ReadOnlyString(bOptUTF8, readLen);
225}
226
227
228wxString CFileDataIO::ReadOnlyString(bool bOptUTF8, uint16 raw_len) const
229{
230 // We only need to set the the NULL terminator, since we know that
231 // reads will either succeed or throw an exception, in which case
232 // we wont be returning anything
233 std::vector<char> val_array(raw_len + 1);
234 val_array[raw_len] = 0;
235
236 char* val = &(val_array[0]);
237
238 Read(val, raw_len);
239 wxString str;
240
241 if (CHECK_BOM(raw_len, val)((raw_len >= 3) && (val[0] == (char)0xEF) &&
(val[1] == (char)0xBB) && (val[2] == (char)0xBF))
) {
242 // This is a UTF8 string with a BOM header, skip header.
243 str = UTF82unicode(val + 3);
244 } else if (bOptUTF8) {
245 str = UTF82unicode(val);
246 if (str.IsEmpty()) {
247 // Fallback to Latin-1
248 str = wxString(val, wxConvISO8859_1wxGet_wxConvISO8859_1(), raw_len);
249 }
250 } else {
251 // Raw strings are written as Latin-1 (see CFileDataIO::WriteStringCore)
252 str = wxString(val, wxConvISO8859_1wxGet_wxConvISO8859_1(), raw_len);
253 }
254
255 return str;
256}
257
258
259void CFileDataIO::WriteUInt8(uint8 value)
260{
261 Write(&value, sizeof(uint8));
262}
263
264
265void CFileDataIO::WriteUInt16(uint16 value)
266{
267 ENDIAN_SWAP_I_16(value)value = (value);
268
269 Write(&value, sizeof(uint16));
270}
271
272
273void CFileDataIO::WriteUInt32(uint32 value)
274{
275 ENDIAN_SWAP_I_32(value)value = (value);
276
277 Write(&value, sizeof(uint32));
278}
279
280
281void CFileDataIO::WriteUInt64(uint64 value)
282{
283 ENDIAN_SWAP_I_64(value)value = (value);
284
285 Write(&value, sizeof(uint64));
286}
287
288
289// UInt128 values are stored a little weird way...
290// Four little-endian 32-bit numbers, stored in
291// big-endian order
292void CFileDataIO::WriteUInt128(const Kademlia::CUInt128& value)
293{
294 for (int i = 0; i < 4; i++) {
295 // Four 32bits chunks
296 WriteUInt32(value.Get32BitChunk(i));
297 }
298}
299
300
301void CFileDataIO::WriteHash(const CMD4Hash& value)
302{
303 Write(value.GetHash(), MD4HASH_LENGTH);
304}
305
306
307void CFileDataIO::WriteFloat(float value)
308{
309 Write(&value, sizeof(float));
310}
311
312
313void CFileDataIO::WriteBsob(const unsigned char* value, uint8 size)
314{
315 WriteUInt8(size);
316 Write(value, size);
317}
318
319
320void CFileDataIO::WriteString(const wxString& str, EUtf8Str eEncode, uint8 SizeLen)
321{
322 switch (eEncode) {
323 case utf8strRaw:
324 case utf8strOptBOM: {
325 Unicode2CharBuf s(unicode2UTF8(str));
326 if (s.data()) {
327 WriteStringCore(s, eEncode, SizeLen);
328 break;
329 }
330 }
331 /* fall through */
332 default: {
333 // Non UTF-8 strings are saved as Latin-1
334 wxCharBuffer s1 = str.mb_str(wxConvISO8859_1wxGet_wxConvISO8859_1());
335 WriteStringCore(s1, utf8strNone, SizeLen);
336 }
337 }
338}
339
340
341void CFileDataIO::WriteStringCore(const char *s, EUtf8Str eEncode, uint8 SizeLen)
342{
343 uint32 sLength = s ? strlen(s) : 0;
344 uint32 real_length = 0;
345 if (eEncode == utf8strOptBOM) {
346 real_length = sLength + 3; // For BOM header.
347 } else {
348 real_length = sLength;
349 }
350
351 switch (SizeLen) {
352 case 0:
353 // Don't write size.
354 break;
355
356 case sizeof(uint16):
357 // We must not allow too long strings to be written,
358 // as this would allow for a buggy clients to "poison"
359 // us, by sending ISO8859-1 strings that expand to a
360 // greater than 16b length when converted as UTF-8.
361 if (real_length > 0xFFFF) {
362 wxFAIL_MSG(wxT("String is too long to be saved"))do { if ( wxTheAssertHandler && (wxOnAssert("SafeFile.cpp"
, 362, __FUNCTION__, "\"Assert failure\"", L"String is too long to be saved"
), wxTrapInAssert) ) { wxTrapInAssert = false; asm volatile (
"int $3"); } } while ( (void)0, 0 )
;
363
364 real_length = std::min<uint32>(real_length, 0xFFFF);
365 if (eEncode == utf8strOptBOM) {
366 sLength = real_length - 3;
367 } else {
368 sLength = real_length;
369 }
370 }
371
372 WriteUInt16(real_length);
373 break;
374
375 case sizeof(uint32):
376 WriteUInt32(real_length);
377 break;
378
379 default:
380 MULE_VALIDATE_PARAMS(false, wxT("Invalid length for string-length field."))do { if (!(((false)))) { do { if ( wxTheAssertHandler &&
(wxOnAssert("SafeFile.cpp", 380, __FUNCTION__, "\"Assert failure\""
, L"((false))"), wxTrapInAssert) ) { wxTrapInAssert = false; asm
volatile ("int $3"); } } while ( (void)0, 0 ); throw CInvalidParamsEx
(((L"Invalid length for string-length field."))); } } while (
false)
;
381 }
382
383 // The BOM header must be written even if the string is empty.
384 if (eEncode == utf8strOptBOM) {
385 Write(BOMHeader, 3);
386 }
387
388 // Only attempt to write non-NULL strings.
389 if (sLength) {
390 // No NULL terminator is written since we explicitly specify the length
391 Write(s, sLength);
392 }
393}
394
395
396CTag *CFileDataIO::ReadTag(bool bOptACP) const
397{
398 CTag *retVal = NULL__null;
399 wxString name;
400 uint8_t type = 0;
401 try {
402 type = ReadUInt8();
403 name = ReadString(false);
404
405 switch (type)
406 {
407 // NOTE: This tag data type is accepted and stored only to give us the possibility to upgrade
408 // the net in some months.
409 //
410 // And still.. it doesn't work this way without breaking backward compatibility. To properly
411 // do this without messing up the network the following would have to be done:
412 // - those tag types have to be ignored by any client, otherwise those tags would also be sent (and
413 // that's really the problem)
414 //
415 // - ignoring means, each client has to read and right throw away those tags, so those tags get
416 // get never stored in any tag list which might be sent by that client to some other client.
417 //
418 // - all calling functions have to be changed to deal with the 'nr. of tags' attribute (which was
419 // already parsed) correctly.. just ignoring those tags here is not enough, any taglists have to
420 // be built with the knowledge that the 'nr. of tags' attribute may get decreased during the tag
421 // reading..
422 //
423 // If those new tags would just be stored and sent to remote clients, any malicious or just bugged
424 // client could let send a lot of nodes "corrupted" packets...
425 //
426 case TAGTYPE_HASH16:
427 {
428 retVal = new CTagHash(name, ReadHash());
429 break;
430 }
431
432 case TAGTYPE_STRING:
433 retVal = new CTagString(name, ReadString(bOptACP));
434 break;
435
436 case TAGTYPE_UINT64:
437 retVal = new CTagInt64(name, ReadUInt64());
438 break;
439
440 case TAGTYPE_UINT32:
441 retVal = new CTagInt32(name, ReadUInt32());
442 break;
443
444 case TAGTYPE_UINT16:
445 retVal = new CTagInt16(name, ReadUInt16());
446 break;
447
448 case TAGTYPE_UINT8:
449 retVal = new CTagInt8(name, ReadUInt8());
450 break;
451
452 case TAGTYPE_FLOAT32:
453 retVal = new CTagFloat(name, ReadFloat());
454 break;
455
456 // NOTE: This tag data type is accepted and stored only to give us the possibility to upgrade
457 // the net in some months.
458 //
459 // And still.. it doesn't work this way without breaking backward compatibility
460 case TAGTYPE_BSOB:
461 {
462 uint8 size = 0;
463 CScopedArray<unsigned char> value(ReadBsob(&size));
464
465 retVal = new CTagBsob(name, value.get(), size);
466 break;
467 }
468
469 default:
470 throw wxString(CFormat(wxT("Invalid Kad tag type; type=0x%02x name=%s\n")L"Invalid Kad tag type; type=0x%02x name=%s\n") % type % name);
471 }
472 } catch(const CMuleException& e) {
473 AddLogLineN(e.what())theLogger.AddLogLine(L"SafeFile.cpp", 473, false, logStandard
, e.what())
;
474 delete retVal;
475 throw;
476 } catch(const wxString& e) {
477 AddLogLineN(e)theLogger.AddLogLine(L"SafeFile.cpp", 477, false, logStandard
, e)
;
478 throw;
479 }
480
481 return retVal;
482}
483
484
485void CFileDataIO::ReadTagPtrList(TagPtrList* taglist, bool bOptACP) const
486{
487 MULE_VALIDATE_PARAMS(taglist, wxT("NULL pointer argument in ReadTagPtrList"))do { if (!(((taglist)))) { do { if ( wxTheAssertHandler &&
(wxOnAssert("SafeFile.cpp", 487, __FUNCTION__, "\"Assert failure\""
, L"((taglist))"), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 ); throw CInvalidParamsEx
(((L"NULL pointer argument in ReadTagPtrList"))); } } while (
false)
;
488
489 uint32 count = ReadUInt8();
490 for (uint32 i = 0; i < count; i++)
491 {
492 CTag* tag = ReadTag(bOptACP);
493 taglist->push_back(tag);
494 }
495}
496
497
498void CFileDataIO::WriteTag(const CTag& tag)
499{
500 try
501 {
502 WriteUInt8(tag.GetType());
503
504 if (!tag.GetName().IsEmpty()) {
505 WriteString(tag.GetName(),utf8strNone);
506 } else {
507 WriteUInt16(1);
508 WriteUInt8(tag.GetNameID());
509 }
510
511 switch (tag.GetType())
512 {
513 case TAGTYPE_HASH16:
514 // Do NOT use this to transfer any tags for at least half a year!!
515 WriteHash(CMD4Hash(tag.GetHash()));
516 break;
517 case TAGTYPE_STRING:
518 WriteString(tag.GetStr(), utf8strRaw); // Always UTF8
519 break;
520 case TAGTYPE_UINT64:
521 WriteUInt64(tag.GetInt());
522 break;
523 case TAGTYPE_UINT32:
524 WriteUInt32(tag.GetInt());
525 break;
526 case TAGTYPE_FLOAT32:
527 WriteFloat(tag.GetFloat());
528 break;
529 case TAGTYPE_BSOB:
530 WriteBsob(tag.GetBsob(), tag.GetBsobSize());
531 break;
532 case TAGTYPE_UINT16:
533 WriteUInt16(tag.GetInt());
534 break;
535 case TAGTYPE_UINT8:
536 WriteUInt8(tag.GetInt());
537 break;
538 case TAGTYPE_BLOB:
539 // NOTE: This will break backward compatibility with met files for eMule versions prior to 0.44a
540 // and any aMule prior to SVN 26/02/2005
541 WriteUInt32(tag.GetBlobSize());
542 Write(tag.GetBlob(), tag.GetBlobSize());
543 break;
544 default:
545 //TODO: Support more tag types
546 // With the if above, this should NEVER happen.
547 AddLogLineNS(CFormat(wxT("CFileDataIO::WriteTag: Unknown tag: type=0x%02X")) % tag.GetType())theLogger.AddLogLine(L"SafeFile.cpp", 547, false, logStandard
, CFormat(L"CFileDataIO::WriteTag: Unknown tag: type=0x%02X")
% tag.GetType(), true)
;
548 wxFAILdo { if ( wxTheAssertHandler && (wxOnAssert("SafeFile.cpp"
, 548, __FUNCTION__, "\"Assert failure\"", (const char*)__null
), wxTrapInAssert) ) { wxTrapInAssert = false; asm volatile (
"int $3"); } } while ( (void)0, 0 )
;
549 break;
550 }
551 } catch (...) {
552 AddLogLineNS(wxT("Exception in CDataIO:WriteTag"))theLogger.AddLogLine(L"SafeFile.cpp", 552, false, logStandard
, L"Exception in CDataIO:WriteTag", true)
;
553 throw;
554 }
555}
556
557
558void CFileDataIO::WriteTagPtrList(const TagPtrList& tagList)
559{
560 uint32 count = tagList.size();
561 wxASSERT( count <= 0xFF )do { if ( count <= 0xFF ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("SafeFile.cpp", 561, __FUNCTION__, "count <= 0xFF"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
562
563 WriteUInt8(count);
564 TagPtrList::const_iterator it;
565 for (it = tagList.begin(); it != tagList.end(); ++it) {
566 WriteTag(**it);
567 }
568}
569
570uint64 CFileDataIO::GetIntTagValue() const {
571
572 uint8 type = ReadUInt8();
573
574 ReadString(false);
575
576 switch (type) {
577
578 case TAGTYPE_UINT64:
579 return ReadUInt64();
580 break;
This statement is never executed
581
582 case TAGTYPE_UINT32:
583 return ReadUInt32();
584 break;
585
586 case TAGTYPE_UINT16:
587 return ReadUInt16();
588 break;
589
590 case TAGTYPE_UINT8:
591 return ReadUInt8();
592 break;
593
594 default:
595 throw wxString(wxT("Wrong tag type reading int tag")L"Wrong tag type reading int tag");
596 }
597}
598// File_checked_for_headers