1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "ResChunkPullParser.h" 18 19 #include <androidfw/ResourceTypes.h> 20 #include <cstddef> 21 22 namespace aapt { 23 24 using android::ResChunk_header; 25 next()26ResChunkPullParser::Event ResChunkPullParser::next() { 27 if (!isGoodEvent(mEvent)) { 28 return mEvent; 29 } 30 31 if (mEvent == Event::StartDocument) { 32 mCurrentChunk = mData; 33 } else { 34 mCurrentChunk = reinterpret_cast<const ResChunk_header*>( 35 reinterpret_cast<const char*>(mCurrentChunk) + mCurrentChunk->size); 36 } 37 38 const std::ptrdiff_t diff = reinterpret_cast<const char*>(mCurrentChunk) 39 - reinterpret_cast<const char*>(mData); 40 assert(diff >= 0 && "diff is negative"); 41 const size_t offset = static_cast<const size_t>(diff); 42 43 if (offset == mLen) { 44 mCurrentChunk = nullptr; 45 return (mEvent = Event::EndDocument); 46 } else if (offset + sizeof(ResChunk_header) > mLen) { 47 mLastError = "chunk is past the end of the document"; 48 mCurrentChunk = nullptr; 49 return (mEvent = Event::BadDocument); 50 } 51 52 if (mCurrentChunk->headerSize < sizeof(ResChunk_header)) { 53 mLastError = "chunk has too small header"; 54 mCurrentChunk = nullptr; 55 return (mEvent = Event::BadDocument); 56 } else if (mCurrentChunk->size < mCurrentChunk->headerSize) { 57 mLastError = "chunk's total size is smaller than header"; 58 mCurrentChunk = nullptr; 59 return (mEvent = Event::BadDocument); 60 } else if (offset + mCurrentChunk->size > mLen) { 61 mLastError = "chunk's data extends past the end of the document"; 62 mCurrentChunk = nullptr; 63 return (mEvent = Event::BadDocument); 64 } 65 return (mEvent = Event::Chunk); 66 } 67 68 } // namespace aapt 69