Bug Summary

File:home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx
Warning:line 209, column 12
Potential leak of memory pointed to by 'pObject'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name tocread.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/lotuswordpro/inc -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
6 *
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
9 *
10 * Sun Microsystems Inc., October, 2000
11 *
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 *
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
20 *
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 *
31 *
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
38 *
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
45 *
46 * The Initial Developer of the Original Code is: IBM Corporation
47 *
48 * Copyright: 2008 by IBM Corporation
49 *
50 * All Rights Reserved.
51 *
52 * Contributor(s): _______________________________________
53 *
54 *
55 ************************************************************************/
56
57#include <sal/config.h>
58#include <sal/log.hxx>
59
60#include <cstring>
61
62#include "first.hxx"
63#include "bentoid.hxx"
64#include "tocread.hxx"
65#include "ut.hxx"
66#include <assert.h>
67namespace OpenStormBento
68{
69
70BenError
71CBenTOCReader::ReadLabelAndTOC()
72{
73 BenError Err;
74
75 unsigned long TOCOffset;
76 if ((Err = ReadLabel(&TOCOffset, &cTOCSize)) != BenErr_OK)
1
Taking false branch
77 return Err;
78
79 sal_uLong nLength = cpContainer->GetSize();
80
81 if (TOCOffset > nLength)
2
Assuming 'TOCOffset' is <= 'nLength'
3
Taking false branch
82 return BenErr_ReadPastEndOfTOC;
83
84 if (cTOCSize > nLength - TOCOffset)
4
Assuming the condition is false
5
Taking false branch
85 return BenErr_ReadPastEndOfTOC;
86
87 cpContainer->SeekToPosition(TOCOffset);
88
89 cpTOC.reset( new BenByte[cTOCSize] );
90 if ((Err = cpContainer->ReadKnownSize(cpTOC.get(), cTOCSize)) != BenErr_OK)
6
Assuming the condition is false
7
Taking false branch
91 return Err;
92
93 if ((Err = ReadTOC()) != BenErr_OK)
8
Calling 'CBenTOCReader::ReadTOC'
94 return Err;
95
96 return BenErr_OK;
97}
98
99BenError
100CBenTOCReader::ReadLabel(unsigned long * pTOCOffset, unsigned long * pTOCSize)
101{
102 // If seek fails, then probably because stream is smaller than
103 // BEN_LABEL_SIZE and thus can't be Bento container
104 BenError Err;
105 cpContainer->SeekFromEnd(-BEN_LABEL_SIZE24);
106
107 BenByte Label[BEN_LABEL_SIZE24];
108 if ((Err = cpContainer->ReadKnownSize(Label, BEN_LABEL_SIZE24)) != BenErr_OK)
109 return Err;
110
111 if (memcmp(Label, gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE8) != 0)
112 if ((Err = SearchForLabel(Label)) != BenErr_OK)
113 return Err;
114
115 BenByte * pCurrLabel = Label + BEN_MAGIC_BYTES_SIZE8;
116
117 BenWord Flags =
118 UtGetIntelWord(pCurrLabel);
119 pCurrLabel += 2; // Flags
120 // Newer files are 0x0101--indicates if big or little endian. Older
121 // files are 0x0 for flags
122 if (Flags != 0x0101 && Flags != 0x0)
123 return BenErr_UnknownBentoFormatVersion;
124
125 cBlockSize = UtGetIntelWord(pCurrLabel) * 1024; pCurrLabel += 2;
126 if (cBlockSize == 0)
127 return BenErr_NotBentoContainer;
128
129 // Check major version
130 if (UtGetIntelWord(pCurrLabel) != BEN_CURR_MAJOR_VERSION2)
131 return BenErr_UnknownBentoFormatVersion;
132 pCurrLabel += 2;
133
134 pCurrLabel += 2; // Minor version
135
136 *pTOCOffset = UtGetIntelDWord(pCurrLabel); pCurrLabel += 4;
137 *pTOCSize = UtGetIntelDWord(pCurrLabel);
138
139 assert(pCurrLabel + 4 == Label + BEN_LABEL_SIZE)(static_cast <bool> (pCurrLabel + 4 == Label + 24) ? void
(0) : __assert_fail ("pCurrLabel + 4 == Label + BEN_LABEL_SIZE"
, "/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx"
, 139, __extension__ __PRETTY_FUNCTION__))
;
140
141 return BenErr_OK;
142}
143
144#define LABEL_READ_BUFFER_SIZE500 500
145#define MAX_SEARCH_AMOUNT1024 * 1024 1024 * 1024
146
147BenError
148CBenTOCReader::SearchForLabel(BenByte * pLabel)
149{
150 BenError Err;
151
152 sal_uLong Length = cpContainer->GetSize();
153
154 // Always ready to check for MagicBytes from
155 // CurrOffset - BEN_MAGIC_BYTES_SIZE to CurrOffset - 1
156 unsigned long CurrOffset = Length - BEN_LABEL_SIZE24 + BEN_MAGIC_BYTES_SIZE8 -
157 1;
158
159 char Buffer[LABEL_READ_BUFFER_SIZE500] = {0};
160
161 unsigned long BufferStartOffset = Length; // Init to big value
162
163 while (CurrOffset >= BEN_MAGIC_BYTES_SIZE8)
164 {
165 // Don't search backwards more than 1 meg
166 if (Length - CurrOffset > MAX_SEARCH_AMOUNT1024 * 1024)
167 break;
168
169 // If before beginning of buffer
170 if (CurrOffset - BEN_MAGIC_BYTES_SIZE8 < BufferStartOffset)
171 {
172 unsigned long UsedBufferSize;
173 if (CurrOffset < LABEL_READ_BUFFER_SIZE500)
174 UsedBufferSize = CurrOffset;
175 else UsedBufferSize = LABEL_READ_BUFFER_SIZE500;
176
177 cpContainer->SeekToPosition(CurrOffset - UsedBufferSize);
178
179 if ((Err = cpContainer->ReadKnownSize(Buffer, UsedBufferSize)) !=
180 BenErr_OK)
181 return Err;
182
183 BufferStartOffset = CurrOffset - UsedBufferSize;
184 }
185
186 if (memcmp(Buffer + (CurrOffset - BEN_MAGIC_BYTES_SIZE8 -
187 BufferStartOffset), gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE8) == 0)
188 {
189 cpContainer->SeekToPosition(CurrOffset -
190 BEN_MAGIC_BYTES_SIZE8);
191
192 return cpContainer->ReadKnownSize(pLabel, BEN_LABEL_SIZE24);
193 }
194
195 --CurrOffset;
196 }
197
198 return BenErr_NotBentoContainer; // Didn't find magic bytes
199}
200
201BenError
202CBenTOCReader::ReadTOC()
203{
204 BenError Err;
205 BenByte LookAhead = GetCode();
206 BenGeneration Generation = 0;
207
208 // Read in all objects
209 while (LookAhead == BEN_NEW_OBJECT1)
9
Assuming 'LookAhead' is equal to BEN_NEW_OBJECT
10
Loop condition is true. Entering loop body
38
Potential leak of memory pointed to by 'pObject'
210 {
211 BenObjectID ObjectID;
212 if ((Err = GetDWord(&ObjectID)) != BenErr_OK)
11
Taking false branch
213 return Err;
214 CBenObject * pObject = nullptr;
215
216 // Read in all properties for object
217 do
37
Loop condition is false. Exiting loop
218 {
219 BenObjectID PropertyID;
220
221 if ((Err = GetDWord(&PropertyID)) != BenErr_OK)
12
Taking false branch
222 return Err;
223 CBenProperty * pProperty = nullptr;
224
225 // Read in all values for property
226 do
36
Loop condition is false. Exiting loop
227 {
228 BenObjectID ReferencedListID = 0;
229
230 BenObjectID TypeID;
231 if ((Err = GetDWord(&TypeID)) != BenErr_OK)
13
Taking false branch
232 return Err;
233 LookAhead = GetCode();
234
235 if (LookAhead == BEN_EXPLICIT_GEN4)
14
Assuming 'LookAhead' is not equal to BEN_EXPLICIT_GEN
15
Taking false branch
236 {
237 if ((Err = GetDWord(&Generation)) != BenErr_OK)
238 return Err;
239 LookAhead = GetCode();
240 }
241
242 if (LookAhead == BEN_REFERENCE_LIST_ID15)
16
Assuming 'LookAhead' is not equal to BEN_REFERENCE_LIST_ID
17
Taking false branch
243 {
244 if ((Err = GetDWord(&ReferencedListID)) != BenErr_OK)
245 return Err;
246 LookAhead = GetCode();
247 }
248
249 if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME24 ||
18
Assuming 'PropertyID' is equal to BEN_PROPID_GLOBAL_PROPERTY_NAME
250 PropertyID == BEN_PROPID_GLOBAL_TYPE_NAME23)
251 {
252 // Read property or type name
253
254 if (pObject != nullptr || TypeID != BEN_TYPEID_7_BIT_ASCII21 ||
19
Assuming 'TypeID' is equal to BEN_TYPEID_7_BIT_ASCII
21
Taking false branch
255 LookAhead != BEN_OFFSET4_LEN45)
20
Assuming 'LookAhead' is equal to BEN_OFFSET4_LEN4
256 return BenErr_NamedObjectError;
257
258 BenContainerPos Pos;
259 sal_uInt32 Length;
260
261 if ((Err = GetDWord(&Pos)) != BenErr_OK)
22
Taking false branch
262 return Err;
263 if ((Err = GetDWord(&Length)) != BenErr_OK)
23
Taking false branch
264 return Err;
265 LookAhead = GetCode();
266
267 cpContainer->SeekToPosition(Pos);
268
269 const auto nRemainingSize = cpContainer->remainingSize();
270 if (Length > nRemainingSize)
24
Assuming 'Length' is <= 'nRemainingSize'
25
Taking false branch
271 {
272 SAL_WARN("lwp", "stream too short for claimed no of records")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "lwp")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "stream too short for claimed no of records") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lwp"),
("/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx"
":" "272" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "stream too short for claimed no of records"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "stream too short for claimed no of records"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lwp"), ("/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx"
":" "272" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "stream too short for claimed no of records") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lwp"),
("/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx"
":" "272" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "stream too short for claimed no of records"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "stream too short for claimed no of records"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lwp"), ("/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx"
":" "272" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
273 Length = nRemainingSize;
274 }
275
276 #define STACK_BUFFER_SIZE256 256
277 char sStackBuffer[STACK_BUFFER_SIZE256];
278 std::unique_ptr<char[]> sAllocBuffer;
279 char * sBuffer;
280 if (Length > STACK_BUFFER_SIZE256)
26
Assuming 'Length' is <= STACK_BUFFER_SIZE
27
Taking false branch
281 {
282 sAllocBuffer.reset(new char[Length]);
283 sBuffer = sAllocBuffer.get();
284 }
285 else
286 {
287 sBuffer = sStackBuffer;
288 }
289
290 if ((Err = cpContainer->ReadKnownSize(sBuffer, Length)) !=
28
Assuming the condition is false
29
Taking false branch
291 BenErr_OK)
292 {
293 return Err;
294 }
295
296 OString sName;
297 if (Length)
30
Assuming 'Length' is 0
31
Taking false branch
298 sName = OString(sBuffer, Length - 1);
299
300 CUtListElmt * pPrevNamedObjectListElmt;
301 if (FindNamedObject(&cpContainer->GetNamedObjects(),
32
Assuming the condition is false
33
Taking false branch
302 sName, &pPrevNamedObjectListElmt) != nullptr)
303 {
304 return BenErr_DuplicateName;
305 }
306
307 CUtListElmt* pPrevObject = cpContainer->GetObjects().GetLast();
308
309 if (PropertyID
33.1
'PropertyID' is equal to BEN_PROPID_GLOBAL_PROPERTY_NAME
== BEN_PROPID_GLOBAL_PROPERTY_NAME24)
34
Taking true branch
310 pObject = new CBenPropertyName(cpContainer, ObjectID,
35
Memory is allocated
311 pPrevObject, sName, pPrevNamedObjectListElmt);
312 else
313 pObject = new CBenTypeName(cpContainer, ObjectID,
314 pPrevObject, sName, pPrevNamedObjectListElmt);
315 }
316 else if (PropertyID == BEN_PROPID_OBJ_REFERENCES31)
317 {
318 // Don't need to read in references object--we assume
319 // that all references use object ID as key
320 if ((Err = ReadSegments(nullptr, &LookAhead)) != BenErr_OK)
321 return Err;
322 }
323 else if (ObjectID == BEN_OBJID_TOC1)
324 {
325 if (PropertyID == BEN_PROPID_TOC_SEED2)
326 {
327 if (TypeID != BEN_TYPEID_TOC_TYPE19 ||
328 LookAhead != BEN_IMMEDIATE413)
329 return BenErr_TOCSeedError;
330
331 BenDWord Data;
332 if ((Err = GetDWord(&Data)) != BenErr_OK)
333 return Err;
334 LookAhead = GetCode();
335
336 cpContainer->SetNextAvailObjectID(Data);
337 }
338 else
339 {
340 // Ignore the other BEN_OBJID_TOC properties
341 if ((Err = ReadSegments(nullptr, &LookAhead)) != BenErr_OK)
342 return Err;
343 }
344 }
345 else
346 {
347 if (pProperty != nullptr)
348 return BenErr_PropertyWithMoreThanOneValue;
349
350 if (pObject == nullptr)
351 pObject = new CBenObject(cpContainer, ObjectID,
352 cpContainer->GetObjects().GetLast());
353
354 pProperty = new CBenProperty(pObject, PropertyID, TypeID,
355 pObject->GetProperties().GetLast());
356
357 if ((Err = ReadSegments(&pProperty->UseValue(),
358 &LookAhead)) != BenErr_OK)
359 return Err;
360 }
361 } while (LookAhead == BEN_NEW_TYPE3);
362 } while (LookAhead == BEN_NEW_PROPERTY2);
363 }
364
365 if (LookAhead == BEN_READ_PAST_END_OF_TOC50)
366 return BenErr_OK;
367 else return BenErr_InvalidTOC;
368}
369
370BenError
371CBenTOCReader::ReadSegments(CBenValue * pValue, BenByte * pLookAhead)
372{
373 BenError Err;
374
375 while (*pLookAhead >= BEN_SEGMENT_CODE_START5 &&
376 *pLookAhead <= BEN_SEGMENT_CODE_END14)
377 {
378 if ((Err = ReadSegment(pValue, pLookAhead)) !=
379 BenErr_OK)
380 return Err;
381 }
382
383 return BenErr_OK;
384}
385
386BenError
387CBenTOCReader::ReadSegment(CBenValue * pValue, BenByte * pLookAhead)
388{
389 BenError Err;
390
391 bool Immediate = false;
392 bool EightByteOffset = false;
393 sal_uInt32 Offset(0), Length(0);
394
395 switch (*pLookAhead)
396 {
397 case BEN_CONT_OFFSET4_LEN46:
398 case BEN_OFFSET4_LEN45:
399 if ((Err = GetDWord(&Offset)) != BenErr_OK)
400 return Err;
401 if ((Err = GetDWord(&Length)) != BenErr_OK)
402 return Err;
403 break;
404
405 case BEN_IMMEDIATE09:
406 Length = 0; Immediate = true;
407 break;
408
409 case BEN_IMMEDIATE110:
410 Length = 1; Immediate = true;
411 break;
412
413 case BEN_IMMEDIATE211:
414 Length = 2; Immediate = true;
415 break;
416
417 case BEN_IMMEDIATE312:
418 Length = 3; Immediate = true;
419 break;
420
421 case BEN_CONT_IMMEDIATE414:
422 case BEN_IMMEDIATE413:
423 Length = 4; Immediate = true;
424 break;
425
426 case BEN_CONT_OFFSET8_LEN48:
427 case BEN_OFFSET8_LEN47:
428 EightByteOffset = true;
429 break;
430
431 default:
432 return BenErr_OK;
433 }
434
435 BenByte ImmData[4];
436 if (Immediate && Length != 0)
437 if ((Err = GetData(ImmData, 4)) != BenErr_OK)
438 return Err;
439
440 *pLookAhead = GetCode();
441
442 if (EightByteOffset)
443 return BenErr_64BitOffsetNotSupported;
444
445 if (pValue != nullptr)
446 {
447 if (! Immediate)
448 new CBenValueSegment(pValue, Offset, Length);
449 else if (Length != 0)
450 {
451 assert(Length <= 4)(static_cast <bool> (Length <= 4) ? void (0) : __assert_fail
("Length <= 4", "/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx"
, 451, __extension__ __PRETTY_FUNCTION__))
;
452 new CBenValueSegment(pValue, ImmData, static_cast<unsigned short>(Length));
453 }
454 }
455
456 return BenErr_OK;
457}
458
459bool
460CBenTOCReader::CanGetData(unsigned long Amt)
461{
462 return cCurr + Amt <= cTOCSize;
463}
464
465BenError
466CBenTOCReader::GetByte(BenByte * pByte)
467{
468 if (! CanGetData(1))
469 return BenErr_ReadPastEndOfTOC;
470
471 *pByte = UtGetIntelByte(cpTOC.get() + cCurr);
472 ++cCurr;
473 return BenErr_OK;
474}
475
476BenError
477CBenTOCReader::GetDWord(BenDWord * pDWord)
478{
479 if (! CanGetData(4))
480 return BenErr_ReadPastEndOfTOC;
481
482 *pDWord = UtGetIntelDWord(cpTOC.get() + cCurr);
483 cCurr += 4;
484 return BenErr_OK;
485}
486
487BenByte
488CBenTOCReader::GetCode()
489{
490 BenByte Code;
491 do
492 {
493 if (GetByte(&Code) != BenErr_OK)
494 return BEN_READ_PAST_END_OF_TOC50;
495
496 if (Code == BEN_END_OF_BUFFER24)
497 // Advance to next block
498 cCurr = cBlockSize * ((cCurr + (cBlockSize - 1)) /
499 cBlockSize);
500 }
501 while (Code == BEN_NOOP0xFF || Code == BEN_END_OF_BUFFER24);
502 return Code;
503}
504
505BenError
506CBenTOCReader::GetData(void * pBuffer, unsigned long Amt)
507{
508 if (! CanGetData(Amt))
509 return BenErr_ReadPastEndOfTOC;
510
511 std::memcpy(pBuffer, cpTOC.get() + cCurr, Amt);
512 cCurr += Amt;
513 return BenErr_OK;
514}
515}//end OpenStormBento namespace
516
517/* vim:set shiftwidth=4 softtabstop=4 expandtab: */