1 /*
2 * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
4 * Distributed under the terms of the MIT License.
5 */
6
7
8 #include <package/hpkg/ReaderImplBase.h>
9
10 #include <errno.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15
16 #include <algorithm>
17 #include <new>
18
19 #include <ByteOrder.h>
20 #include <DataIO.h>
21 #include <OS.h>
22
23 #include <ZlibCompressionAlgorithm.h>
24 #include <ZstdCompressionAlgorithm.h>
25
26 #include <package/hpkg/HPKGDefsPrivate.h>
27 #include <package/hpkg/PackageFileHeapReader.h>
28
29
30 namespace BPackageKit {
31
32 namespace BHPKG {
33
34 namespace BPrivate {
35
36
37 static const uint16 kAttributeTypes[B_HPKG_ATTRIBUTE_ID_ENUM_COUNT] = {
38 #define B_DEFINE_HPKG_ATTRIBUTE(id, type, name, constant) \
39 B_HPKG_ATTRIBUTE_TYPE_##type,
40 #include <package/hpkg/PackageAttributes.h>
41 #undef B_DEFINE_HPKG_ATTRIBUTE
42 };
43
44 // #pragma mark - AttributeHandlerContext
45
46
AttributeHandlerContext(BErrorOutput * errorOutput,BPackageContentHandler * packageContentHandler,BHPKGPackageSectionID section,bool ignoreUnknownAttributes)47 ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
48 BErrorOutput* errorOutput, BPackageContentHandler* packageContentHandler,
49 BHPKGPackageSectionID section, bool ignoreUnknownAttributes)
50 :
51 errorOutput(errorOutput),
52 packageContentHandler(packageContentHandler),
53 hasLowLevelHandler(false),
54 ignoreUnknownAttributes(ignoreUnknownAttributes),
55 section(section)
56 {
57 }
58
59
AttributeHandlerContext(BErrorOutput * errorOutput,BLowLevelPackageContentHandler * lowLevelHandler,BHPKGPackageSectionID section,bool ignoreUnknownAttributes)60 ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
61 BErrorOutput* errorOutput, BLowLevelPackageContentHandler* lowLevelHandler,
62 BHPKGPackageSectionID section, bool ignoreUnknownAttributes)
63 :
64 errorOutput(errorOutput),
65 lowLevelHandler(lowLevelHandler),
66 hasLowLevelHandler(true),
67 ignoreUnknownAttributes(ignoreUnknownAttributes),
68 section(section)
69 {
70 }
71
72
~AttributeHandlerContext()73 ReaderImplBase::AttributeHandlerContext::~AttributeHandlerContext()
74 {
75 }
76
77
78 void
ErrorOccurred()79 ReaderImplBase::AttributeHandlerContext::ErrorOccurred()
80 {
81 if (hasLowLevelHandler)
82 lowLevelHandler->HandleErrorOccurred();
83 else
84 packageContentHandler->HandleErrorOccurred();
85 }
86
87
88 // #pragma mark - AttributeHandler
89
90
~AttributeHandler()91 ReaderImplBase::AttributeHandler::~AttributeHandler()
92 {
93 }
94
95
96 void
SetLevel(int level)97 ReaderImplBase::AttributeHandler::SetLevel(int level)
98 {
99 fLevel = level;
100 }
101
102
103 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)104 ReaderImplBase::AttributeHandler::HandleAttribute(
105 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
106 AttributeHandler** _handler)
107 {
108 return B_OK;
109 }
110
111
112 status_t
NotifyDone(AttributeHandlerContext * context)113 ReaderImplBase::AttributeHandler::NotifyDone(
114 AttributeHandlerContext* context)
115 {
116 return B_OK;
117 }
118
119
120 // #pragma mark - AttributeHandler allocation
121
122
123 void*
operator new(size_t size,AttributeHandlerContext * context)124 ReaderImplBase::AttributeHandler::operator new(size_t size, AttributeHandlerContext* context)
125 {
126 AttributeHandler* handler = (AttributeHandler*)context->handlersAllocator.Allocate(size);
127 if (handler != NULL)
128 handler->fDeleting = false;
129 return handler;
130 }
131
132
133 void
operator delete(void * pointer)134 ReaderImplBase::AttributeHandler::operator delete(void* pointer)
135 {
136 AttributeHandler* handler = (AttributeHandler*)pointer;
137 if (!handler->fDeleting)
138 debugger("Package AttributeHandler: deleted without calling Delete()");
139
140 // Nothing else to do; memory is released by Delete().
141 }
142
143
144 status_t
Delete(AttributeHandlerContext * context)145 ReaderImplBase::AttributeHandler::Delete(AttributeHandlerContext* context)
146 {
147 fDeleting = true;
148 delete this;
149
150 context->handlersAllocator.Free(this);
151 return B_OK;
152 }
153
154
155 // #pragma mark - PackageInfoAttributeHandlerBase
156
157
158 ReaderImplBase::PackageInfoAttributeHandlerBase
PackageInfoAttributeHandlerBase(BPackageInfoAttributeValue & packageInfoValue)159 ::PackageInfoAttributeHandlerBase(
160 BPackageInfoAttributeValue& packageInfoValue)
161 :
162 fPackageInfoValue(packageInfoValue)
163 {
164 }
165
166
167 status_t
NotifyDone(AttributeHandlerContext * context)168 ReaderImplBase::PackageInfoAttributeHandlerBase::NotifyDone(
169 AttributeHandlerContext* context)
170 {
171 status_t error = context->packageContentHandler->HandlePackageAttribute(
172 fPackageInfoValue);
173 if (context->ignoreUnknownAttributes && error == B_NOT_SUPPORTED)
174 error = B_OK; // Safe to skip a future/unknown attribute.
175 fPackageInfoValue.Clear();
176 return error;
177 }
178
179
180 // #pragma mark - PackageVersionAttributeHandler
181
182
PackageVersionAttributeHandler(BPackageInfoAttributeValue & packageInfoValue,BPackageVersionData & versionData,bool notify)183 ReaderImplBase::PackageVersionAttributeHandler::PackageVersionAttributeHandler(
184 BPackageInfoAttributeValue& packageInfoValue,
185 BPackageVersionData& versionData, bool notify)
186 :
187 super(packageInfoValue),
188 fPackageVersionData(versionData),
189 fNotify(notify)
190 {
191 }
192
193
194 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)195 ReaderImplBase::PackageVersionAttributeHandler::HandleAttribute(
196 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
197 AttributeHandler** _handler)
198 {
199 switch (id) {
200 case B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MINOR:
201 fPackageVersionData.minor = value.string;
202 break;
203
204 case B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MICRO:
205 fPackageVersionData.micro = value.string;
206 break;
207
208 case B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_PRE_RELEASE:
209 fPackageVersionData.preRelease = value.string;
210 break;
211
212 case B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_REVISION:
213 fPackageVersionData.revision = value.unsignedInt;
214 break;
215
216 default:
217 if (context->ignoreUnknownAttributes)
218 break;
219
220 context->errorOutput->PrintError("Error: Invalid package "
221 "attribute section: unexpected package attribute id %d "
222 "encountered when parsing package version\n", id);
223 return B_BAD_DATA;
224 }
225
226 return B_OK;
227 }
228
229
230 status_t
NotifyDone(AttributeHandlerContext * context)231 ReaderImplBase::PackageVersionAttributeHandler::NotifyDone(
232 AttributeHandlerContext* context)
233 {
234 if (!fNotify)
235 return B_OK;
236
237 fPackageInfoValue.attributeID = B_PACKAGE_INFO_VERSION;
238 return super::NotifyDone(context);
239 }
240
241
242 // #pragma mark - PackageResolvableAttributeHandler
243
244
245 ReaderImplBase::PackageResolvableAttributeHandler
PackageResolvableAttributeHandler(BPackageInfoAttributeValue & packageInfoValue)246 ::PackageResolvableAttributeHandler(
247 BPackageInfoAttributeValue& packageInfoValue)
248 :
249 super(packageInfoValue)
250 {
251 }
252
253
254 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)255 ReaderImplBase::PackageResolvableAttributeHandler::HandleAttribute(
256 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
257 AttributeHandler** _handler)
258 {
259 switch (id) {
260 case B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR:
261 fPackageInfoValue.resolvable.haveVersion = true;
262 fPackageInfoValue.resolvable.version.major = value.string;
263 if (_handler != NULL) {
264 *_handler
265 = new(context) PackageVersionAttributeHandler(
266 fPackageInfoValue,
267 fPackageInfoValue.resolvable.version, false);
268 if (*_handler == NULL)
269 return B_NO_MEMORY;
270 }
271 break;
272
273 case B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES_COMPATIBLE:
274 fPackageInfoValue.resolvable.haveCompatibleVersion = true;
275 fPackageInfoValue.resolvable.compatibleVersion.major = value.string;
276 if (_handler != NULL) {
277 *_handler
278 = new(context) PackageVersionAttributeHandler(
279 fPackageInfoValue,
280 fPackageInfoValue.resolvable.compatibleVersion, false);
281 if (*_handler == NULL)
282 return B_NO_MEMORY;
283 }
284 break;
285
286 default:
287 if (context->ignoreUnknownAttributes)
288 break;
289
290 context->errorOutput->PrintError("Error: Invalid package "
291 "attribute section: unexpected package attribute id %d "
292 "encountered when parsing package resolvable\n", id);
293 return B_BAD_DATA;
294 }
295
296 return B_OK;
297 }
298
299
300 // #pragma mark - PackageResolvableExpressionAttributeHandler
301
302
303 ReaderImplBase::PackageResolvableExpressionAttributeHandler
PackageResolvableExpressionAttributeHandler(BPackageInfoAttributeValue & packageInfoValue)304 ::PackageResolvableExpressionAttributeHandler(
305 BPackageInfoAttributeValue& packageInfoValue)
306 :
307 super(packageInfoValue)
308 {
309 }
310
311
312 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)313 ReaderImplBase::PackageResolvableExpressionAttributeHandler::HandleAttribute(
314 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
315 AttributeHandler** _handler)
316 {
317 switch (id) {
318 case B_HPKG_ATTRIBUTE_ID_PACKAGE_RESOLVABLE_OPERATOR:
319 if (value.unsignedInt >= B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT) {
320 context->errorOutput->PrintError(
321 "Error: Invalid package attribute section: invalid "
322 "package resolvable operator %lld encountered\n",
323 value.unsignedInt);
324 return B_BAD_DATA;
325 }
326 fPackageInfoValue.resolvableExpression.op
327 = (BPackageResolvableOperator)value.unsignedInt;
328 break;
329
330 case B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR:
331 fPackageInfoValue.resolvableExpression.haveOpAndVersion = true;
332 fPackageInfoValue.resolvableExpression.version.major
333 = value.string;
334 if (_handler != NULL) {
335 *_handler
336 = new(context) PackageVersionAttributeHandler(
337 fPackageInfoValue,
338 fPackageInfoValue.resolvableExpression.version,
339 false);
340 if (*_handler == NULL)
341 return B_NO_MEMORY;
342 }
343 return B_OK;
344
345 default:
346 if (context->ignoreUnknownAttributes)
347 break;
348
349 context->errorOutput->PrintError("Error: Invalid package "
350 "attribute section: unexpected package attribute id %d "
351 "encountered when parsing package resolvable-expression\n",
352 id);
353 return B_BAD_DATA;
354 }
355
356 return B_OK;
357 }
358
359
360 // #pragma mark - GlobalWritableFileInfoAttributeHandler
361
362
363 ReaderImplBase::GlobalWritableFileInfoAttributeHandler
GlobalWritableFileInfoAttributeHandler(BPackageInfoAttributeValue & packageInfoValue)364 ::GlobalWritableFileInfoAttributeHandler(
365 BPackageInfoAttributeValue& packageInfoValue)
366 :
367 super(packageInfoValue)
368 {
369 }
370
371
372 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)373 ReaderImplBase::GlobalWritableFileInfoAttributeHandler::HandleAttribute(
374 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
375 AttributeHandler** _handler)
376 {
377 switch (id) {
378 case B_HPKG_ATTRIBUTE_ID_PACKAGE_WRITABLE_FILE_UPDATE_TYPE:
379 if (value.unsignedInt >= B_WRITABLE_FILE_UPDATE_TYPE_ENUM_COUNT) {
380 context->errorOutput->PrintError(
381 "Error: Invalid package attribute section: invalid "
382 "global settings file update type %" B_PRIu64
383 " encountered\n", value.unsignedInt);
384 return B_BAD_DATA;
385 }
386 fPackageInfoValue.globalWritableFileInfo.updateType
387 = (BWritableFileUpdateType)value.unsignedInt;
388 break;
389
390 case B_HPKG_ATTRIBUTE_ID_PACKAGE_IS_WRITABLE_DIRECTORY:
391 fPackageInfoValue.globalWritableFileInfo.isDirectory
392 = value.unsignedInt != 0;
393 break;
394
395 default:
396 if (context->ignoreUnknownAttributes)
397 break;
398
399 context->errorOutput->PrintError("Error: Invalid package "
400 "attribute section: unexpected package attribute id %d "
401 "encountered when parsing global settings file info\n",
402 id);
403 return B_BAD_DATA;
404 }
405
406 return B_OK;
407 }
408
409
410 // #pragma mark - UserSettingsFileInfoAttributeHandler
411
412
413 ReaderImplBase::UserSettingsFileInfoAttributeHandler
UserSettingsFileInfoAttributeHandler(BPackageInfoAttributeValue & packageInfoValue)414 ::UserSettingsFileInfoAttributeHandler(
415 BPackageInfoAttributeValue& packageInfoValue)
416 :
417 super(packageInfoValue)
418 {
419 }
420
421
422 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)423 ReaderImplBase::UserSettingsFileInfoAttributeHandler::HandleAttribute(
424 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
425 AttributeHandler** _handler)
426 {
427 switch (id) {
428 case B_HPKG_ATTRIBUTE_ID_PACKAGE_SETTINGS_FILE_TEMPLATE:
429 fPackageInfoValue.userSettingsFileInfo.templatePath = value.string;
430 break;
431
432 case B_HPKG_ATTRIBUTE_ID_PACKAGE_IS_WRITABLE_DIRECTORY:
433 fPackageInfoValue.userSettingsFileInfo.isDirectory
434 = value.unsignedInt != 0;
435 break;
436
437 default:
438 if (context->ignoreUnknownAttributes)
439 break;
440
441 context->errorOutput->PrintError("Error: Invalid package "
442 "attribute section: unexpected package attribute id %d "
443 "encountered when parsing user settings file info\n",
444 id);
445 return B_BAD_DATA;
446 }
447
448 return B_OK;
449 }
450
451
452 // #pragma mark - UserAttributeHandler
453
454
UserAttributeHandler(BPackageInfoAttributeValue & packageInfoValue)455 ReaderImplBase::UserAttributeHandler::UserAttributeHandler(
456 BPackageInfoAttributeValue& packageInfoValue)
457 :
458 super(packageInfoValue),
459 fGroups()
460 {
461 }
462
463
464 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)465 ReaderImplBase::UserAttributeHandler::HandleAttribute(
466 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
467 AttributeHandler** _handler)
468 {
469 switch (id) {
470 case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_REAL_NAME:
471 fPackageInfoValue.user.realName = value.string;
472 break;
473
474 case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_HOME:
475 fPackageInfoValue.user.home = value.string;
476 break;
477
478 case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SHELL:
479 fPackageInfoValue.user.shell = value.string;
480 break;
481
482 case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_GROUP:
483 if (!fGroups.Add(value.string))
484 return B_NO_MEMORY;
485 break;
486
487 default:
488 if (context->ignoreUnknownAttributes)
489 break;
490
491 context->errorOutput->PrintError("Error: Invalid package "
492 "attribute section: unexpected package attribute id %d "
493 "encountered when parsing user settings file info\n",
494 id);
495 return B_BAD_DATA;
496 }
497
498 return B_OK;
499 }
500
501
502 status_t
NotifyDone(AttributeHandlerContext * context)503 ReaderImplBase::UserAttributeHandler::NotifyDone(
504 AttributeHandlerContext* context)
505 {
506 if (!fGroups.IsEmpty()) {
507 fPackageInfoValue.user.groups = fGroups.Elements();
508 fPackageInfoValue.user.groupCount = fGroups.Count();
509 }
510
511 return super::NotifyDone(context);
512 }
513
514
515 // #pragma mark - PackageAttributeHandler
516
517
518 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)519 ReaderImplBase::PackageAttributeHandler::HandleAttribute(
520 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
521 AttributeHandler** _handler)
522 {
523 switch (id) {
524 case B_HPKG_ATTRIBUTE_ID_PACKAGE_NAME:
525 fPackageInfoValue.SetTo(B_PACKAGE_INFO_NAME, value.string);
526 break;
527
528 case B_HPKG_ATTRIBUTE_ID_PACKAGE_SUMMARY:
529 fPackageInfoValue.SetTo(B_PACKAGE_INFO_SUMMARY, value.string);
530 break;
531
532 case B_HPKG_ATTRIBUTE_ID_PACKAGE_DESCRIPTION:
533 fPackageInfoValue.SetTo(B_PACKAGE_INFO_DESCRIPTION,
534 value.string);
535 break;
536
537 case B_HPKG_ATTRIBUTE_ID_PACKAGE_VENDOR:
538 fPackageInfoValue.SetTo(B_PACKAGE_INFO_VENDOR, value.string);
539 break;
540
541 case B_HPKG_ATTRIBUTE_ID_PACKAGE_PACKAGER:
542 fPackageInfoValue.SetTo(B_PACKAGE_INFO_PACKAGER, value.string);
543 break;
544
545 case B_HPKG_ATTRIBUTE_ID_PACKAGE_BASE_PACKAGE:
546 fPackageInfoValue.SetTo(B_PACKAGE_INFO_BASE_PACKAGE, value.string);
547 break;
548
549 case B_HPKG_ATTRIBUTE_ID_PACKAGE_FLAGS:
550 fPackageInfoValue.SetTo(B_PACKAGE_INFO_FLAGS,
551 (uint32)value.unsignedInt);
552 break;
553
554 case B_HPKG_ATTRIBUTE_ID_PACKAGE_ARCHITECTURE:
555 if (value.unsignedInt
556 >= B_PACKAGE_ARCHITECTURE_ENUM_COUNT) {
557 context->errorOutput->PrintError(
558 "Error: Invalid package attribute section: "
559 "Invalid package architecture %lld encountered\n",
560 value.unsignedInt);
561 return B_BAD_DATA;
562 }
563 fPackageInfoValue.SetTo(B_PACKAGE_INFO_ARCHITECTURE,
564 (uint8)value.unsignedInt);
565 break;
566
567 case B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR:
568 fPackageInfoValue.attributeID = B_PACKAGE_INFO_VERSION;
569 fPackageInfoValue.version.major = value.string;
570 if (_handler != NULL) {
571 *_handler
572 = new(context) PackageVersionAttributeHandler(
573 fPackageInfoValue, fPackageInfoValue.version, true);
574 if (*_handler == NULL)
575 return B_NO_MEMORY;
576 }
577 break;
578
579 case B_HPKG_ATTRIBUTE_ID_PACKAGE_COPYRIGHT:
580 fPackageInfoValue.SetTo(B_PACKAGE_INFO_COPYRIGHTS,
581 value.string);
582 break;
583
584 case B_HPKG_ATTRIBUTE_ID_PACKAGE_LICENSE:
585 fPackageInfoValue.SetTo(B_PACKAGE_INFO_LICENSES,
586 value.string);
587 break;
588
589 case B_HPKG_ATTRIBUTE_ID_PACKAGE_URL:
590 fPackageInfoValue.SetTo(B_PACKAGE_INFO_URLS, value.string);
591 break;
592
593 case B_HPKG_ATTRIBUTE_ID_PACKAGE_SOURCE_URL:
594 fPackageInfoValue.SetTo(B_PACKAGE_INFO_SOURCE_URLS, value.string);
595 break;
596
597 case B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES:
598 fPackageInfoValue.resolvable.name = value.string;
599 fPackageInfoValue.attributeID = B_PACKAGE_INFO_PROVIDES;
600 if (_handler != NULL) {
601 *_handler
602 = new(context) PackageResolvableAttributeHandler(
603 fPackageInfoValue);
604 if (*_handler == NULL)
605 return B_NO_MEMORY;
606 }
607 break;
608
609 case B_HPKG_ATTRIBUTE_ID_PACKAGE_REQUIRES:
610 case B_HPKG_ATTRIBUTE_ID_PACKAGE_SUPPLEMENTS:
611 case B_HPKG_ATTRIBUTE_ID_PACKAGE_CONFLICTS:
612 case B_HPKG_ATTRIBUTE_ID_PACKAGE_FRESHENS:
613 fPackageInfoValue.resolvableExpression.name = value.string;
614 switch (id) {
615 case B_HPKG_ATTRIBUTE_ID_PACKAGE_REQUIRES:
616 fPackageInfoValue.attributeID = B_PACKAGE_INFO_REQUIRES;
617 break;
618
619 case B_HPKG_ATTRIBUTE_ID_PACKAGE_SUPPLEMENTS:
620 fPackageInfoValue.attributeID
621 = B_PACKAGE_INFO_SUPPLEMENTS;
622 break;
623
624 case B_HPKG_ATTRIBUTE_ID_PACKAGE_CONFLICTS:
625 fPackageInfoValue.attributeID
626 = B_PACKAGE_INFO_CONFLICTS;
627 break;
628
629 case B_HPKG_ATTRIBUTE_ID_PACKAGE_FRESHENS:
630 fPackageInfoValue.attributeID = B_PACKAGE_INFO_FRESHENS;
631 break;
632 }
633 if (_handler != NULL) {
634 *_handler = new(context)
635 PackageResolvableExpressionAttributeHandler(
636 fPackageInfoValue);
637 if (*_handler == NULL)
638 return B_NO_MEMORY;
639 }
640 break;
641
642 case B_HPKG_ATTRIBUTE_ID_PACKAGE_REPLACES:
643 fPackageInfoValue.SetTo(B_PACKAGE_INFO_REPLACES, value.string);
644 break;
645
646 case B_HPKG_ATTRIBUTE_ID_PACKAGE_CHECKSUM:
647 fPackageInfoValue.SetTo(B_PACKAGE_INFO_CHECKSUM, value.string);
648 break;
649
650 case B_HPKG_ATTRIBUTE_ID_PACKAGE_INSTALL_PATH:
651 fPackageInfoValue.SetTo(B_PACKAGE_INFO_INSTALL_PATH, value.string);
652 break;
653
654 case B_HPKG_ATTRIBUTE_ID_PACKAGE_GLOBAL_WRITABLE_FILE:
655 fPackageInfoValue.globalWritableFileInfo.path = value.string;
656 fPackageInfoValue.globalWritableFileInfo.updateType
657 = B_WRITABLE_FILE_UPDATE_TYPE_ENUM_COUNT;
658 fPackageInfoValue.attributeID
659 = B_PACKAGE_INFO_GLOBAL_WRITABLE_FILES;
660 if (_handler != NULL) {
661 *_handler
662 = new(context) GlobalWritableFileInfoAttributeHandler(
663 fPackageInfoValue);
664 if (*_handler == NULL)
665 return B_NO_MEMORY;
666 }
667 break;
668
669 case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SETTINGS_FILE:
670 fPackageInfoValue.userSettingsFileInfo.path = value.string;
671 fPackageInfoValue.attributeID
672 = B_PACKAGE_INFO_USER_SETTINGS_FILES;
673 if (_handler != NULL) {
674 *_handler
675 = new(context) UserSettingsFileInfoAttributeHandler(
676 fPackageInfoValue);
677 if (*_handler == NULL)
678 return B_NO_MEMORY;
679 }
680 break;
681
682 case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER:
683 fPackageInfoValue.user.name = value.string;
684 fPackageInfoValue.attributeID = B_PACKAGE_INFO_USERS;
685 if (_handler != NULL) {
686 *_handler = new(context) UserAttributeHandler(
687 fPackageInfoValue);
688 if (*_handler == NULL)
689 return B_NO_MEMORY;
690 }
691 break;
692
693 case B_HPKG_ATTRIBUTE_ID_PACKAGE_GROUP:
694 fPackageInfoValue.SetTo(B_PACKAGE_INFO_GROUPS, value.string);
695 break;
696
697 case B_HPKG_ATTRIBUTE_ID_PACKAGE_POST_INSTALL_SCRIPT:
698 fPackageInfoValue.SetTo(B_PACKAGE_INFO_POST_INSTALL_SCRIPTS,
699 value.string);
700 break;
701
702 case B_HPKG_ATTRIBUTE_ID_PACKAGE_PRE_UNINSTALL_SCRIPT:
703 fPackageInfoValue.SetTo(B_PACKAGE_INFO_PRE_UNINSTALL_SCRIPTS,
704 value.string);
705 break;
706
707 default:
708 if (context->ignoreUnknownAttributes)
709 break;
710
711 context->errorOutput->PrintError(
712 "Error: Invalid package attribute section: unexpected "
713 "package attribute id %d encountered\n", id);
714 return B_BAD_DATA;
715 }
716
717 // notify unless the current attribute has children, in which case
718 // the child-handler will notify when it's done
719 if (_handler == NULL) {
720 status_t error = context->packageContentHandler
721 ->HandlePackageAttribute(fPackageInfoValue);
722 if (context->ignoreUnknownAttributes && error == B_NOT_SUPPORTED)
723 error = B_OK; // Safe to skip a future/unknown attribute.
724 fPackageInfoValue.Clear();
725 if (error != B_OK)
726 return error;
727 }
728
729 return B_OK;
730 }
731
732
733 // #pragma mark - LowLevelAttributeHandler
734
735
LowLevelAttributeHandler()736 ReaderImplBase::LowLevelAttributeHandler::LowLevelAttributeHandler()
737 :
738 fParentToken(NULL),
739 fToken(NULL),
740 fID(B_HPKG_ATTRIBUTE_ID_ENUM_COUNT)
741 {
742 }
743
744
LowLevelAttributeHandler(uint8 id,const BPackageAttributeValue & value,void * parentToken,void * token)745 ReaderImplBase::LowLevelAttributeHandler::LowLevelAttributeHandler(uint8 id,
746 const BPackageAttributeValue& value, void* parentToken, void* token)
747 :
748 fParentToken(NULL),
749 fToken(token),
750 fID(id),
751 fValue(value)
752 {
753 }
754
755
756 status_t
HandleAttribute(AttributeHandlerContext * context,uint8 id,const AttributeValue & value,AttributeHandler ** _handler)757 ReaderImplBase::LowLevelAttributeHandler::HandleAttribute(
758 AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
759 AttributeHandler** _handler)
760 {
761 // notify the content handler
762 void* token;
763 status_t error = context->lowLevelHandler->HandleAttribute(
764 (BHPKGAttributeID)id, value, fToken, token);
765 if (error != B_OK)
766 return error;
767
768 // create a subhandler for the attribute, if it has children
769 if (_handler != NULL) {
770 *_handler = new(context) LowLevelAttributeHandler(id, value,
771 fToken, token);
772 if (*_handler == NULL) {
773 context->lowLevelHandler->HandleAttributeDone((BHPKGAttributeID)id,
774 value, fToken, token);
775 return B_NO_MEMORY;
776 }
777 return B_OK;
778 }
779
780 // no children -- just call the done hook
781 return context->lowLevelHandler->HandleAttributeDone((BHPKGAttributeID)id,
782 value, fToken, token);
783 }
784
785
786 status_t
NotifyDone(AttributeHandlerContext * context)787 ReaderImplBase::LowLevelAttributeHandler::NotifyDone(
788 AttributeHandlerContext* context)
789 {
790 if (fID != B_HPKG_ATTRIBUTE_ID_ENUM_COUNT) {
791 status_t error = context->lowLevelHandler->HandleAttributeDone(
792 (BHPKGAttributeID)fID, fValue, fParentToken, fToken);
793 if (error != B_OK)
794 return error;
795 }
796 return super::NotifyDone(context);
797 }
798
799
800 // #pragma mark - ReaderImplBase
801
802
ReaderImplBase(const char * fileType,BErrorOutput * errorOutput)803 ReaderImplBase::ReaderImplBase(const char* fileType, BErrorOutput* errorOutput)
804 :
805 fPackageAttributesSection("package attributes"),
806 fFileType(fileType),
807 fErrorOutput(errorOutput),
808 fFile(NULL),
809 fOwnsFile(false),
810 fRawHeapReader(NULL),
811 fHeapReader(NULL),
812 fCurrentSection(NULL)
813 {
814 }
815
816
~ReaderImplBase()817 ReaderImplBase::~ReaderImplBase()
818 {
819 delete fHeapReader;
820 if (fRawHeapReader != fHeapReader)
821 delete fRawHeapReader;
822
823 if (fOwnsFile)
824 delete fFile;
825 }
826
827
828 uint64
UncompressedHeapSize() const829 ReaderImplBase::UncompressedHeapSize() const
830 {
831 return fRawHeapReader->UncompressedHeapSize();
832 }
833
834
835 BAbstractBufferedDataReader*
DetachHeapReader(PackageFileHeapReader * & _rawHeapReader)836 ReaderImplBase::DetachHeapReader(PackageFileHeapReader*& _rawHeapReader)
837 {
838 BAbstractBufferedDataReader* heapReader = fHeapReader;
839 _rawHeapReader = fRawHeapReader;
840 fHeapReader = NULL;
841 fRawHeapReader = NULL;
842
843 return heapReader;
844 }
845
846
847 status_t
InitHeapReader(uint32 compression,uint32 chunkSize,off_t offset,uint64 compressedSize,uint64 uncompressedSize)848 ReaderImplBase::InitHeapReader(uint32 compression, uint32 chunkSize,
849 off_t offset, uint64 compressedSize, uint64 uncompressedSize)
850 {
851 DecompressionAlgorithmOwner* decompressionAlgorithm = NULL;
852 BReference<DecompressionAlgorithmOwner> decompressionAlgorithmReference;
853
854 switch (compression) {
855 case B_HPKG_COMPRESSION_NONE:
856 break;
857 case B_HPKG_COMPRESSION_ZLIB:
858 decompressionAlgorithm = DecompressionAlgorithmOwner::Create(
859 new(std::nothrow) BZlibCompressionAlgorithm,
860 new(std::nothrow) BZlibDecompressionParameters);
861 decompressionAlgorithmReference.SetTo(decompressionAlgorithm, true);
862 if (decompressionAlgorithm == NULL
863 || decompressionAlgorithm->algorithm == NULL
864 || decompressionAlgorithm->parameters == NULL) {
865 return B_NO_MEMORY;
866 }
867 break;
868 case B_HPKG_COMPRESSION_ZSTD:
869 decompressionAlgorithm = DecompressionAlgorithmOwner::Create(
870 new(std::nothrow) BZstdCompressionAlgorithm,
871 new(std::nothrow) BZstdDecompressionParameters);
872 decompressionAlgorithmReference.SetTo(decompressionAlgorithm, true);
873 if (decompressionAlgorithm == NULL
874 || decompressionAlgorithm->algorithm == NULL
875 || decompressionAlgorithm->parameters == NULL) {
876 return B_NO_MEMORY;
877 }
878 break;
879 default:
880 fErrorOutput->PrintError("Error: Invalid heap compression\n");
881 return B_BAD_DATA;
882 }
883
884 fRawHeapReader = new(std::nothrow) PackageFileHeapReader(fErrorOutput,
885 fFile, offset, compressedSize, uncompressedSize,
886 decompressionAlgorithm);
887 if (fRawHeapReader == NULL)
888 return B_NO_MEMORY;
889
890 status_t error = fRawHeapReader->Init();
891 if (error != B_OK)
892 return error;
893
894 error = CreateCachedHeapReader(fRawHeapReader, fHeapReader);
895 if (error != B_OK) {
896 if (error != B_NOT_SUPPORTED)
897 return error;
898
899 fHeapReader = fRawHeapReader;
900 }
901
902 return B_OK;
903 }
904
905
906 status_t
CreateCachedHeapReader(PackageFileHeapReader * heapReader,BAbstractBufferedDataReader * & _cachedReader)907 ReaderImplBase::CreateCachedHeapReader(PackageFileHeapReader* heapReader,
908 BAbstractBufferedDataReader*& _cachedReader)
909 {
910 return B_NOT_SUPPORTED;
911 }
912
913
914 status_t
InitSection(PackageFileSection & section,uint64 endOffset,uint64 length,uint64 maxSaneLength,uint64 stringsLength,uint64 stringsCount)915 ReaderImplBase::InitSection(PackageFileSection& section, uint64 endOffset,
916 uint64 length, uint64 maxSaneLength, uint64 stringsLength,
917 uint64 stringsCount)
918 {
919 // check length vs. endOffset
920 if (length > endOffset) {
921 ErrorOutput()->PrintError("Error: %s file %s section size is %"
922 B_PRIu64 " bytes. This is greater than the available space\n",
923 fFileType, section.name, length);
924 return B_BAD_DATA;
925 }
926
927 // check sanity length
928 if (maxSaneLength > 0 && length > maxSaneLength) {
929 ErrorOutput()->PrintError("Error: %s file %s section size is %"
930 B_PRIu64 " bytes. This is beyond the reader's sanity limit\n",
931 fFileType, section.name, length);
932 return B_NOT_SUPPORTED;
933 }
934
935 // check strings subsection size/count
936 if ((stringsLength <= 1) != (stringsCount == 0) || stringsLength > length) {
937 ErrorOutput()->PrintError("Error: strings subsection description of %s "
938 "file %s section is invalid (%" B_PRIu64 " strings, length: %"
939 B_PRIu64 ", section length: %" B_PRIu64 ")\n",
940 fFileType, section.name, stringsCount, stringsLength, length);
941 return B_BAD_DATA;
942 }
943
944 section.uncompressedLength = length;
945 section.offset = endOffset - length;
946 section.currentOffset = 0;
947 section.stringsLength = stringsLength;
948 section.stringsCount = stringsCount;
949
950 return B_OK;
951 }
952
953
954 status_t
PrepareSection(PackageFileSection & section)955 ReaderImplBase::PrepareSection(PackageFileSection& section)
956 {
957 // allocate memory for the section data and read it in
958 section.data = new(std::nothrow) uint8[section.uncompressedLength];
959 if (section.data == NULL) {
960 ErrorOutput()->PrintError("Error: Out of memory!\n");
961 return B_NO_MEMORY;
962 }
963
964 status_t error = ReadSection(section);
965 if (error != B_OK)
966 return error;
967
968 // parse the section strings
969 section.currentOffset = 0;
970 SetCurrentSection(§ion);
971
972 error = ParseStrings();
973 if (error != B_OK)
974 return error;
975
976 return B_OK;
977 }
978
979
980 status_t
ParseStrings()981 ReaderImplBase::ParseStrings()
982 {
983 // allocate table, if there are any strings
984 if (fCurrentSection->stringsCount == 0) {
985 fCurrentSection->currentOffset += fCurrentSection->stringsLength;
986 return B_OK;
987 }
988
989 fCurrentSection->strings
990 = new(std::nothrow) char*[fCurrentSection->stringsCount];
991 if (fCurrentSection->strings == NULL) {
992 fErrorOutput->PrintError("Error: Out of memory!\n");
993 return B_NO_MEMORY;
994 }
995
996 // parse the section and fill the table
997 char* position
998 = (char*)fCurrentSection->data + fCurrentSection->currentOffset;
999 char* sectionEnd = position + fCurrentSection->stringsLength;
1000 uint32 index = 0;
1001 while (true) {
1002 if (position >= sectionEnd) {
1003 fErrorOutput->PrintError("Error: Malformed %s strings section\n",
1004 fCurrentSection->name);
1005 return B_BAD_DATA;
1006 }
1007
1008 size_t stringLength = strnlen(position, (char*)sectionEnd - position);
1009
1010 if (stringLength == 0) {
1011 if (position + 1 != sectionEnd) {
1012 fErrorOutput->PrintError(
1013 "Error: %ld excess bytes in %s strings section\n",
1014 sectionEnd - (position + 1), fCurrentSection->name);
1015 return B_BAD_DATA;
1016 }
1017
1018 if (index != fCurrentSection->stringsCount) {
1019 fErrorOutput->PrintError("Error: Invalid %s strings section: "
1020 "Less strings (%lld) than specified in the header (%lld)\n",
1021 fCurrentSection->name, index,
1022 fCurrentSection->stringsCount);
1023 return B_BAD_DATA;
1024 }
1025
1026 fCurrentSection->currentOffset += fCurrentSection->stringsLength;
1027
1028 return B_OK;
1029 }
1030
1031 if (index >= fCurrentSection->stringsCount) {
1032 fErrorOutput->PrintError("Error: Invalid %s strings section: "
1033 "More strings (%lld) than specified in the header (%lld)\n",
1034 fCurrentSection->name, index, fCurrentSection->stringsCount);
1035 return B_BAD_DATA;
1036 }
1037
1038 fCurrentSection->strings[index++] = position;
1039 position += stringLength + 1;
1040 }
1041 }
1042
1043
1044 status_t
ParsePackageAttributesSection(AttributeHandlerContext * context,AttributeHandler * rootAttributeHandler)1045 ReaderImplBase::ParsePackageAttributesSection(
1046 AttributeHandlerContext* context, AttributeHandler* rootAttributeHandler)
1047 {
1048 // parse package attributes
1049 SetCurrentSection(&fPackageAttributesSection);
1050
1051 // init the attribute handler stack
1052 rootAttributeHandler->SetLevel(0);
1053 ClearAttributeHandlerStack();
1054 PushAttributeHandler(rootAttributeHandler);
1055
1056 bool sectionHandled;
1057 status_t error = ParseAttributeTree(context, sectionHandled);
1058 if (error == B_OK && sectionHandled) {
1059 if (fPackageAttributesSection.currentOffset
1060 < fPackageAttributesSection.uncompressedLength) {
1061 fErrorOutput->PrintError("Error: %llu excess byte(s) in package "
1062 "attributes section\n",
1063 fPackageAttributesSection.uncompressedLength
1064 - fPackageAttributesSection.currentOffset);
1065 error = B_BAD_DATA;
1066 }
1067 }
1068
1069 SetCurrentSection(NULL);
1070
1071 // clean up on error
1072 if (error != B_OK) {
1073 context->ErrorOccurred();
1074 while (AttributeHandler* handler = PopAttributeHandler()) {
1075 if (handler != rootAttributeHandler)
1076 handler->Delete(context);
1077 }
1078 return error;
1079 }
1080
1081 return B_OK;
1082 }
1083
1084
1085 status_t
ParseAttributeTree(AttributeHandlerContext * context,bool & _sectionHandled)1086 ReaderImplBase::ParseAttributeTree(AttributeHandlerContext* context,
1087 bool& _sectionHandled)
1088 {
1089 if (context->hasLowLevelHandler) {
1090 bool handleSection = false;
1091 status_t error = context->lowLevelHandler->HandleSectionStart(
1092 context->section, handleSection);
1093 if (error != B_OK)
1094 return error;
1095
1096 if (!handleSection) {
1097 _sectionHandled = false;
1098 return B_OK;
1099 }
1100 }
1101
1102 status_t error = _ParseAttributeTree(context);
1103
1104 if (context->hasLowLevelHandler) {
1105 status_t endError = context->lowLevelHandler->HandleSectionEnd(
1106 context->section);
1107 if (error == B_OK)
1108 error = endError;
1109 }
1110
1111 _sectionHandled = true;
1112 return error;
1113 }
1114
1115
1116 status_t
_Init(BPositionIO * file,bool keepFile)1117 ReaderImplBase::_Init(BPositionIO* file, bool keepFile)
1118 {
1119 fFile = file;
1120 fOwnsFile = keepFile;
1121 return fFile != NULL ? B_OK : B_BAD_VALUE;
1122 }
1123
1124
1125 status_t
_ParseAttributeTree(AttributeHandlerContext * context)1126 ReaderImplBase::_ParseAttributeTree(AttributeHandlerContext* context)
1127 {
1128 int level = 0;
1129
1130 while (true) {
1131 uint8 id;
1132 AttributeValue value;
1133 bool hasChildren;
1134 uint64 tag;
1135
1136 status_t error = _ReadAttribute(id, value, &hasChildren, &tag);
1137 if (error != B_OK)
1138 return error;
1139
1140 if (tag == 0) {
1141 AttributeHandler* handler = PopAttributeHandler();
1142 error = handler->NotifyDone(context);
1143 if (error != B_OK)
1144 return error;
1145 if (level-- == 0)
1146 return B_OK;
1147
1148 error = handler->Delete(context);
1149 if (error != B_OK)
1150 return error;
1151
1152 continue;
1153 }
1154
1155 AttributeHandler* childHandler = NULL;
1156 error = CurrentAttributeHandler()->HandleAttribute(context, id, value,
1157 hasChildren ? &childHandler : NULL);
1158 if (error != B_OK)
1159 return error;
1160
1161 // parse children
1162 if (hasChildren) {
1163 // create an ignore handler, if necessary
1164 if (childHandler == NULL) {
1165 childHandler = new(context) IgnoreAttributeHandler;
1166 if (childHandler == NULL) {
1167 fErrorOutput->PrintError("Error: Out of memory!\n");
1168 return B_NO_MEMORY;
1169 }
1170 }
1171
1172 childHandler->SetLevel(++level);
1173 PushAttributeHandler(childHandler);
1174 }
1175 }
1176 }
1177
1178
1179 status_t
_ReadAttribute(uint8 & _id,AttributeValue & _value,bool * _hasChildren,uint64 * _tag)1180 ReaderImplBase::_ReadAttribute(uint8& _id, AttributeValue& _value,
1181 bool* _hasChildren, uint64* _tag)
1182 {
1183 uint64 tag;
1184 status_t error = ReadUnsignedLEB128(tag);
1185 if (error != B_OK)
1186 return error;
1187
1188 if (tag != 0) {
1189 // get the type
1190 uint16 type = attribute_tag_type(tag);
1191 if (type >= B_HPKG_ATTRIBUTE_TYPE_ENUM_COUNT) {
1192 fErrorOutput->PrintError("Error: Invalid %s section: attribute "
1193 "type %d not supported!\n", fCurrentSection->name, type);
1194 return B_BAD_DATA;
1195 }
1196
1197 // get the ID
1198 _id = attribute_tag_id(tag);
1199 if (_id < B_HPKG_ATTRIBUTE_ID_ENUM_COUNT) {
1200 if (type != kAttributeTypes[_id]) {
1201 fErrorOutput->PrintError("Error: Invalid %s section: "
1202 "unexpected type %d for attribute id %d (expected %d)!\n",
1203 fCurrentSection->name, type, _id, kAttributeTypes[_id]);
1204 return B_BAD_DATA;
1205 }
1206 } else if (fMinorFormatVersion <= fCurrentMinorFormatVersion) {
1207 fErrorOutput->PrintError("Error: Invalid %s section: "
1208 "attribute id %d not supported!\n", fCurrentSection->name, _id);
1209 return B_BAD_DATA;
1210 }
1211
1212 // get the value
1213 error = ReadAttributeValue(type, attribute_tag_encoding(tag),
1214 _value);
1215 if (error != B_OK)
1216 return error;
1217 }
1218
1219 if (_hasChildren != NULL)
1220 *_hasChildren = attribute_tag_has_children(tag);
1221 if (_tag != NULL)
1222 *_tag = tag;
1223
1224 return B_OK;
1225 }
1226
1227
1228 status_t
ReadAttributeValue(uint8 type,uint8 encoding,AttributeValue & _value)1229 ReaderImplBase::ReadAttributeValue(uint8 type, uint8 encoding,
1230 AttributeValue& _value)
1231 {
1232 switch (type) {
1233 case B_HPKG_ATTRIBUTE_TYPE_INT:
1234 case B_HPKG_ATTRIBUTE_TYPE_UINT:
1235 {
1236 uint64 intValue;
1237 status_t error;
1238
1239 switch (encoding) {
1240 case B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT:
1241 {
1242 uint8 value;
1243 error = _Read(value);
1244 intValue = value;
1245 break;
1246 }
1247 case B_HPKG_ATTRIBUTE_ENCODING_INT_16_BIT:
1248 {
1249 uint16 value;
1250 error = _Read(value);
1251 intValue = B_BENDIAN_TO_HOST_INT16(value);
1252 break;
1253 }
1254 case B_HPKG_ATTRIBUTE_ENCODING_INT_32_BIT:
1255 {
1256 uint32 value;
1257 error = _Read(value);
1258 intValue = B_BENDIAN_TO_HOST_INT32(value);
1259 break;
1260 }
1261 case B_HPKG_ATTRIBUTE_ENCODING_INT_64_BIT:
1262 {
1263 uint64 value;
1264 error = _Read(value);
1265 intValue = B_BENDIAN_TO_HOST_INT64(value);
1266 break;
1267 }
1268 default:
1269 {
1270 fErrorOutput->PrintError("Error: Invalid %s section: "
1271 "invalid encoding %d for int value type %d\n",
1272 fCurrentSection->name, encoding, type);
1273 return B_BAD_VALUE;
1274 }
1275 }
1276
1277 if (error != B_OK)
1278 return error;
1279
1280 if (type == B_HPKG_ATTRIBUTE_TYPE_INT)
1281 _value.SetTo((int64)intValue);
1282 else
1283 _value.SetTo(intValue);
1284
1285 return B_OK;
1286 }
1287
1288 case B_HPKG_ATTRIBUTE_TYPE_STRING:
1289 {
1290 if (encoding == B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE) {
1291 uint64 index;
1292 status_t error = ReadUnsignedLEB128(index);
1293 if (error != B_OK)
1294 return error;
1295
1296 if (index > fCurrentSection->stringsCount) {
1297 fErrorOutput->PrintError("Error: Invalid %s section: "
1298 "string reference (%lld) out of bounds (%lld)\n",
1299 fCurrentSection->name, index,
1300 fCurrentSection->stringsCount);
1301 return B_BAD_DATA;
1302 }
1303
1304 _value.SetTo(fCurrentSection->strings[index]);
1305 } else if (encoding == B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE) {
1306 const char* string;
1307 status_t error = _ReadString(string);
1308 if (error != B_OK)
1309 return error;
1310
1311 _value.SetTo(string);
1312 } else {
1313 fErrorOutput->PrintError("Error: Invalid %s section: invalid "
1314 "string encoding (%u)\n", fCurrentSection->name, encoding);
1315 return B_BAD_DATA;
1316 }
1317
1318 return B_OK;
1319 }
1320
1321 default:
1322 fErrorOutput->PrintError("Error: Invalid %s section: invalid "
1323 "value type: %d\n", fCurrentSection->name, type);
1324 return B_BAD_DATA;
1325 }
1326 }
1327
1328
1329 status_t
ReadUnsignedLEB128(uint64 & _value)1330 ReaderImplBase::ReadUnsignedLEB128(uint64& _value)
1331 {
1332 uint64 result = 0;
1333 int shift = 0;
1334 while (true) {
1335 uint8 byte;
1336 status_t error = _Read(byte);
1337 if (error != B_OK)
1338 return error;
1339
1340 result |= uint64(byte & 0x7f) << shift;
1341 if ((byte & 0x80) == 0)
1342 break;
1343 shift += 7;
1344 }
1345
1346 _value = result;
1347 return B_OK;
1348 }
1349
1350
1351 status_t
_ReadString(const char * & _string,size_t * _stringLength)1352 ReaderImplBase::_ReadString(const char*& _string, size_t* _stringLength)
1353 {
1354 const char* string
1355 = (const char*)fCurrentSection->data + fCurrentSection->currentOffset;
1356 size_t stringLength = strnlen(string,
1357 fCurrentSection->uncompressedLength - fCurrentSection->currentOffset);
1358
1359 if (stringLength
1360 == fCurrentSection->uncompressedLength
1361 - fCurrentSection->currentOffset) {
1362 fErrorOutput->PrintError(
1363 "_ReadString(): string extends beyond %s end\n",
1364 fCurrentSection->name);
1365 return B_BAD_DATA;
1366 }
1367
1368 _string = string;
1369 if (_stringLength != NULL)
1370 *_stringLength = stringLength;
1371
1372 fCurrentSection->currentOffset += stringLength + 1;
1373 return B_OK;
1374 }
1375
1376
1377 status_t
_ReadSectionBuffer(void * buffer,size_t size)1378 ReaderImplBase::_ReadSectionBuffer(void* buffer, size_t size)
1379 {
1380 if (size > fCurrentSection->uncompressedLength
1381 - fCurrentSection->currentOffset) {
1382 fErrorOutput->PrintError(
1383 "_ReadSectionBuffer(%lu): read beyond %s end\n", size,
1384 fCurrentSection->name);
1385 return B_BAD_DATA;
1386 }
1387
1388 memcpy(buffer, fCurrentSection->data + fCurrentSection->currentOffset,
1389 size);
1390 fCurrentSection->currentOffset += size;
1391 return B_OK;
1392 }
1393
1394
1395 status_t
ReadBuffer(off_t offset,void * buffer,size_t size)1396 ReaderImplBase::ReadBuffer(off_t offset, void* buffer, size_t size)
1397 {
1398 status_t error = fFile->ReadAtExactly(offset, buffer, size);
1399 if (error != B_OK) {
1400 fErrorOutput->PrintError("_ReadBuffer(%p, %lu) failed to read data: "
1401 "%s\n", buffer, size, strerror(error));
1402 return error;
1403 }
1404
1405 return B_OK;
1406 }
1407
1408
1409 status_t
ReadSection(const PackageFileSection & section)1410 ReaderImplBase::ReadSection(const PackageFileSection& section)
1411 {
1412 return fHeapReader->ReadData(section.offset,
1413 section.data, section.uncompressedLength);
1414 }
1415
1416
1417 } // namespace BPrivate
1418
1419 } // namespace BHPKG
1420
1421 } // namespace BPackageKit
1422