END_TEST

/* Regression test for SF bug #483514. */
START_TEST(test_dtd_default_handling)
{
    char *text =
        "<!DOCTYPE doc [\n"
        "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
        "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
        "<!ELEMENT doc EMPTY>\n"
        "<!ATTLIST doc a CDATA #IMPLIED>\n"
        "<?pi in dtd?>\n"
        "<!--comment in dtd-->\n"
        "]><doc/>";

    XML_SetDefaultHandler(parser, accumulate_characters);
    XML_SetDoctypeDeclHandler(parser,
                              dummy_start_doctype_handler,
                              dummy_end_doctype_handler);
    XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
    XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
    XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
    XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
    XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
    XML_SetCommentHandler(parser, dummy_comment_handler);
    run_character_check(text, "\n\n\n\n\n\n\n<doc/>");
}
void ParserEngine::init()
{
	if (_parser)
		XML_ParserFree(_parser);

	if (!_pBuffer)
		_pBuffer  = new char[PARSE_BUFFER_SIZE];

	if (dynamic_cast<NoNamespacePrefixesStrategy*>(_pNamespaceStrategy))
	{
		_parser = XML_ParserCreateNS(_encodingSpecified ? _encoding.c_str() : 0, '\t');
		if (_parser)
		{
			XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl);
		}
	}
	else if (dynamic_cast<NamespacePrefixesStrategy*>(_pNamespaceStrategy))
	{
		_parser = XML_ParserCreateNS(_encodingSpecified ? _encoding.c_str() : 0, '\t');
		if (_parser)
		{
			XML_SetReturnNSTriplet(_parser, 1);
			XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl);
		}
	}
	else
	{
		_parser = XML_ParserCreate(_encodingSpecified ? _encoding.c_str() : 0);
	}

	if (!_parser) throw XMLException("Cannot create Expat parser");

	XML_SetUserData(_parser, this);
	XML_SetElementHandler(_parser, handleStartElement, handleEndElement);
	XML_SetCharacterDataHandler(_parser, handleCharacterData);
	XML_SetProcessingInstructionHandler(_parser, handleProcessingInstruction);
	if (_expandInternalEntities)
		XML_SetDefaultHandlerExpand(_parser, handleDefault);
	else
		XML_SetDefaultHandler(_parser, handleDefault);
	XML_SetUnparsedEntityDeclHandler(_parser, handleUnparsedEntityDecl);
	XML_SetNotationDeclHandler(_parser, handleNotationDecl);
	XML_SetExternalEntityRefHandler(_parser, handleExternalEntityRef);
	XML_SetCommentHandler(_parser, handleComment);
	XML_SetCdataSectionHandler(_parser, handleStartCdataSection, handleEndCdataSection);
	XML_SetDoctypeDeclHandler(_parser, handleStartDoctypeDecl, handleEndDoctypeDecl);
	XML_SetEntityDeclHandler(_parser, handleEntityDecl);
	XML_SetSkippedEntityHandler(_parser, handleSkippedEntity);
	XML_SetParamEntityParsing(_parser, _externalParameterEntities ? XML_PARAM_ENTITY_PARSING_ALWAYS : XML_PARAM_ENTITY_PARSING_NEVER);
	XML_SetUnknownEncodingHandler(_parser, handleUnknownEncoding, this);
}
Exemple #3
0
void
OMXMLReaderExpat::reset()
{
    TRACE("OMXMLReaderExpat::reset");
    
    XML_ParserFree(_parser);
    
    if (_workBuffer != 0)
    {
        delete [] _workBuffer;
    }
    
    OMListIterator<OMXMLAttribute*> iter(_attributes, OMBefore);
    while (++iter)
    {
        delete iter.value();
    }
    _attributes.clear();
    
    OMUInt32 elementCount = _startNmspaceDecls.count();
    for (OMUInt32 i = 0; i < elementCount; i++)
    {
        delete _startNmspaceDecls.getAt(i);
    }
    _startNmspaceDecls.clear();
    _endNmspaceDecls.clear();
    
    
    clearEvents();

    _parser = XML_ParserCreateNS(0, NAMESPACE_SEPARATOR);
    XML_SetNotationDeclHandler(_parser, ::expat_NotationDeclHandler);
    XML_SetEntityDeclHandler(_parser, ::expat_EntityDeclHandler);
    XML_SetStartNamespaceDeclHandler(_parser, ::expat_StartNamespaceDeclHandler);
    XML_SetEndNamespaceDeclHandler(_parser, ::expat_EndNamespaceDeclHandler);
    XML_SetStartElementHandler(_parser, ::expat_StartElementHandler);
    XML_SetEndElementHandler(_parser, ::expat_EndElementHandler);
    XML_SetCharacterDataHandler(_parser, ::expat_CharacterDataHandler);
    XML_SetUserData(_parser, this);

    _workBuffer = new wchar_t[WORK_BUFFER_MIN_SIZE];
    _workBufferSize = WORK_BUFFER_MIN_SIZE;
    
    _readNextChunk = true;
    _status = true;
    _numInBuffer = 0;
    
    _xmlStream->setPosition(0);
}
Exemple #4
0
bool_t reset_handlers_parser(parser_t *parser) {
  if( parser ) {
    XML_SetStartElementHandler(parser->p, parser->callbacks.start_tag ?
			       xml_startelementhandler : NULL);
    XML_SetEndElementHandler(parser->p, parser->callbacks.end_tag ?
			     xml_endelementhandler : NULL);
    XML_SetCommentHandler(parser->p, parser->callbacks.comment ?
			  xml_commenthandler : NULL);
    XML_SetCharacterDataHandler(parser->p, parser->callbacks.chardata ?
				xml_characterdatahandler : NULL);
    XML_SetProcessingInstructionHandler(parser->p, parser->callbacks.pidata ?
					xml_processinginstructionhandler : NULL);
    XML_SetStartCdataSectionHandler(parser->p, parser->callbacks.start_cdata ?
				    xml_startcdatahandler : NULL);
    /* if start_cdata, always set endcdatahandler */
    XML_SetEndCdataSectionHandler(parser->p, parser->callbacks.start_cdata ?
				  xml_endcdatahandler : NULL);
    XML_SetDefaultHandler(parser->p, parser->callbacks.dfault ?
    			  xml_defaulthandler : NULL);


    XML_SetStartDoctypeDeclHandler(parser->p, parser->callbacks.start_doctypedecl ?
				   xml_startdoctypedeclhandler : NULL);
    /* if start_doctypedecl, always set enddoctypedeclhandler */
    XML_SetEndDoctypeDeclHandler(parser->p, parser->callbacks.start_doctypedecl ?
				 xml_enddoctypedeclhandler : NULL);
    XML_SetEntityDeclHandler(parser->p, parser->callbacks.entitydecl ?
			     xml_entitydeclhandler : NULL);

    /* what to do about entities: there can be internal and external
     * entities, which expat treats differently. We want all our
     * entities to stay unprocessed, otherwise we'll get well formedness
     * errors. When a handler is called, the raw string is passed to
     * the default handler (provided it exists). */
    XML_UseForeignDTD(parser->p, XML_TRUE);
    XML_SetParamEntityParsing(parser->p, XML_PARAM_ENTITY_PARSING_NEVER);
    XML_SetExternalEntityRefHandler(parser->p,
				    xml_externalentityrefhandler);
    XML_SetExternalEntityRefHandlerArg(parser->p, parser);
    XML_SetSkippedEntityHandler(parser->p, xml_skippedentityhandler);


    return TRUE;
  }
  return FALSE;
}
Exemple #5
0
nad_t nad_parse(const char *buf, int len) {
    struct build_data bd;
    XML_Parser p;

    if(len == 0)
        len = strlen(buf);

    p = XML_ParserCreateNS(NULL, '|');
    if(p == NULL)
        return NULL;
    bd.p = p;

    XML_SetReturnNSTriplet(p, 1);
    /* Prevent the "billion laughs" attack against expat by disabling
     * internal entity expansion.  With 2.x, forcibly stop the parser
     * if an entity is declared - this is safer and a more obvious
     * failure mode.  With older versions, simply prevent expenansion
     * of such entities. */
#ifdef HAVE_XML_STOPPARSER
    XML_SetEntityDeclHandler(p, (void *) _nad_parse_entity_declaration);
#else
    XML_SetDefaultHandler(p, NULL);
#endif

    bd.nad = nad_new();
    bd.depth = 0;

    XML_SetUserData(p, (void *) &bd);
    XML_SetElementHandler(p, _nad_parse_element_start, _nad_parse_element_end);
    XML_SetCharacterDataHandler(p, _nad_parse_cdata);
    XML_SetStartNamespaceDeclHandler(p, _nad_parse_namespace_start);

    if(!XML_Parse(p, buf, len, 1)) {
        XML_ParserFree(p);
        nad_free(bd.nad);
        return NULL;
    }

    XML_ParserFree(p);

    if(bd.depth != 0)
        return NULL;

    return bd.nad;
}
Exemple #6
0
APR_DECLARE(apr_xml_parser *) apr_xml_parser_create_ex(apr_pool_t *pool,
    void *start_func, void *end_func, void *cdata_func)
{
    apr_xml_parser *parser = apr_pcalloc(pool, sizeof(*parser));

    parser->impl = apr_xml_get_parser_impl();

    parser->p = pool;
    parser->doc = apr_pcalloc(pool, sizeof(*parser->doc));

    parser->doc->namespaces = apr_array_make(pool, 5, sizeof(const char *));

    /* ### is there a way to avoid hard-coding this? */
    apr_xml_insert_uri(parser->doc->namespaces, APR_KW_DAV);

    parser->xp = XML_ParserCreate(NULL);
    if (parser->xp == NULL) {
        (*apr_pool_abort_get(pool))(APR_ENOMEM);
        return NULL;
    }

    apr_pool_cleanup_register(pool, parser, cleanup_parser,
                              apr_pool_cleanup_null);

    XML_SetUserData(parser->xp, parser);
    XML_SetElementHandler(parser->xp, start_func, end_func);
    XML_SetCharacterDataHandler(parser->xp, cdata_func);

    /* Prevent the "billion laughs" attack against expat by disabling
     * internal entity expansion.  With 2.x, forcibly stop the parser
     * if an entity is declared - this is safer and a more obvious
     * failure mode.  With older versions, installing a noop
     * DefaultHandler means that internal entities will be expanded as
     * the empty string, which is also sufficient to prevent the
     * attack. */
#if XML_MAJOR_VERSION > 1
    XML_SetEntityDeclHandler(parser->xp, entity_declaration);
#else
    XML_SetDefaultHandler(parser->xp, default_handler);
#endif

    return parser;
}
Exemple #7
0
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;
}
Exemple #8
0
OMXMLReaderExpat::OMXMLReaderExpat(OMRawStorage* xmlStream)
: _appendData(false), _xmlStream(xmlStream), _parser(0)
{
    TRACE("OMXMLReaderExpat::OMXMLReaderExpat");

    clearEvents();

    _parser = XML_ParserCreateNS(0, NAMESPACE_SEPARATOR);
    XML_SetNotationDeclHandler(_parser, ::expat_NotationDeclHandler);
    XML_SetEntityDeclHandler(_parser, ::expat_EntityDeclHandler);
    XML_SetStartNamespaceDeclHandler(_parser, ::expat_StartNamespaceDeclHandler);
    XML_SetEndNamespaceDeclHandler(_parser, ::expat_EndNamespaceDeclHandler);
    XML_SetStartElementHandler(_parser, ::expat_StartElementHandler);
    XML_SetEndElementHandler(_parser, ::expat_EndElementHandler);
    XML_SetCharacterDataHandler(_parser, ::expat_CharacterDataHandler);
    XML_SetUserData(_parser, this);

    _workBuffer = new wchar_t[WORK_BUFFER_MIN_SIZE];
    _workBufferSize = WORK_BUFFER_MIN_SIZE;

    _readNextChunk = true;
    _status = true;
    _numInBuffer = 0;
}
void _Expat_XML_SetEntityDeclHandler(struct ExpatIFace * Self, XML_Parser parser, XML_EntityDeclHandler handler)
{
	XML_SetEntityDeclHandler(parser, handler);
}
Exemple #10
0
am_config_t *am_parse_config_xml(unsigned long instance_id, const char *xml, size_t xml_sz, char log_enable) {
    const char *thisfunc = "am_parse_config_xml():";
    am_config_t *r = NULL;
    char *begin, *stream = NULL;
    size_t data_sz;
    pcre *x = NULL;
    const char *error = NULL;
    int erroroffset;

    am_xml_parser_ctx_t xctx = {.depth = 0, .setting_value = 0,
        .conf = NULL, .rgx = NULL, .parser = NULL, .log_enable = log_enable};

    if (xml == NULL || xml_sz == 0) {
        am_log_error(instance_id, "%s memory allocation error", thisfunc);
        return NULL;
    }

    /*match [key]=value returned within <value>[key]=value_of_a_key</value> element*/
    x = pcre_compile("(?<=\\[)(.+?)(?=\\])\\]\\s*\\=\\s*(.+)", 0, &error, &erroroffset, NULL);
    if (x == NULL) {
        am_log_error(instance_id, "%s pcre error %s", thisfunc, error == NULL ? "" : error);
    }

    r = calloc(1, sizeof (am_config_t));
    if (r == NULL) {
        am_log_error(instance_id, "%s memory allocation error", thisfunc);
        pcre_free(x);
        return NULL;
    }
    r->instance_id = instance_id;

    begin = strstr(xml, "![CDATA[");
    if (begin != NULL) {
        char *end = strstr(begin + 8, "]]>");
        if (end != NULL) {
            stream = begin + 8;
            data_sz = end - (begin + 8);
        }
    } else {
        /*no CDATA*/
        stream = (char *) xml;
        data_sz = xml_sz;
    }

    if (stream != NULL && data_sz > 0) {
        XML_Parser parser = XML_ParserCreate("UTF-8");
        xctx.parser = &parser;
        xctx.conf = r;
        xctx.rgx = x;
        XML_SetUserData(parser, &xctx);
        XML_SetElementHandler(parser, start_element, end_element);
        XML_SetCharacterDataHandler(parser, character_data);
        XML_SetEntityDeclHandler(parser, entity_declaration);
        if (XML_Parse(parser, stream, (int) data_sz, XML_TRUE) == XML_STATUS_ERROR) {
            const char *message = XML_ErrorString(XML_GetErrorCode(parser));
            int line = XML_GetCurrentLineNumber(parser);
            int col = XML_GetCurrentColumnNumber(parser);
            am_log_error(instance_id, "%s xml parser error (%d:%d) %s", thisfunc,
                    line, col, message);
            am_config_free(&r);
            r = NULL;
        } else {
            r->ts = time(NULL);
        }
        XML_ParserFree(parser);
    }

    pcre_free(x);
    return r;
}
Exemple #11
0
void bmx_expat_XML_SetEntityDeclHandler(XML_Parser parser) {
	XML_SetEntityDeclHandler(parser, bmx_expat_EntityDeclHandler);
}