static void process_tomboy_xml_content (BijiLazyDeserializer *self) { BijiLazyDeserializerPrivate *priv = self->priv; int ret; gchar *revamped_html; g_string_append (priv->html, "<html xmlns=\"http://www.w3.org/1999/xhtml\"><body>"); priv->inner = xmlReaderForMemory (priv->content, strlen(priv->content), "", "UTF-8", 0); ret = xmlTextReaderRead (priv->inner); /* Make the GString grow as we read */ while (ret == 1) { process_tomboy_node (self); ret = xmlTextReaderRead (priv->inner); } g_string_append (priv->html, "</body></html>"); /* Now the inner content is known, we can * assign note values and let deserialization work on last elements*/ biji_note_obj_set_raw_text (priv->note, priv->raw_text->str); revamped_html = biji_str_replace (priv->html->str, "\n", "<br/>"); biji_note_obj_set_html (priv->note, revamped_html); g_free (revamped_html); }
char* getElementContent(MemoryStruct *xmlDoc, char *elementName) { xmlTextReaderPtr reader; int ret; xmlChar *name, *value; reader = xmlReaderForMemory(xmlDoc->data, xmlDoc->size, "http://www.example.org/", NULL, 0); if (reader != NULL) { ret = xmlTextReaderRead(reader); while (ret == 1) { name = xmlTextReaderName(reader); if (strcmp(elementName, (char*) name) == 0 && xmlTextReaderNodeType(reader) == 1) { //printf("Name: %s\tType: %d\t", name, xmlTextReaderNodeType(reader)); ret = xmlTextReaderRead(reader); if (ret == 1) { value = xmlTextReaderValue(reader); //printf("Value: %s\n", value); //xmlFree(value); xmlFree(name); xmlFreeTextReader(reader); return (char*) value; } } xmlFree(name); ret = xmlTextReaderRead(reader); } xmlFreeTextReader(reader); if (ret != 0) printf("Failed to parse.\n"); } else printf("Unable to read XML from memory.\n"); return; }
static void process_bijiben_html_content (BijiLazyDeserializer *self, xmlTextReaderPtr reader) { BijiLazyDeserializerPrivate *priv = self->priv; int ret; gchar *sane_html; sane_html = (gchar*) xmlTextReaderReadInnerXml (reader); priv->inner = xmlReaderForMemory (sane_html, strlen(sane_html), "", "UTF-8", 0); ret = xmlTextReaderRead (priv->inner); /* Make the GString grow as we read */ while (ret == 1) { process_bijiben_node (self); ret = xmlTextReaderRead (priv->inner); } biji_note_obj_set_raw_text (priv->note, priv->raw_text->str); biji_note_obj_set_html (priv->note, sane_html); xmlFree (BAD_CAST sane_html); }
static void process_bijiben_html_content (BijiLazyDeserializer *self) { BijiLazyDeserializerPrivate *priv = self->priv; int ret; gchar *sane_text, *sane_html; priv->inner = xmlReaderForMemory (priv->content, strlen(priv->content), "", "UTF-8", 0); ret = xmlTextReaderRead (priv->inner); /* Make the GString grow as we read */ while (ret == 1) { process_bijiben_node (self); ret = xmlTextReaderRead (priv->inner); } /* Now the inner content is known, we can * assign note values and let deserialization work on last elements*/ sane_html = biji_str_mass_replace (priv->html->str, "
" , "<br/>", "&" , "&" , NULL); sane_text = biji_str_mass_replace (priv->raw_text->str, "
", " ", "&", "&" , NULL); biji_note_obj_set_raw_text (priv->note, sane_text); biji_note_obj_set_html_content (priv->note, sane_html); g_free (sane_text); g_free (sane_html); }
EPUB3Error EPUB3ParseOPFFromData(EPUB3Ref epub, void * buffer, uint32_t bufferSize) { assert(epub != NULL); assert(buffer != NULL); assert(bufferSize > 0); EPUB3Error error = kEPUB3Success; xmlInitParser(); xmlTextReaderPtr reader = NULL; reader = xmlReaderForMemory(buffer, bufferSize, NULL, NULL, XML_PARSE_RECOVER | XML_PARSE_NONET); if(reader != NULL) { EPUB3XMLParseContext contextStack[PARSE_CONTEXT_STACK_DEPTH]; EPUB3XMLParseContextPtr currentContext = &contextStack[0]; int retVal = xmlTextReaderRead(reader); currentContext->state = kEPUB3OPFStateRoot; currentContext->tagName = xmlTextReaderConstName(reader); while(retVal == 1) { error = EPUB3ParseXMLReaderNodeForOPF(epub, reader, ¤tContext); retVal = xmlTextReaderRead(reader); } if(retVal < 0) { error = kEPUB3XMLParseError; } } else { error = kEPUB3XMLReadFromBufferError; } xmlFreeTextReader(reader); xmlCleanupParser(); return error; }
/* * call-seq: * from_memory(string, url = nil, encoding = nil, options = 0) * * Create a new reader that parses +string+ */ static VALUE from_memory(int argc, VALUE *argv, VALUE klass) { VALUE rb_buffer, rb_url, encoding, rb_options; const char * c_url = NULL; const char * c_encoding = NULL; int c_options = 0; rb_scan_args(argc, argv, "13", &rb_buffer, &rb_url, &encoding, &rb_options); if (!RTEST(rb_buffer)) rb_raise(rb_eArgError, "string cannot be nil"); if (RTEST(rb_url)) c_url = StringValuePtr(rb_url); if (RTEST(encoding)) c_encoding = StringValuePtr(encoding); if (RTEST(rb_options)) c_options = NUM2INT(rb_options); xmlTextReaderPtr reader = xmlReaderForMemory( StringValuePtr(rb_buffer), RSTRING_LEN(rb_buffer), c_url, c_encoding, c_options ); if(reader == NULL) { xmlFreeTextReader(reader); rb_raise(rb_eRuntimeError, "couldn't create a parser"); } VALUE rb_reader = Data_Wrap_Struct(klass, NULL, dealloc, reader); rb_funcall(rb_reader, rb_intern("initialize"), 3, rb_buffer, rb_url, encoding); return rb_reader; }
static bool create_xml_reader(write_data_t *write_data) { write_data->xml_reader = log_ralloc(write_data->r, xmlReaderForMemory(write_data->response_text->elts, write_data->response_text->nelts * write_data->response_text->elt_size, NULL, NULL, 0) ); if (write_data->xml_reader == NULL) { return false; } xmlTextReaderSetErrorHandler(write_data->xml_reader, xml_reader_error, write_data); return true; }
/** * Read the xml document in from a memory location. * @param xml The xml document * @param ptr The source xml input location * @param len The size of the memory buffer * @return @c TRUE if successful, @c FALSE if an error occurs. * @ingroup EXML_Read_Group */ int exml_mem_read(EXML *xml, void *s_mem, size_t len) { xmlTextReaderPtr reader; CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE); reader = xmlReaderForMemory( s_mem, len, "", NULL, XML_PARSE_RECOVER ); return _exml_read(xml, reader); }
EXPORT EPUB3Error EPUB3CopyRootFilePathFromContainer(EPUB3Ref epub, char ** rootPath) { assert(epub != NULL); if(epub->archive == NULL) return kEPUB3ArchiveUnavailableError; static const char *containerFilename = "META-INF/container.xml"; void *buffer = NULL; uint32_t bufferSize = 0; uint32_t bytesCopied; xmlTextReaderPtr reader = NULL; EPUB3Bool foundPath = kEPUB3_NO; EPUB3Error error = kEPUB3Success; error = EPUB3CopyFileIntoBuffer(epub, &buffer, &bufferSize, &bytesCopied, containerFilename); if(error == kEPUB3Success) { reader = xmlReaderForMemory(buffer, bufferSize, "", NULL, XML_PARSE_RECOVER); if(reader != NULL) { int retVal; while((retVal = xmlTextReaderRead(reader)) == 1) { const char *rootFileName = "rootfile"; const xmlChar *name = xmlTextReaderConstLocalName(reader); if(xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT && xmlStrcmp(name, BAD_CAST rootFileName) == 0) { xmlChar *fullPath = xmlTextReaderGetAttribute(reader, BAD_CAST "full-path"); if(fullPath != NULL) { // TODD: validate that the full-path attribute is of the form path-rootless // see http://idpf.org/epub/30/spec/epub30-ocf.html#sec-container-metainf-container.xml foundPath = kEPUB3_YES; *rootPath = strdup((char *)fullPath); } else { // The spec requires the full-path attribute error = kEPUB3XMLXDocumentInvalidError; } break; } } if(retVal < 0) { error = kEPUB3XMLParseError; } if(!foundPath) { error = kEPUB3XMLXElementNotFoundError; } } else { error = kEPUB3XMLReadFromBufferError; } EPUB3_FREE_AND_NULL(buffer); } xmlFreeTextReader(reader); return error; }
static xmlTextReaderPtr create_parser_buf(const char *buffer, int buflen, const char *filename) { xmlTextReaderPtr reader = NULL; if ((reader = xmlReaderForMemory(buffer, buflen, filename, NULL, 0))) { xmlTextReaderSetErrorHandler(reader, error_handler, NULL); if (xmlTextReaderRead(reader) != 1) { xmlFreeTextReader(reader); reader = NULL; } } else { tmx_err(E_UNKN, "xml parser: unable to open %s", filename); } return reader; }
/*DEF*/void *XoReadXmlMem(char *buf,int sz,char *roottype,int flags,int *err) { xmlTextReaderPtr reader = NULL; void *obj; *err = 0; reader = xmlReaderForMemory(buf,sz,"",NULL,0); if (reader == NULL) { char tmperr[256]; sprintf(tmperr,"XoReadXmlMem():cannot create reader memory\n"); XOERR(tmperr,0); } obj = XoReadXmlReader(reader,roottype,flags,err); xmlFreeTextReader(reader); return obj; }
/*DEF*/void *XoReadObixMem(char *buf,int sz,void *unused,int flags,int *err) { xmlTextReaderPtr reader = NULL; void *obj; flags = flags | XOML_PARSE_OBIX; *err = 0; reader = xmlReaderForMemory(buf,sz,"",NULL,0); if (reader == NULL) { char tmperr[256]; sprintf(tmperr,"XoReadObixMem():cannot create reader memory\n"); XOERR(tmperr,0); return NULL; } obj = XoReadXmlReader(reader,NULL,flags,err); xmlFreeTextReader(reader); return obj; }
gboolean xml_reader_load_from_data (XmlReader *reader, const gchar *data, gssize length, const gchar *uri, const gchar *encoding) { g_return_val_if_fail (XML_IS_READER (reader), FALSE); xml_reader_clear (reader); if (length == -1) length = strlen (data); reader->xml = xmlReaderForMemory (data, length, uri, encoding, 0); xmlTextReaderSetErrorHandler (reader->xml, xml_reader_error_cb, reader); return (reader->xml != NULL); }
static gboolean _ag_service_load_from_file (AgService *service) { xmlTextReaderPtr reader; gchar *filepath; gboolean ret; GError *error = NULL; gsize len; g_return_val_if_fail (service->name != NULL, FALSE); DEBUG_REFS ("Loading service %s", service->name); filepath = _ag_find_libaccounts_file (service->name, ".service", "AG_SERVICES", SERVICE_FILES_DIR); if (G_UNLIKELY (!filepath)) return FALSE; g_file_get_contents (filepath, &service->file_data, &len, &error); if (G_UNLIKELY (error)) { g_warning ("Error reading %s: %s", filepath, error->message); g_error_free (error); g_free (filepath); return FALSE; } /* TODO: cache the xmlReader */ reader = xmlReaderForMemory (service->file_data, len, filepath, NULL, 0); g_free (filepath); if (G_UNLIKELY (reader == NULL)) return FALSE; ret = read_service_file (reader, service); xmlFreeTextReader (reader); return ret; }
/* call-seq: * XML::Reader.string(io) -> XML::Reader * XML::Reader.string(io, :encoding => XML::Encoding::UTF_8, * :options => XML::Parser::Options::NOENT) -> XML::Parser * * Creates a new reader by parsing the specified string. * * You may provide an optional hash table to control how the * parsing is performed. Valid options are: * * base_uri - The base url for the parsed document. * encoding - The document encoding, defaults to nil. Valid values * are the encoding constants defined on XML::Encoding. * options - Controls the execution of the parser, defaults to 0. * Valid values are the constants defined on * XML::Parser::Options. Mutliple options can be combined * by using Bitwise OR (|). */ static VALUE rxml_reader_string(int argc, VALUE *argv, VALUE klass) { xmlTextReaderPtr xreader; VALUE string; VALUE options; char *xbaseurl = NULL; const char *xencoding = NULL; int xoptions = 0; rb_scan_args(argc, argv, "11", &string, &options); Check_Type(string, T_STRING); if (!NIL_P(options)) { VALUE baseurl = Qnil; VALUE encoding = Qnil; VALUE parserOptions = Qnil; Check_Type(options, T_HASH); baseurl = rb_hash_aref(options, base_uri_SYMBOL); xbaseurl = NIL_P(baseurl) ? NULL : StringValueCStr(baseurl); encoding = rb_hash_aref(options, ENCODING_SYMBOL); xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding)); parserOptions = rb_hash_aref(options, OPTIONS_SYMBOL); xoptions = NIL_P(parserOptions) ? 0 : NUM2INT(parserOptions); } xreader = xmlReaderForMemory(StringValueCStr(string), RSTRING_LEN(string), xbaseurl, xencoding, xoptions); if (xreader == NULL) rxml_raise(&xmlLastError); return rxml_reader_wrap(xreader); }
int xml_label_from_mem(const char *buf, int buf_size, struct ltfs_label *label) { int ret; xmlTextReaderPtr reader; CHECK_ARG_NULL(buf, -LTFS_NULL_ARG); CHECK_ARG_NULL(label, -LTFS_NULL_ARG); reader = xmlReaderForMemory(buf, buf_size, NULL, NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING); if (! reader) { ltfsmsg(LTFS_ERR, "17009E"); return -LTFS_LIBXML2_FAILURE; } ret = _xml_parse_label(reader, label); if (ret < 0) { ltfsmsg(LTFS_ERR, "17010E"); ret = -LTFS_LABEL_INVALID; } xmlFreeTextReader(reader); return ret; }
/** * dax_dom_document_new_from_memory: * * Creates a new #DaxDomDocument. FIXME * * Return value: the newly created #DaxDomDocument instance */ DaxDomDocument * dax_dom_document_new_from_memory (const gchar *buffer, gint size, const gchar *base_iri, GError **error) { DaxDomDocument *document; ParserContext ctx; ctx.reader = xmlReaderForMemory(buffer, size, base_iri, NULL, XML_PARSE_XINCLUDE); if (ctx.reader == NULL) return NULL; document = dax_document_new (); ctx.current_node = DAX_DOM_NODE (document); /* Set up the base uri */ dax_dom_document_set_base_iri (document, base_iri); dax_dom_document_parse_and_setup (document, &ctx); return document; }
XmlParser& XmlParser::xmlString(const std::string& xmlString) { xmlInitParser(); const char* cstr = xmlString.c_str(); _reader = xmlReaderForMemory(cstr, (int)strlen(cstr), NULL, NULL, 0); return *this; }
XmlReader::XmlReader(std::string&& xml) : buf(std::move(xml)), reader(xmlReaderForMemory(buf.c_str(), buf.size(), nullptr, nullptr, 0)) { }
XmlReader::XmlReader(const std::string& xml) : buf(xml), reader(xmlReaderForMemory(buf.c_str(), buf.size(), nullptr, nullptr, 0)) { }
static GError * download_contacts (EBookBackendWebdav *webdav, EFlag *running, EDataBookView *book_view, GCancellable *cancellable) { EBookBackendWebdavPrivate *priv = webdav->priv; EBookBackend *book_backend; SoupMessage *message; guint status; xmlTextReaderPtr reader; response_element_t *elements; response_element_t *element; response_element_t *next; gint count; gint i; gchar *new_ctag = NULL; g_mutex_lock (&priv->update_lock); if (!check_addressbook_changed (webdav, &new_ctag, cancellable)) { g_free (new_ctag); g_mutex_unlock (&priv->update_lock); return EDB_ERROR (SUCCESS); } book_backend = E_BOOK_BACKEND (webdav); if (book_view != NULL) { e_data_book_view_notify_progress (book_view, -1, _("Loading Addressbook summary...")); } message = send_propfind (webdav, cancellable); status = message->status_code; if (status == 401 || status == 407) { g_object_unref (message); g_free (new_ctag); if (book_view) e_data_book_view_notify_progress (book_view, -1, NULL); g_mutex_unlock (&priv->update_lock); return webdav_handle_auth_request (webdav); } if (status != 207) { GError *error; error = e_data_book_create_error_fmt ( E_DATA_BOOK_STATUS_OTHER_ERROR, _("PROPFIND on webdav failed with HTTP status %d (%s)"), status, message->reason_phrase && *message->reason_phrase ? message->reason_phrase : (soup_status_get_phrase (message->status_code) ? soup_status_get_phrase (message->status_code) : _("Unknown error"))); g_object_unref (message); g_free (new_ctag); if (book_view) e_data_book_view_notify_progress (book_view, -1, NULL); g_mutex_unlock (&priv->update_lock); return error; } if (message->response_body == NULL) { g_warning ("No response body in webdav PROPFIND result"); g_object_unref (message); g_free (new_ctag); if (book_view) e_data_book_view_notify_progress (book_view, -1, NULL); g_mutex_unlock (&priv->update_lock); return e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR, _("No response body in webdav PROPFIND result")); } /* parse response */ reader = xmlReaderForMemory ( message->response_body->data, message->response_body->length, NULL, NULL, XML_PARSE_NOWARNING); elements = parse_propfind_response (reader); /* count contacts */ count = 0; for (element = elements; element != NULL; element = element->next) { ++count; } /* download contacts */ i = 0; for (element = elements; element != NULL; element = element->next, ++i) { const gchar *uri; const gchar *etag; EContact *contact; gchar *complete_uri; /* stop downloading if search was aborted */ if (running != NULL && !e_flag_is_set (running)) break; if (book_view != NULL) { gfloat percent = 100.0 / count * i; gchar buf[100]; snprintf (buf, sizeof (buf), _("Loading Contacts (%d%%)"), (gint) percent); e_data_book_view_notify_progress (book_view, -1, buf); } /* skip collections */ uri = (const gchar *) element->href; if (uri[strlen (uri) - 1] == '/') continue; /* uri might be relative, construct complete one */ if (uri[0] == '/') { SoupURI *soup_uri = soup_uri_new (priv->uri); soup_uri->path = g_strdup (uri); complete_uri = soup_uri_to_string (soup_uri, 0); soup_uri_free (soup_uri); } else { complete_uri = g_strdup (uri); } etag = (const gchar *) element->etag; g_mutex_lock (&priv->cache_lock); contact = e_book_backend_cache_get_contact (priv->cache, complete_uri); g_mutex_unlock (&priv->cache_lock); /* download contact if it is not cached or its ETag changed */ if (contact == NULL || etag == NULL || strcmp (e_contact_get_const (contact, E_CONTACT_REV), etag) != 0) { contact = download_contact (webdav, complete_uri, cancellable); if (contact != NULL) { g_mutex_lock (&priv->cache_lock); if (e_book_backend_cache_remove_contact (priv->cache, complete_uri)) e_book_backend_notify_remove (book_backend, complete_uri); e_book_backend_cache_add_contact (priv->cache, contact); g_mutex_unlock (&priv->cache_lock); e_book_backend_notify_update (book_backend, contact); } } g_free (complete_uri); } /* free element list */ for (element = elements; element != NULL; element = next) { next = element->next; xmlFree (element->href); xmlFree (element->etag); g_free (element); } xmlFreeTextReader (reader); g_object_unref (message); if (new_ctag) { g_mutex_lock (&priv->cache_lock); if (!e_file_cache_replace_object (E_FILE_CACHE (priv->cache), WEBDAV_CTAG_KEY, new_ctag)) e_file_cache_add_object (E_FILE_CACHE (priv->cache), WEBDAV_CTAG_KEY, new_ctag); g_mutex_unlock (&priv->cache_lock); } g_free (new_ctag); if (book_view) e_data_book_view_notify_progress (book_view, -1, NULL); g_mutex_unlock (&priv->update_lock); return EDB_ERROR (SUCCESS); }
int cli_scandmg(cli_ctx *ctx) { struct dmg_koly_block hdr; int ret, namelen, ofd; size_t maplen, nread; off_t pos = 0; char *dirname, *tmpfile; const char *outdata; unsigned int file = 0; struct dmg_mish_with_stripes *mish_list = NULL, *mish_list_tail = NULL; enum dmgReadState state = DMG_FIND_BASE_PLIST; int stateDepth[DMG_MAX_STATE]; #if HAVE_LIBXML2 xmlTextReaderPtr reader; #endif if (!ctx || !ctx->fmap) { cli_errmsg("cli_scandmg: Invalid context\n"); return CL_ENULLARG; } maplen = (*ctx->fmap)->real_len; pos = maplen - 512; if (pos <= 0) { cli_dbgmsg("cli_scandmg: Sizing problem for DMG archive.\n"); return CL_CLEAN; } /* Grab koly block */ if (fmap_readn(*ctx->fmap, &hdr, pos, sizeof(hdr)) != sizeof(hdr)) { cli_dbgmsg("cli_scandmg: Invalid DMG trailer block\n"); return CL_EFORMAT; } /* Check magic */ hdr.magic = be32_to_host(hdr.magic); if (hdr.magic == 0x6b6f6c79) { cli_dbgmsg("cli_scandmg: Found koly block @ %ld\n", (long) pos); } else { cli_dbgmsg("cli_scandmg: No koly magic, %8x\n", hdr.magic); return CL_EFORMAT; } hdr.dataForkOffset = be64_to_host(hdr.dataForkOffset); hdr.dataForkLength = be64_to_host(hdr.dataForkLength); cli_dbgmsg("cli_scandmg: data offset %lu len %d\n", (unsigned long)hdr.dataForkOffset, (int)hdr.dataForkLength); hdr.xmlOffset = be64_to_host(hdr.xmlOffset); hdr.xmlLength = be64_to_host(hdr.xmlLength); if (hdr.xmlLength > (uint64_t)INT_MAX) { cli_dbgmsg("cli_scandmg: The embedded XML is way larger than necessary, and probably corrupt or tampered with.\n"); return CL_EFORMAT; } if ((hdr.xmlOffset > (uint64_t)maplen) || (hdr.xmlLength > (uint64_t)maplen) || (hdr.xmlOffset + hdr.xmlLength) > (uint64_t)maplen) { cli_dbgmsg("cli_scandmg: XML out of range for this file\n"); return CL_EFORMAT; } cli_dbgmsg("cli_scandmg: XML offset %lu len %d\n", (unsigned long)hdr.xmlOffset, (int)hdr.xmlLength); if (hdr.xmlLength == 0) { cli_dbgmsg("cli_scandmg: Embedded XML length is zero.\n"); return CL_EFORMAT; } /* Create temp folder for contents */ if (!(dirname = cli_gentemp(ctx->engine->tmpdir))) { return CL_ETMPDIR; } if (mkdir(dirname, 0700)) { cli_errmsg("cli_scandmg: Cannot create temporary directory %s\n", dirname); free(dirname); return CL_ETMPDIR; } cli_dbgmsg("cli_scandmg: Extracting into %s\n", dirname); /* Dump XML to tempfile, if needed */ if (ctx->engine->keeptmp) { int xret; xret = dmg_extract_xml(ctx, dirname, &hdr); if (xret != CL_SUCCESS) { /* Printed err detail inside dmg_extract_xml */ free(dirname); return xret; } } /* scan XML with cli_map_scandesc */ ret = cli_map_scandesc(*ctx->fmap, (off_t)hdr.xmlOffset, (size_t)hdr.xmlLength, ctx); if (ret != CL_CLEAN) { cli_dbgmsg("cli_scandmg: retcode from scanning TOC xml: %s\n", cl_strerror(ret)); if (!ctx->engine->keeptmp) cli_rmdirs(dirname); free(dirname); return ret; } /* page data from map */ outdata = fmap_need_off_once_len(*ctx->fmap, hdr.xmlOffset, hdr.xmlLength, &nread); if (!outdata || (nread != hdr.xmlLength)) { cli_errmsg("cli_scandmg: Failed getting XML from map, len %d\n", (int)hdr.xmlLength); if (!ctx->engine->keeptmp) cli_rmdirs(dirname); free(dirname); return CL_EMAP; } /* time to walk the tree */ /* plist -> dict -> (key:resource_fork) dict -> (key:blkx) array -> dict */ /* each of those bottom level dict should have 4 parts */ /* [ Attributes, Data, ID, Name ], where Data is Base64 mish block */ /* This is the block where we require libxml2 */ #if HAVE_LIBXML2 /* XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_COMPACT */ #define DMG_XML_PARSE_OPTS (1 << 1 | 1 << 11 | 1 << 16) reader = xmlReaderForMemory(outdata, (int)hdr.xmlLength, "toc.xml", NULL, DMG_XML_PARSE_OPTS); if (!reader) { cli_dbgmsg("cli_scandmg: Failed parsing XML!\n"); if (!ctx->engine->keeptmp) cli_rmdirs(dirname); free(dirname); return CL_EFORMAT; } stateDepth[DMG_FIND_BASE_PLIST] = -1; // May need to check for (xmlTextReaderIsEmptyElement(reader) == 0) /* Break loop if have return code or reader can't read any more */ while ((ret == CL_CLEAN) && (xmlTextReaderRead(reader) == 1)) { xmlReaderTypes nodeType; nodeType = xmlTextReaderNodeType(reader); if (nodeType == XML_READER_TYPE_ELEMENT) { // New element, do name check xmlChar *nodeName; int depth; depth = xmlTextReaderDepth(reader); if (depth < 0) { break; } if ((depth > 50) && SCAN_ALGO) { // Possible heuristic, should limit runaway cli_dbgmsg("cli_scandmg: Excessive nesting in DMG TOC.\n"); break; } nodeName = xmlTextReaderLocalName(reader); if (!nodeName) continue; dmg_parsemsg("read: name %s depth %d\n", nodeName, depth); if ((state == DMG_FIND_DATA_MISH) && (depth == stateDepth[state-1])) { xmlChar * textValue; struct dmg_mish_with_stripes *mish_set; /* Reset state early, for continue cases */ stateDepth[DMG_FIND_KEY_DATA] = -1; state--; if (xmlStrcmp(nodeName, "data") != 0) { cli_dbgmsg("cli_scandmg: Not blkx data element\n"); xmlFree(nodeName); continue; } dmg_parsemsg("read: Found blkx data element\n"); /* Pull out data content from text */ if (xmlTextReaderIsEmptyElement(reader)) { cli_dbgmsg("cli_scandmg: blkx data element is empty\n"); xmlFree(nodeName); continue; } if (xmlTextReaderRead(reader) != 1) { xmlFree(nodeName); break; } if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_TEXT) { cli_dbgmsg("cli_scandmg: Next node not text\n"); xmlFree(nodeName); continue; } textValue = xmlTextReaderValue(reader); if (textValue == NULL) { xmlFree(nodeName); continue; } /* Have encoded mish block */ mish_set = cli_malloc(sizeof(struct dmg_mish_with_stripes)); if (mish_set == NULL) { ret = CL_EMEM; xmlFree(textValue); xmlFree(nodeName); break; } ret = dmg_decode_mish(ctx, &file, textValue, mish_set); xmlFree(textValue); if (ret == CL_EFORMAT) { /* Didn't decode, or not a mish block */ ret = CL_CLEAN; xmlFree(nodeName); continue; } else if (ret != CL_CLEAN) { xmlFree(nodeName); continue; } /* Add mish block to list */ if (mish_list_tail != NULL) { mish_list_tail->next = mish_set; mish_list_tail = mish_set; } else { mish_list = mish_set; mish_list_tail = mish_set; } mish_list_tail->next = NULL; } if ((state == DMG_FIND_KEY_DATA) && (depth > stateDepth[state-1]) && (xmlStrcmp(nodeName, "key") == 0)) { xmlChar * textValue; dmg_parsemsg("read: Found key - checking for Data\n"); if (xmlTextReaderRead(reader) != 1) { xmlFree(nodeName); break; } if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_TEXT) { cli_dbgmsg("cli_scandmg: Key node no text\n"); xmlFree(nodeName); continue; } textValue = xmlTextReaderValue(reader); if (textValue == NULL) { cli_dbgmsg("cli_scandmg: no value from xmlTextReaderValue\n"); xmlFree(nodeName); continue; } if (xmlStrcmp(textValue, "Data") == 0) { dmg_parsemsg("read: Matched data\n"); stateDepth[DMG_FIND_KEY_DATA] = depth; state++; } else { dmg_parsemsg("read: text value is %s\n", textValue); } xmlFree(textValue); } if ((state == DMG_FIND_BLKX_CONTAINER) && (depth == stateDepth[state-1])) { if (xmlStrcmp(nodeName, "array") == 0) { dmg_parsemsg("read: Found array blkx\n"); stateDepth[DMG_FIND_BLKX_CONTAINER] = depth; state++; } else if (xmlStrcmp(nodeName, "dict") == 0) { dmg_parsemsg("read: Found dict blkx\n"); stateDepth[DMG_FIND_BLKX_CONTAINER] = depth; state++; } else { cli_dbgmsg("cli_scandmg: Bad blkx, not container\n"); stateDepth[DMG_FIND_KEY_BLKX] = -1; state--; } } if ((state == DMG_FIND_KEY_BLKX) && (depth == stateDepth[state-1] + 1) && (xmlStrcmp(nodeName, "key") == 0)) { xmlChar * textValue; dmg_parsemsg("read: Found key - checking for blkx\n"); if (xmlTextReaderRead(reader) != 1) { xmlFree(nodeName); break; } if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_TEXT) { cli_dbgmsg("cli_scandmg: Key node no text\n"); xmlFree(nodeName); continue; } textValue = xmlTextReaderValue(reader); if (textValue == NULL) { cli_dbgmsg("cli_scandmg: no value from xmlTextReaderValue\n"); xmlFree(nodeName); continue; } if (xmlStrcmp(textValue, "blkx") == 0) { cli_dbgmsg("cli_scandmg: Matched blkx\n"); stateDepth[DMG_FIND_KEY_BLKX] = depth; state++; } else { cli_dbgmsg("cli_scandmg: wanted blkx, text value is %s\n", textValue); } xmlFree(textValue); } if ((state == DMG_FIND_DICT_RESOURCE_FORK) && (depth == stateDepth[state-1])) { if (xmlStrcmp(nodeName, "dict") == 0) { dmg_parsemsg("read: Found resource-fork dict\n"); stateDepth[DMG_FIND_DICT_RESOURCE_FORK] = depth; state++; } else { dmg_parsemsg("read: Not resource-fork dict\n"); stateDepth[DMG_FIND_KEY_RESOURCE_FORK] = -1; state--; } } if ((state == DMG_FIND_KEY_RESOURCE_FORK) && (depth == stateDepth[state-1] + 1) && (xmlStrcmp(nodeName, "key") == 0)) { dmg_parsemsg("read: Found resource-fork key\n"); stateDepth[DMG_FIND_KEY_RESOURCE_FORK] = depth; state++; } if ((state == DMG_FIND_BASE_DICT) && (depth == stateDepth[state-1] + 1) && (xmlStrcmp(nodeName, "dict") == 0)) { dmg_parsemsg("read: Found dict start\n"); stateDepth[DMG_FIND_BASE_DICT] = depth; state++; } if ((state == DMG_FIND_BASE_PLIST) && (xmlStrcmp(nodeName, "plist") == 0)) { dmg_parsemsg("read: Found plist start\n"); stateDepth[DMG_FIND_BASE_PLIST] = depth; state++; } xmlFree(nodeName); } else if ((nodeType == XML_READER_TYPE_END_ELEMENT) && (state > DMG_FIND_BASE_PLIST)) { int significantEnd = 0; int depth = xmlTextReaderDepth(reader); if (depth < 0) { break; } else if (depth < stateDepth[state-1]) { significantEnd = 1; } else if ((depth == stateDepth[state-1]) && (state-1 == DMG_FIND_BLKX_CONTAINER)) { /* Special case, ending blkx container */ significantEnd = 1; } if (significantEnd) { dmg_parsemsg("read: significant end tag, state %d\n", state); stateDepth[state-1] = -1; state--; if ((state-1 == DMG_FIND_KEY_RESOURCE_FORK) || (state-1 == DMG_FIND_KEY_BLKX)) { /* Keys end their own tag (validly) and the next state depends on the following tag */ // cli_dbgmsg("read: significant end tag ending prior key state\n"); stateDepth[state-1] = -1; state--; } } else { dmg_parsemsg("read: not significant end tag, state %d depth %d prior depth %d\n", state, depth, stateDepth[state-1]); } } } xmlFreeTextReader(reader); xmlCleanupParser(); #else cli_dbgmsg("cli_scandmg: libxml2 support is compiled out. It is required for full DMG support.\n"); #endif /* Loop over mish array */ file = 0; while ((ret == CL_CLEAN) && (mish_list != NULL)) { /* Handle & scan mish block */ ret = dmg_handle_mish(ctx, file++, dirname, hdr.xmlOffset, mish_list); free(mish_list->mish); mish_list_tail = mish_list; mish_list = mish_list->next; free(mish_list_tail); } /* Cleanup */ /* If error occurred, need to free mish items and mish blocks */ while (mish_list != NULL) { free(mish_list->mish); mish_list_tail = mish_list; mish_list = mish_list->next; free(mish_list_tail); } if (!ctx->engine->keeptmp) cli_rmdirs(dirname); free(dirname); return ret; }
int cli_scanxdp(cli_ctx *ctx) { #if HAVE_LIBXML2 xmlTextReaderPtr reader = NULL; fmap_t *map = *(ctx->fmap); const char *buf; const xmlChar *name, *value; char *decoded; size_t decodedlen; int rc = CL_SUCCESS; char *dumpname; size_t i; buf = (const char *)fmap_need_off_once(map, map->offset, map->len); if (!(buf)) return CL_EREAD; if (ctx->engine->keeptmp) { dumpname = dump_xdp(ctx, buf, map->len); if (dumpname) free(dumpname); } /* * Since a PDF file can contain embedded XDP documents, * it's possible that the filetyping code matched an embedded XDP document. * If that's the case, then xmlReaderForMemory will throw an error. For now, * silently ignore the error and return CL_SUCCESS so the filetyping code can * continue on. */ reader = xmlReaderForMemory(buf, (int)(map->len), "noname.xml", NULL, CLAMAV_MIN_XMLREADER_FLAGS); if (!(reader)) return CL_SUCCESS; while (xmlTextReaderRead(reader) == 1) { name = xmlTextReaderConstLocalName(reader); if (!(name)) continue; if (!strcmp((const char *)name, "chunk") && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { value = xmlTextReaderReadInnerXml(reader); if (value) { decoded = cl_base64_decode((char *)value, strlen((const char *)value), NULL, &decodedlen, 0); if (decoded) { unsigned int shouldscan=0; if (decodedlen > 5) { for (i=0; i < MIN(MAGIC_BUFFER_SIZE, decodedlen-5); i++) { if (decoded[i] != '%') continue; if (decoded[i+1] == 'P' || decoded[i+1] == 'p') { if (decoded[i+2] == 'D' || decoded[i+2] == 'd') { if (decoded[i+3] == 'F' || decoded[i+3] == 'f') { if (decoded[i+4] == '-') { shouldscan=1; break; } } } } } } if (!shouldscan) { free(decoded); xmlFree((void *)value); break; } rc = cli_mem_scandesc(decoded, decodedlen, ctx); free(decoded); if (rc != CL_SUCCESS || rc == CL_BREAK) { xmlFree((void *)value); break; } } xmlFree((void *)value); } } } xmlFreeTextReader(reader); return rc; #else return CL_SUCCESS; #endif }
/** Handles deserialization from both myanimelist and search results. * Search results are <anime><entry></entry><entry></entry></anime> * myanimelist results are <entry><anime></anime><anime></anime></entry> */ std::list<std::shared_ptr<Anime> > AnimeSerializer::deserialize(const std::string& xml) const { std::list<std::shared_ptr<Anime> > res; std::unique_ptr<char[]> cstr(new char[xml.size()]); std::memcpy(cstr.get(), xml.c_str(), xml.size()); std::unique_ptr<xmlTextReader, xmlTextReaderDeleter> reader(xmlReaderForMemory( cstr.get(), xml.size(), "", "UTF-8", XML_PARSE_RECOVER | XML_PARSE_NOENT )); if (!reader) { std::cerr << "Error: Couldn't create XML reader" << std::endl; std::cerr << "XML follows: " << xml << std::endl; return res; } Anime anime; int ret = 1; FIELDS field = FIELDNONE; FIELDS prev_field = FIELDNONE; bool entry_after_anime = false; bool seen_anime = false; bool seen_entry = false; for( ret = xmlTextReaderRead(reader.get()); ret == 1; ret = xmlTextReaderRead(reader.get()) ) { const std::string name = xmlchar_to_str(xmlTextReaderConstName (reader.get())); std::string value = xmlchar_to_str(xmlTextReaderConstValue(reader.get())); m_text_util->parse_html_entities(value); if (name.size() > 0) { auto field_iter = field_map.find(name); if (field_iter != field_map.end()) { prev_field = field; field = field_iter->second; } else { std::cerr << "Unexpected field " << name << std::endl; } switch (xmlTextReaderNodeType(reader.get())) { case XML_READER_TYPE_ELEMENT: entry_after_anime |= (field == ENTRY) && seen_anime && !seen_entry; seen_entry |= field == ENTRY; seen_anime |= field == ANIME; break; case XML_READER_TYPE_END_ELEMENT: if ( ( entry_after_anime && field == ENTRY) || (!entry_after_anime && field == ANIME)) { res.push_back(std::make_shared<Anime>(anime)); anime = Anime(); } field = FIELDNONE; break; case XML_READER_TYPE_TEXT: if( field != FIELDTEXT ) { std::cerr << "There's a problem!" << std::endl; } if (value.size() > 0) { auto member_iter = member_map.find(prev_field); if ( member_iter != member_map.end() ) { member_iter->second(anime, std::move(value)); } } else { std::cerr << "Error: Unexpected " << name << " = " << value << std::endl; } break; case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: break; default: std::cerr << "Warning: Unexpected node type " << xmlTextReaderNodeType(reader.get()) << " : " << name << "=" << value << std::endl; break; } } } if ( ret != 0 ) { std::cerr << "Error: Failed to parse! ret = " << ret << std::endl; std::cerr << "The xml is:\n" << xml << std::endl; } return res; }
BusConfigParser* bus_config_load (const DBusString *file, dbus_bool_t is_toplevel, const BusConfigParser *parent, DBusError *error) { xmlTextReader *reader; BusConfigParser *parser; DBusString dirname, data; DBusError tmp_error; int ret; _DBUS_ASSERT_ERROR_IS_CLEAR (error); parser = NULL; reader = NULL; if (!_dbus_string_init (&dirname)) { _DBUS_SET_OOM (error); return NULL; } if (!_dbus_string_init (&data)) { _DBUS_SET_OOM (error); _dbus_string_free (&dirname); return NULL; } if (is_toplevel) { /* xmlMemSetup only fails if one of the functions is NULL */ /* xmlMemSetup (dbus_free, dbus_malloc, dbus_realloc, _dbus_strdup); */ xmlInitParser (); xmlSetGenericErrorFunc (NULL, xml_shut_up); } if (!_dbus_string_get_dirname (file, &dirname)) { _DBUS_SET_OOM (error); goto failed; } parser = bus_config_parser_new (&dirname, is_toplevel, parent); if (parser == NULL) { _DBUS_SET_OOM (error); goto failed; } if (!_dbus_file_get_contents (&data, file, error)) goto failed; reader = xmlReaderForMemory (_dbus_string_get_const_data (&data), _dbus_string_get_length (&data), NULL, NULL, 0); if (reader == NULL) { _DBUS_SET_OOM (error); goto failed; } xmlTextReaderSetParserProp (reader, XML_PARSER_SUBST_ENTITIES, 1); dbus_error_init (&tmp_error); xmlTextReaderSetStructuredErrorHandler (reader, xml_text_reader_error, &tmp_error); while ((ret = xmlTextReaderRead (reader)) == 1) { int type; if (dbus_error_is_set (&tmp_error)) goto reader_out; type = xmlTextReaderNodeType (reader); if (type == -1) { _DBUS_MAYBE_SET_OOM (&tmp_error); goto reader_out; } switch ((xmlReaderTypes) type) { case XML_READER_TYPE_ELEMENT: xml_text_start_element (parser, reader, &tmp_error); break; case XML_READER_TYPE_TEXT: case XML_READER_TYPE_CDATA: { DBusString content; const char *value; #ifdef __SYMBIAN32__ value = (const char *) xmlTextReaderConstValue (reader); #else value = xmlTextReaderConstValue (reader); #endif if (value != NULL) { _dbus_string_init_const (&content, value); bus_config_parser_content (parser, &content, &tmp_error); } else _DBUS_MAYBE_SET_OOM (&tmp_error); break; } case XML_READER_TYPE_DOCUMENT_TYPE: { const char *name; #ifdef __SYMBIAN32__ name = (const char *) xmlTextReaderConstName (reader); #else name = xmlTextReaderConstName (reader); #endif if (name != NULL) bus_config_parser_check_doctype (parser, name, &tmp_error); else _DBUS_MAYBE_SET_OOM (&tmp_error); break; } case XML_READER_TYPE_END_ELEMENT: { const char *name; #ifdef __SYMBIAN32__ name = (const char *) xmlTextReaderConstName (reader); #else name = xmlTextReaderConstName (reader); #endif if (name != NULL) bus_config_parser_end_element (parser, name, &tmp_error); else _DBUS_MAYBE_SET_OOM (&tmp_error); break; } case XML_READER_TYPE_DOCUMENT: case XML_READER_TYPE_DOCUMENT_FRAGMENT: case XML_READER_TYPE_PROCESSING_INSTRUCTION: case XML_READER_TYPE_COMMENT: case XML_READER_TYPE_ENTITY: case XML_READER_TYPE_NOTATION: case XML_READER_TYPE_WHITESPACE: case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: case XML_READER_TYPE_END_ENTITY: case XML_READER_TYPE_XML_DECLARATION: /* nothing to do, just read on */ break; case XML_READER_TYPE_NONE: case XML_READER_TYPE_ATTRIBUTE: case XML_READER_TYPE_ENTITY_REFERENCE: _dbus_assert_not_reached ("unexpected nodes in XML"); } if (dbus_error_is_set (&tmp_error)) goto reader_out; } if (ret == -1) _DBUS_MAYBE_SET_OOM (&tmp_error); reader_out: xmlFreeTextReader (reader); reader = NULL; if (dbus_error_is_set (&tmp_error)) { dbus_move_error (&tmp_error, error); goto failed; } if (!bus_config_parser_finished (parser, error)) goto failed; _dbus_string_free (&dirname); _dbus_string_free (&data); if (is_toplevel) xmlCleanupParser(); _DBUS_ASSERT_ERROR_IS_CLEAR (error); return parser; failed: _DBUS_ASSERT_ERROR_IS_SET (error); _dbus_string_free (&dirname); _dbus_string_free (&data); if (is_toplevel) xmlCleanupParser(); if (parser) bus_config_parser_unref (parser); _dbus_assert (reader == NULL); /* must go to reader_out first */ return NULL; }
int cli_scanxar(cli_ctx *ctx) { int rc = CL_SUCCESS; unsigned int cksum_fails = 0; unsigned int extract_errors = 0; #if HAVE_LIBXML2 int fd = -1; struct xar_header hdr; fmap_t *map = *ctx->fmap; long length, offset, size, at; int encoding; z_stream strm; char *toc, *tmpname; xmlTextReaderPtr reader = NULL; int a_hash, e_hash; unsigned char *a_cksum = NULL, *e_cksum = NULL; memset(&strm, 0x00, sizeof(z_stream)); /* retrieve xar header */ if (fmap_readn(*ctx->fmap, &hdr, 0, sizeof(hdr)) != sizeof(hdr)) { cli_dbgmsg("cli_scanxar: Invalid header, too short.\n"); return CL_EFORMAT; } hdr.magic = be32_to_host(hdr.magic); if (hdr.magic == XAR_HEADER_MAGIC) { cli_dbgmsg("cli_scanxar: Matched magic\n"); } else { cli_dbgmsg("cli_scanxar: Invalid magic\n"); return CL_EFORMAT; } hdr.size = be16_to_host(hdr.size); hdr.version = be16_to_host(hdr.version); hdr.toc_length_compressed = be64_to_host(hdr.toc_length_compressed); hdr.toc_length_decompressed = be64_to_host(hdr.toc_length_decompressed); hdr.chksum_alg = be32_to_host(hdr.chksum_alg); /* cli_dbgmsg("hdr.magic %x\n", hdr.magic); */ /* cli_dbgmsg("hdr.size %i\n", hdr.size); */ /* cli_dbgmsg("hdr.version %i\n", hdr.version); */ /* cli_dbgmsg("hdr.toc_length_compressed %lu\n", hdr.toc_length_compressed); */ /* cli_dbgmsg("hdr.toc_length_decompressed %lu\n", hdr.toc_length_decompressed); */ /* cli_dbgmsg("hdr.chksum_alg %i\n", hdr.chksum_alg); */ /* Uncompress TOC */ strm.next_in = (unsigned char *)fmap_need_off_once(*ctx->fmap, hdr.size, hdr.toc_length_compressed); if (strm.next_in == NULL) { cli_dbgmsg("cli_scanxar: fmap_need_off_once fails on TOC.\n"); return CL_EREAD; } strm.avail_in = hdr.toc_length_compressed; toc = cli_malloc(hdr.toc_length_decompressed+1); if (toc == NULL) { cli_dbgmsg("cli_scanxar: cli_malloc fails on TOC decompress buffer.\n"); return CL_EMEM; } toc[hdr.toc_length_decompressed] = '\0'; strm.avail_out = hdr.toc_length_decompressed; strm.next_out = (unsigned char *)toc; rc = inflateInit(&strm); if (rc != Z_OK) { cli_dbgmsg("cli_scanxar:inflateInit error %i \n", rc); rc = CL_EFORMAT; goto exit_toc; } rc = inflate(&strm, Z_SYNC_FLUSH); if (rc != Z_OK && rc != Z_STREAM_END) { cli_dbgmsg("cli_scanxar:inflate error %i \n", rc); rc = CL_EFORMAT; goto exit_toc; } rc = inflateEnd(&strm); if (rc != Z_OK) { cli_dbgmsg("cli_scanxar:inflateEnd error %i \n", rc); rc = CL_EFORMAT; goto exit_toc; } /* cli_dbgmsg("cli_scanxar: TOC xml:\n%s\n", toc); */ /* printf("cli_scanxar: TOC xml:\n%s\n", toc); */ /* cli_dbgmsg("cli_scanxar: TOC end:\n"); */ /* printf("cli_scanxar: TOC end:\n"); */ /* scan the xml */ cli_dbgmsg("cli_scanxar: scanning xar TOC xml in memory.\n"); rc = cli_mem_scandesc(toc, hdr.toc_length_decompressed, ctx); if (rc != CL_SUCCESS) { if (rc != CL_VIRUS || !SCAN_ALL) goto exit_toc; } /* make a file to leave if --leave-temps in effect */ if(ctx->engine->keeptmp) { if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) { cli_dbgmsg("cli_scanxar: Can't create temporary file for TOC.\n"); goto exit_toc; } if (cli_writen(fd, toc, hdr.toc_length_decompressed) < 0) { cli_dbgmsg("cli_scanxar: cli_writen error writing TOC.\n"); rc = CL_EWRITE; xar_cleanup_temp_file(ctx, fd, tmpname); goto exit_toc; } rc = xar_cleanup_temp_file(ctx, fd, tmpname); if (rc != CL_SUCCESS) goto exit_toc; } reader = xmlReaderForMemory(toc, hdr.toc_length_decompressed, "noname.xml", NULL, 0); if (reader == NULL) { cli_dbgmsg("cli_scanxar: xmlReaderForMemory error for TOC\n"); goto exit_toc; } rc = xar_scan_subdocuments(reader, ctx); if (rc != CL_SUCCESS) { cli_dbgmsg("xar_scan_subdocuments returns %i.\n", rc); goto exit_reader; } /* Walk the TOC XML and extract files */ fd = -1; tmpname = NULL; while (CL_SUCCESS == (rc = xar_get_toc_data_values(reader, &length, &offset, &size, &encoding, &a_cksum, &a_hash, &e_cksum, &e_hash))) { int do_extract_cksum = 1; unsigned char * blockp; void *a_sc, *e_sc; void *a_mc, *e_mc; void *a_hash_ctx, *e_hash_ctx; char result[SHA1_HASH_SIZE]; char * expected; /* clean up temp file from previous loop iteration */ if (fd > -1 && tmpname) { rc = xar_cleanup_temp_file(ctx, fd, tmpname); if (rc != CL_SUCCESS) goto exit_reader; } at = offset + hdr.toc_length_compressed + hdr.size; if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) { cli_dbgmsg("cli_scanxar: Can't generate temporary file.\n"); goto exit_reader; } cli_dbgmsg("cli_scanxar: decompress into temp file:\n%s, size %li,\n" "from xar heap offset %li length %li\n", tmpname, size, offset, length); a_hash_ctx = xar_hash_init(a_hash, &a_sc, &a_mc); e_hash_ctx = xar_hash_init(e_hash, &e_sc, &e_mc); switch (encoding) { case CL_TYPE_GZ: /* inflate gzip directly because file segments do not contain magic */ memset(&strm, 0, sizeof(strm)); if ((rc = inflateInit(&strm)) != Z_OK) { cli_dbgmsg("cli_scanxar: InflateInit failed: %d\n", rc); rc = CL_EFORMAT; extract_errors++; break; } while ((size_t)at < map->len && (unsigned long)at < offset+hdr.toc_length_compressed+hdr.size+length) { unsigned long avail_in; void * next_in; unsigned int bytes = MIN(map->len - at, map->pgsz); bytes = MIN(length, bytes); if(!(strm.next_in = next_in = (void*)fmap_need_off_once(map, at, bytes))) { cli_dbgmsg("cli_scanxar: Can't read %u bytes @ %lu.\n", bytes, (long unsigned)at); inflateEnd(&strm); rc = CL_EREAD; goto exit_tmpfile; } at += bytes; strm.avail_in = avail_in = bytes; do { int inf, outsize = 0; unsigned char buff[FILEBUFF]; strm.avail_out = sizeof(buff); strm.next_out = buff; inf = inflate(&strm, Z_SYNC_FLUSH); if (inf != Z_OK && inf != Z_STREAM_END && inf != Z_BUF_ERROR) { cli_dbgmsg("cli_scanxar: inflate error %i %s.\n", inf, strm.msg?strm.msg:""); rc = CL_EFORMAT; extract_errors++; break; } bytes = sizeof(buff) - strm.avail_out; xar_hash_update(e_hash_ctx, buff, bytes, e_hash); if (cli_writen(fd, buff, bytes) < 0) { cli_dbgmsg("cli_scanxar: cli_writen error file %s.\n", tmpname); inflateEnd(&strm); rc = CL_EWRITE; goto exit_tmpfile; } outsize += sizeof(buff) - strm.avail_out; if (cli_checklimits("cli_scanxar", ctx, outsize, 0, 0) != CL_CLEAN) { break; } if (inf == Z_STREAM_END) { break; } } while (strm.avail_out == 0); if (rc != CL_SUCCESS) break; avail_in -= strm.avail_in; xar_hash_update(a_hash_ctx, next_in, avail_in, a_hash); } inflateEnd(&strm); break; case CL_TYPE_7Z: #define CLI_LZMA_OBUF_SIZE 1024*1024 #define CLI_LZMA_HDR_SIZE LZMA_PROPS_SIZE+8 #define CLI_LZMA_IBUF_SIZE CLI_LZMA_OBUF_SIZE>>2 /* estimated compression ratio 25% */ { struct CLI_LZMA lz; unsigned long in_remaining = length; unsigned long out_size = 0; unsigned char * buff = __lzma_wrap_alloc(NULL, CLI_LZMA_OBUF_SIZE); int lret; memset(&lz, 0, sizeof(lz)); if (buff == NULL) { cli_dbgmsg("cli_scanxar: memory request for lzma decompression buffer fails.\n"); rc = CL_EMEM; goto exit_tmpfile; } blockp = (void*)fmap_need_off_once(map, at, CLI_LZMA_HDR_SIZE); if (blockp == NULL) { char errbuff[128]; cli_strerror(errno, errbuff, sizeof(errbuff)); cli_dbgmsg("cli_scanxar: Can't read %li bytes @ %li, errno:%s.\n", length, at, errbuff); rc = CL_EREAD; __lzma_wrap_free(NULL, buff); goto exit_tmpfile; } lz.next_in = blockp; lz.avail_in = CLI_LZMA_HDR_SIZE; xar_hash_update(a_hash_ctx, blockp, CLI_LZMA_HDR_SIZE, a_hash); lret = cli_LzmaInit(&lz, 0); if (lret != LZMA_RESULT_OK) { cli_dbgmsg("cli_scanxar: cli_LzmaInit() fails: %i.\n", lret); rc = CL_EFORMAT; __lzma_wrap_free(NULL, buff); extract_errors++; break; } at += CLI_LZMA_HDR_SIZE; in_remaining -= CLI_LZMA_HDR_SIZE; while ((size_t)at < map->len && (unsigned long)at < offset+hdr.toc_length_compressed+hdr.size+length) { SizeT avail_in; SizeT avail_out; void * next_in; unsigned long in_consumed; lz.next_out = buff; lz.avail_out = CLI_LZMA_OBUF_SIZE; lz.avail_in = avail_in = MIN(CLI_LZMA_IBUF_SIZE, in_remaining); lz.next_in = next_in = (void*)fmap_need_off_once(map, at, lz.avail_in); if (lz.next_in == NULL) { char errbuff[128]; cli_strerror(errno, errbuff, sizeof(errbuff)); cli_dbgmsg("cli_scanxar: Can't read %li bytes @ %li, errno: %s.\n", length, at, errbuff); rc = CL_EREAD; __lzma_wrap_free(NULL, buff); cli_LzmaShutdown(&lz); goto exit_tmpfile; } lret = cli_LzmaDecode(&lz); if (lret != LZMA_RESULT_OK && lret != LZMA_STREAM_END) { cli_dbgmsg("cli_scanxar: cli_LzmaDecode() fails: %i.\n", lret); rc = CL_EFORMAT; extract_errors++; break; } in_consumed = avail_in - lz.avail_in; in_remaining -= in_consumed; at += in_consumed; avail_out = CLI_LZMA_OBUF_SIZE - lz.avail_out; if (avail_out == 0) cli_dbgmsg("cli_scanxar: cli_LzmaDecode() produces no output for " "avail_in %lu, avail_out %lu.\n", avail_in, avail_out); xar_hash_update(a_hash_ctx, next_in, in_consumed, a_hash); xar_hash_update(e_hash_ctx, buff, avail_out, e_hash); /* Write a decompressed block. */ /* cli_dbgmsg("Writing %li bytes to LZMA decompress temp file, " */ /* "consumed %li of %li available compressed bytes.\n", */ /* avail_out, in_consumed, avail_in); */ if (cli_writen(fd, buff, avail_out) < 0) { cli_dbgmsg("cli_scanxar: cli_writen error writing lzma temp file for %li bytes.\n", avail_out); __lzma_wrap_free(NULL, buff); cli_LzmaShutdown(&lz); rc = CL_EWRITE; goto exit_tmpfile; } /* Check file size limitation. */ out_size += avail_out; if (cli_checklimits("cli_scanxar", ctx, out_size, 0, 0) != CL_CLEAN) { break; } if (lret == LZMA_STREAM_END) break; } cli_LzmaShutdown(&lz); __lzma_wrap_free(NULL, buff); } break; case CL_TYPE_ANY: default: case CL_TYPE_BZ: case CL_TYPE_XZ: /* for uncompressed, bzip2, xz, and unknown, just pull the file, cli_magic_scandesc does the rest */ do_extract_cksum = 0; { unsigned long write_len; if (ctx->engine->maxfilesize) write_len = MIN((size_t)(ctx->engine->maxfilesize), (size_t)length); else write_len = length; if (!(blockp = (void*)fmap_need_off_once(map, at, length))) { char errbuff[128]; cli_strerror(errno, errbuff, sizeof(errbuff)); cli_dbgmsg("cli_scanxar: Can't read %li bytes @ %li, errno:%s.\n", length, at, errbuff); rc = CL_EREAD; goto exit_tmpfile; } xar_hash_update(a_hash_ctx, blockp, length, a_hash); if (cli_writen(fd, blockp, write_len) < 0) { cli_dbgmsg("cli_scanxar: cli_writen error %li bytes @ %li.\n", length, at); rc = CL_EWRITE; goto exit_tmpfile; } /*break;*/ } } if (rc == CL_SUCCESS) { xar_hash_final(a_hash_ctx, result, a_hash); if (a_cksum != NULL) { expected = cli_hex2str((char *)a_cksum); if (xar_hash_check(a_hash, result, expected) != 0) { cli_dbgmsg("cli_scanxar: archived-checksum missing or mismatch.\n"); cksum_fails++; } else { cli_dbgmsg("cli_scanxar: archived-checksum matched.\n"); } free(expected); } if (e_cksum != NULL) { if (do_extract_cksum) { xar_hash_final(e_hash_ctx, result, e_hash); expected = cli_hex2str((char *)e_cksum); if (xar_hash_check(e_hash, result, expected) != 0) { cli_dbgmsg("cli_scanxar: extracted-checksum missing or mismatch.\n"); cksum_fails++; } else { cli_dbgmsg("cli_scanxar: extracted-checksum matched.\n"); } free(expected); } } rc = cli_magic_scandesc(fd, ctx); if (rc != CL_SUCCESS) { if (rc == CL_VIRUS) { cli_dbgmsg("cli_scanxar: Infected with %s\n", cli_get_last_virus(ctx)); if (!SCAN_ALL) goto exit_tmpfile; } else if (rc != CL_BREAK) { cli_dbgmsg("cli_scanxar: cli_magic_scandesc error %i\n", rc); goto exit_tmpfile; } } } if (a_cksum != NULL) { xmlFree(a_cksum); a_cksum = NULL; } if (e_cksum != NULL) { xmlFree(e_cksum); e_cksum = NULL; } } exit_tmpfile: xar_cleanup_temp_file(ctx, fd, tmpname); exit_reader: if (a_cksum != NULL) xmlFree(a_cksum); if (e_cksum != NULL) xmlFree(e_cksum); xmlTextReaderClose(reader); xmlFreeTextReader(reader); exit_toc: free(toc); if (rc == CL_BREAK) rc = CL_SUCCESS; #else cli_dbgmsg("cli_scanxar: can't scan xar files, need libxml2.\n"); #endif if (cksum_fails + extract_errors != 0) { cli_warnmsg("cli_scanxar: %u checksum errors and %u extraction errors, use --debug for more info.\n", cksum_fails, extract_errors); } return rc; }
CInterfaceDefinition *CInterfaceDefinitionLoader::load( const unsigned char &buffer, unsigned int buffer_size ) { assert( !m_interface_definition && !m_reader && m_element_path.empty() ); m_interface_definition = new CInterfaceDefinition; xmlInitParser(); m_reader = xmlReaderForMemory( (char *) &buffer, buffer_size, NULL, NULL, 0 ); if( !m_reader ) { INTEGRA_TRACE_ERROR << "unable to read file"; cleanup(); return NULL; } int depth = -1; bool handled_element_content = false; char *inner_xml = NULL; while( xmlTextReaderRead( m_reader ) ) { switch( xmlTextReaderNodeType( m_reader ) ) { case XML_READER_TYPE_TEXT: { char *element_value = ( char * ) xmlTextReaderValue( m_reader ); if( handle_element_value( element_value ) != CError::SUCCESS ) { xmlFree( element_value ); cleanup(); return NULL; } xmlFree( element_value ); handled_element_content = true; store_map_entries(); } break; case XML_READER_TYPE_ELEMENT: { const char *element_name = ( const char * ) xmlTextReaderConstName( m_reader ); int new_depth = xmlTextReaderDepth( m_reader ); while( depth >= new_depth ) { pop_element_name(); depth--; } if( depth < new_depth ) { push_element_name( element_name ); depth++; } assert( depth == new_depth ); if( handle_element() != CError::SUCCESS ) { cleanup(); return NULL; } if( xmlTextReaderHasAttributes( m_reader ) ) { if( handle_element_attributes() != CError::SUCCESS ) { cleanup(); return NULL; } } if( xmlTextReaderIsEmptyElement( m_reader ) ) { handle_element_value( "" ); handled_element_content = true; } else { handled_element_content = false; inner_xml = ( char * ) xmlTextReaderReadInnerXml( m_reader ); } } break; case XML_READER_TYPE_END_ELEMENT: if( !handled_element_content && inner_xml ) { handle_element_value( inner_xml ); } if( inner_xml ) { xmlFree( inner_xml ); inner_xml = NULL; } handled_element_content = true; break; default: break; } } CError CError = do_sanity_check(); if( CError != CError::SUCCESS ) { INTEGRA_TRACE_ERROR << "sanity check failed"; cleanup(); return NULL; } m_interface_definition->propagate_defaults(); INTEGRA_TRACE_VERBOSE << "Loaded ok: " << m_interface_definition->get_interface_info().get_name(); CInterfaceDefinition *loaded_interface = m_interface_definition; m_interface_definition = NULL; cleanup(); return loaded_interface; }