16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/* 26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project 36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License. 66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at 76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software 116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and 146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License. 156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "unflatten/ResChunkPullParser.h" 181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h" 196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <androidfw/ResourceTypes.h> 216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <cstddef> 226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt { 246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiusing android::ResChunk_header; 266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiResChunkPullParser::Event ResChunkPullParser::next() { 286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (!isGoodEvent(mEvent)) { 296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return mEvent; 306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (mEvent == Event::StartDocument) { 336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mCurrentChunk = mData; 346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else { 351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski mCurrentChunk = (const ResChunk_header*) 361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski (((const char*) mCurrentChunk) + util::deviceToHost32(mCurrentChunk->size)); 376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 391ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski const std::ptrdiff_t diff = (const char*) mCurrentChunk - (const char*) mData; 406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski assert(diff >= 0 && "diff is negative"); 416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const size_t offset = static_cast<const size_t>(diff); 426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (offset == mLen) { 446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mCurrentChunk = nullptr; 456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return (mEvent = Event::EndDocument); 466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else if (offset + sizeof(ResChunk_header) > mLen) { 476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mLastError = "chunk is past the end of the document"; 486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mCurrentChunk = nullptr; 496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return (mEvent = Event::BadDocument); 506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 521ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski if (util::deviceToHost16(mCurrentChunk->headerSize) < sizeof(ResChunk_header)) { 536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mLastError = "chunk has too small header"; 546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mCurrentChunk = nullptr; 556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return (mEvent = Event::BadDocument); 561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } else if (util::deviceToHost32(mCurrentChunk->size) < 571ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski util::deviceToHost16(mCurrentChunk->headerSize)) { 586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mLastError = "chunk's total size is smaller than header"; 596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mCurrentChunk = nullptr; 606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return (mEvent = Event::BadDocument); 611ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } else if (offset + util::deviceToHost32(mCurrentChunk->size) > mLen) { 626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mLastError = "chunk's data extends past the end of the document"; 636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mCurrentChunk = nullptr; 646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return (mEvent = Event::BadDocument); 656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return (mEvent = Event::Chunk); 676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} // namespace aapt 70