static unsigned long sk_stream_read(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count ) { SkStream* str = (SkStream*)stream->descriptor.pointer; if (count) { if (!str->rewind()) { return 0; } else { unsigned long ret; if (offset) { ret = str->read(NULL, offset); if (ret != offset) { return 0; } } ret = str->read(buffer, count); if (ret != count) { return 0; } count = ret; } } return count; }
bool SkXMLParser::parse(SkStream& input) { size_t len = input.read(NULL, 0); SkAutoMalloc am(len); char* doc = (char*)am.get(); input.rewind(); size_t len2 = input.read(doc, len); SkASSERT(len2 == len); return this->parse(doc, len2); }
bool AutoCleanPng::decodeBounds() { if (setjmp(png_jmpbuf(fPng_ptr))) { return false; } png_set_progressive_read_fn(fPng_ptr, this, InfoCallback, nullptr, nullptr); // Arbitrary buffer size, though note that it matches (below) // SkPngCodec::processData(). FIXME: Can we better suit this to the size of // the PNG header? constexpr size_t kBufferSize = 4096; char buffer[kBufferSize]; while (true) { const size_t bytesRead = fStream->read(buffer, kBufferSize); if (!bytesRead) { // We have read to the end of the input without decoding bounds. break; } png_process_data(fPng_ptr, fInfo_ptr, (png_bytep) buffer, bytesRead); if (fDecodedBounds) { break; } } // For safety, clear the pointer to this object. png_set_progressive_read_fn(fPng_ptr, nullptr, nullptr, nullptr, nullptr); return fDecodedBounds; }
static uint8_t rbyte(SkStream& s) { uint8_t b; SkDEBUGCODE(size_t size = ) s.read(&b, 1); SkASSERT(size == 1); return b; }
static uint8_t rbyte(SkStream& s) { uint8_t b; size_t size = s.read(&b, 1); SkASSERT(size == 1); return b; }
static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) { SkStream* stream = static_cast<SkStream*>(png_get_io_ptr(png_ptr)); const size_t bytes = stream->read(data, length); if (bytes != length) { // FIXME: We want to report the fact that the stream was truncated. // One way to do that might be to pass a enum to longjmp so setjmp can // specify the failure. png_error(png_ptr, "Read Error!"); } }
static void set(char* array[256], int index, SkStream& s, int data) { SkASSERT((unsigned)index <= 255); size_t size = rdata(s, data); if (array[index] == NULL) array[index] = (char*)sk_malloc_throw(size + 1); else { if (strlen(array[index]) < size) array[index] = (char*)sk_realloc_throw(array[index], size + 1); } s.read(array[index], size); array[index][size] = 0; }
static FPDFEMB_RESULT file_readblock(FPDFEMB_FILE_ACCESS* file, void* dst, unsigned int offset, unsigned int size) { SkStream* stream = (SkStream*)file->user; // SkDebugf("---- readblock %p %p %d %d\n", stream, dst, offset, size); if (!stream->rewind()) { SkDebugf("---- rewind failed\n"); return FPDFERR_ERROR; } if (stream->skip(offset) != offset) { SkDebugf("---- skip failed\n"); return FPDFERR_ERROR; } if (stream->read(dst, size) != size) { SkDebugf("---- read failed\n"); return FPDFERR_ERROR; } return FPDFERR_SUCCESS; }
size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag, size_t offset, size_t length, void* data) { SkStream* stream = SkFontHost::OpenStream(fontID); if (NULL == stream) { return 0; } SkAutoUnref au(stream); SfntHeader header; if (!header.init(stream)) { return 0; } for (int i = 0; i < header.fCount; i++) { if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) { size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset); size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength); // now sanity check the caller's offset/length if (offset >= realLength) { return 0; } // if the caller is trusting the length from the file, then a // hostile file might choose a value which would overflow offset + // length. if (offset + length < offset) { return 0; } if (offset + length > realLength) { length = realLength - offset; } // skip the stream to the part of the table we want to copy from stream->rewind(); size_t bytesToSkip = realOffset + offset; if (stream->skip(bytesToSkip) != bytesToSkip) { return 0; } if (stream->read(data, length) != length) { return 0; } return length; } } return 0; }
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { SkStream* fontStream = ((FamilyTypeface*)face)->openStream(); // store the length of the custom font uint32_t len = fontStream->getLength(); stream->write32(len); // store the entire font in the serialized stream void* fontData = malloc(len); fontStream->read(fontData, len); stream->write(fontData, len); fontStream->unref(); free(fontData); // sk_throw(); }
bool SkXMLParser::parse(SkStream& docStream) { ParsingContext ctx(this); if (!ctx.fXMLParser) { SkDebugf("could not create XML parser\n"); return false; } XML_SetUserData(ctx.fXMLParser, &ctx); XML_SetElementHandler(ctx.fXMLParser, start_element_handler, end_element_handler); XML_SetCharacterDataHandler(ctx.fXMLParser, text_handler); // Disable entity processing, to inhibit internal entity expansion. See expat CVE-2013-0340. XML_SetEntityDeclHandler(ctx.fXMLParser, entity_decl_handler); static const int kBufferSize = 512 SkDEBUGCODE( - 507); bool done = false; do { void* buffer = XML_GetBuffer(ctx.fXMLParser, kBufferSize); if (!buffer) { SkDebugf("could not buffer enough to continue\n"); return false; } size_t len = docStream.read(buffer, kBufferSize); done = docStream.isAtEnd(); XML_Status status = XML_ParseBuffer(ctx.fXMLParser, SkToS32(len), done); if (XML_STATUS_ERROR == status) { XML_Error error = XML_GetErrorCode(ctx.fXMLParser); int line = XML_GetCurrentLineNumber(ctx.fXMLParser); int column = XML_GetCurrentColumnNumber(ctx.fXMLParser); const XML_LChar* errorString = XML_ErrorString(error); SkDebugf("parse error @%d:%d: %d (%s).\n", line, column, error, errorString); return false; } } while (!done); return true; }
SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { SkStream* stream = this->getLocalStream(); if (stream) { // should have been provided by CreateFromStream() *ttcIndex = 0; SkAutoTUnref<SkStream> dupStream(stream->duplicate()); if (dupStream) { return dupStream.detach(); } // TODO: update interface use, remove the following code in this block. size_t length = stream->getLength(); const void* memory = stream->getMemoryBase(); if (NULL != memory) { return new SkMemoryStream(memory, length, true); } SkAutoTMalloc<uint8_t> allocMemory(length); stream->rewind(); if (length == stream->read(allocMemory.get(), length)) { SkAutoTUnref<SkMemoryStream> copyStream(new SkMemoryStream()); copyStream->setMemoryOwned(allocMemory.detach(), length); return copyStream.detach(); } stream->rewind(); stream->ref(); } else { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (NULL == fci.get()) { return NULL; } stream = fci->openStream(this->getIdentity()); *ttcIndex = this->getIdentity().fTTCIndex; } return stream; }
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { // lookup and record if the font is custom (i.e. not a system font) bool isCustomFont = !((FamilyTypeface*)face)->isSysFont(); stream->writeBool(isCustomFont); if (isCustomFont) { SkStream* fontStream = ((FamilyTypeface*)face)->openStream(); // store the length of the custom font uint32_t len = fontStream->getLength(); stream->write32(len); // store the entire font in the serialized stream void* fontData = malloc(len); fontStream->read(fontData, len); stream->write(fontData, len); fontStream->unref(); free(fontData); // SkDebugf("--- fonthost custom serialize %d %d\n", face->style(), len); } else { const char* name = ((FamilyTypeface*)face)->getFilePath(); // const char* name = ((FamilyTypeface*)face)->getUniqueString(); stream->write8((uint8_t)face->style()); if (NULL == name || 0 == *name) { stream->writePackedUInt(0); // SkDebugf("--- fonthost serialize null\n"); } else { uint32_t len = strlen(name); stream->writePackedUInt(len); stream->write(name, len); // SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style()); } } }
LoadState SkFontManager::checkPreData() { LoadState state = load_true; SkStream * inStream = openReadStream( SYSTEM_DL_PREDATA_FILE ); preDataHeader header = { 0, 0, 0 }; if( !inStream ) { state = load_false; goto END0; } inStream->read( &header, SYSTEM_DL_PREDATA_HEADER_LEN ); if( header.tag != __key() ) { state = load_false; goto END0; } if( getUpdateVersion() == header.updateVersion ) { state = load_true; goto END0; } else { state = load_change; goto END0; } END0: if( inStream ) SkDELETE( inStream ); return state; }
static int Decode(GifFileType* fileType, GifByteType* out, int size) { SkStream* stream = (SkStream*) fileType->UserData; return (int) stream->read(out, size); }
/* * Read function that will be passed to gif_lib */ static int32_t read_bytes_callback(GifFileType* fileType, GifByteType* out, int32_t size) { SkStream* stream = (SkStream*) fileType->UserData; return (int32_t) stream->read(out, size); }
LoadState SkFontManager::loadPreData( uint32_t * newFontIndex, bool boot ) { LoadState state = load_true; preDataHeader header = { 0, 0, 0 }; uint32_t curFontIndex = ( boot == true ? readFontConfig() : getCurrentFontIndex() ); uint32_t curNewFontIndex = curFontIndex; uint32_t numEmbeddedFonts = mEmbeddedFonts.numFonts(); bool statePass = ( curFontIndex < numEmbeddedFonts ? true : false ); bool system = ( newFontIndex != NULL ? true : false ); SkStream * stream = NULL; if( openPreDataRead( &stream ) == false ) { if( no_such_file() || permission_denied() ) goto SKIP_ERROR0; HyLogef( "openPreDataRead(%s (%d))", strerror( errno ), errno ); goto ERROR0; } stream->read( &header, SYSTEM_DL_PREDATA_HEADER_LEN ); if( header.tag != __key() ) { HyLogef( "Wrong tag" ); goto ERROR0; } LOAD_START: if( getUpdateVersion() == 0 ) // Boot Load & reload. { setUpdateVersion( header.updateVersion ); if( header.count == 0 ) goto SUCCEED0; for( uint32_t n = 0 ; n < header.count ; n++ ) { SkFontData * font = SkNEW( SkFontData ); if( font ) { font->readPreData( stream ); if( font->checkCertify( system ) == true ) { font->loadFont(); mDownloadFonts.addFonts( font ); } else { if( ( system == true ) && ( statePass == false ) ) { if( state != load_restart ) { if( ( numEmbeddedFonts + n ) == curFontIndex ) { state = load_restart; } else { state = load_change; if( ( numEmbeddedFonts + n ) < curFontIndex ) curNewFontIndex--; } } } else { state = load_change; } font->deleteFiles(); SkDELETE( font ); font = NULL; } } else { HyLogef( "SkNEW( SkFontData )" ); continue; } } } else // Fonts change { if( getUpdateVersion() == header.updateVersion ) { goto SUCCEED0; } else { mDownloadFonts.resetFonts(); setUpdateVersion( 0 ); goto LOAD_START; } } SUCCEED0: if( ( system == true ) && ( statePass == false ) ) { switch( state ) { case load_change: *newFontIndex = curNewFontIndex; break; case load_restart: *newFontIndex = SYSTEM_DEFAULT_FAMILY_INDEX; break; default: *newFontIndex = curFontIndex; break; } } else if( ( system == true ) && ( statePass == true ) ) { *newFontIndex = curFontIndex; } if( stream ) SkDELETE( stream ); return state; SKIP_ERROR0: return load_false; ERROR0: if( stream ) SkDELETE( stream ); return load_false; }
bool SkFontManager::savePreData() { SkStream * inStream = openReadStream( SYSTEM_DL_PREDATA_FILE ); SkFILEWStream * outStream = NULL; preDataHeader header = { 1, __key(), 0 }; SkString permission; if( !inStream ) { setUpdateVersion( 2 ); header.updateVersion++; header.count = mDownloadFonts.numFonts(); goto SAVE0; } else { inStream->read( &header, SYSTEM_DL_PREDATA_HEADER_LEN ); if( header.tag != __key() ) { header.updateVersion = 1; header.tag = __key(); header.count = mDownloadFonts.numFonts(); goto SAVE1; } header.count = mDownloadFonts.numFonts(); header.updateVersion++; if( header.updateVersion >= 0xFFFFFFFE ) header.updateVersion = 2; } SAVE1: SkDELETE( inStream ); inStream = NULL; SAVE0: outStream = openWriteStream( SYSTEM_DL_PREDATA_FILE ); if( !outStream ) { if( permission_denied() ) goto SKIP_ERROR0; HyLogef( "outStream is null" ); goto ERROR0; } outStream->write( &header, SYSTEM_DL_PREDATA_HEADER_LEN ); for( uint32_t n = 0 ; n < header.count ; n++ ) { SkFontData * font = mDownloadFonts.getFont( n ); font->writePreData( outStream ); } SkDELETE( outStream ); outStream = NULL; //setUpdateVersion( header.updateVersion ); permission.set( SYSTEM_FONT_PERMISSION_SET ); permission.append( SYSTEM_DL_PREDATA_FILE ); system( permission.c_str() ); HyLogi( "Font Configuration Data (%d), saved.", header.updateVersion ); return true; SKIP_ERROR0: return false; ERROR0: if( outStream ) SkDELETE( outStream ); return false; }