FAXPP_Error FaxppParserWrapper::parseInputSource(const InputSource &srcToUse, XPath2MemoryManager *m) { reset(); mm = m; // Create a BinInputStream BinInputStream *stream = srcToUse.makeStream(); if(stream == NULL) XQThrow2(XMLParseException, X("FaxppParserWrapper::parseInputSource"), X("Document not found")); inputStreams.push_back(stream); // Initialize the parse FAXPP_Error err = FAXPP_init_parse_callback(parser, binInputStreamReadCallback, stream); // Set the correct base URI if(err == NO_ERROR && srcToUse.getSystemId()) { FAXPP_Text base = { (void*)srcToUse.getSystemId(), (XMLString::stringLen(srcToUse.getSystemId()) + 1) * sizeof(XMLCh) }; err = FAXPP_set_base_uri(parser, &base); } // Force use of encoding set on InputSource (this is done by FunctionParseXML) if(err == NO_ERROR && srcToUse.getEncoding()) { FAXPP_DecodeFunction decode = FAXPP_string_to_decode(UTF8(srcToUse.getEncoding())); if(decode == 0) err = UNSUPPORTED_ENCODING; else FAXPP_set_decode(parser, decode); } #if 0 else if(stream->getContentType()) { } #endif return err; }
XQQuery *XQQuery::parseModule(const XMLCh *ns, const XMLCh *at, const LocationInfo *location) const { InputSource* srcToUse = 0; if(m_context->getDocumentCache()->getXMLEntityResolver()){ XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, at, ns, XMLUni::fgZeroLenString, m_context->getBaseURI()); srcToUse = m_context->getDocumentCache()->getXMLEntityResolver()->resolveEntity(&resourceIdentifier); } if(srcToUse==0) { try { XMLURL urlTmp(m_context->getBaseURI(), at); if (urlTmp.isRelative()) { throw MalformedURLException(__FILE__, __LINE__, XMLExcepts::URL_NoProtocolPresent); } srcToUse = new URLInputSource(urlTmp); } catch(const MalformedURLException&) { // It's not a URL, so let's assume it's a local file name. const XMLCh* baseUri=m_context->getBaseURI(); if(baseUri && baseUri[0]) { XMLCh* tmpBuf = XMLPlatformUtils::weavePaths(baseUri, at); srcToUse = new LocalFileInputSource(tmpBuf); XMLPlatformUtils::fgMemoryManager->deallocate(tmpBuf); } else { srcToUse = new LocalFileInputSource(at); } } } Janitor<InputSource> janIS(srcToUse); XQQuery *module = m_moduleCache->getByURI(srcToUse->getSystemId()); if(module) return module; AutoDelete<DynamicContext> ctxGuard(m_context->createModuleContext()); DynamicContext *moduleCtx = ctxGuard.get(); moduleCtx->setBaseURI(srcToUse->getSystemId()); moduleCtx->setXMLEntityResolver(m_context->getXMLEntityResolver()); AutoDelete<XQQuery> moduleGuard(new (XMLPlatformUtils::fgMemoryManager) XQQuery(ctxGuard.adopt(), true, m_moduleCache, XMLPlatformUtils::fgMemoryManager)); module = moduleGuard; module->setFile(srcToUse->getSystemId()); module->setModuleTargetNamespace(ns); // Put the unparsed module in the cache, to resolve loops correctly m_moduleCache->put(moduleGuard.adopt()); XQilla::parse(*srcToUse, moduleCtx, XQilla::NO_STATIC_RESOLUTION, XMLPlatformUtils::fgMemoryManager, module); return module; }
static FAXPP_Error staticEntityCallback(void *userData, FAXPP_Parser *parser, FAXPP_EntityType type, const FAXPP_Text *base_uri, const FAXPP_Text *systemid, const FAXPP_Text *publicid) { FaxppParserWrapper *fw = (FaxppParserWrapper*)userData; try { // Resolve the entity const XMLCh *system16 = nullTerm(*systemid, fw->mm); const XMLCh *public16 = nullTerm(*publicid, fw->mm); InputSource* srcToUse = 0; if(fw->entityResolver){ XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::ExternalEntity, system16, 0, public16, (XMLCh*)base_uri->ptr); srcToUse = fw->entityResolver->resolveEntity(&resourceIdentifier); } if(srcToUse == 0) { srcToUse = DocumentCacheImpl::resolveURI(system16, (XMLCh*)base_uri->ptr); } Janitor<InputSource> janIS(srcToUse); // Create a BinInputStream BinInputStream *stream = srcToUse->makeStream(); if(stream == NULL) return CANT_LOCATE_EXTERNAL_ENTITY; fw->inputStreams.push_back(stream); FAXPP_Error err = FAXPP_parse_external_entity_callback(parser, type, binInputStreamReadCallback, stream); // Set the correct base URI if(err == NO_ERROR) { FAXPP_Text base = { (void*)srcToUse->getSystemId(), (XMLString::stringLen(srcToUse->getSystemId()) + 1) * sizeof(XMLCh) }; err = FAXPP_set_base_uri(parser, &base); } // Force use of encoding set on InputSource (this is done by FunctionParseXML) if(err == NO_ERROR && srcToUse->getEncoding()) { FAXPP_DecodeFunction decode = FAXPP_string_to_decode(UTF8(srcToUse->getEncoding())); if(decode == 0) err = UNSUPPORTED_ENCODING; else FAXPP_set_decode(parser, decode); } return err; } catch(...) { return CANT_LOCATE_EXTERNAL_ENTITY; } }
// --------------------------------------------------------------------------- // XSAXMLScanner: XMLScanner virtual methods // --------------------------------------------------------------------------- // This method will reset the scanner data structures, and related plugged // in stuff, for a new scan session. We get the input source for the primary // XML entity, create the reader for it, and push it on the stack so that // upon successful return from here we are ready to go. void XSAXMLScanner::scanReset(const InputSource& src) { fGrammar = fSchemaGrammar; fGrammarType = Grammar::SchemaGrammarType; fRootGrammar = fSchemaGrammar; fValidator->setGrammar(fGrammar); // Reset validation fValidate = true; // And for all installed handlers, send reset events. This gives them // a chance to flush any cached data. if (fDocHandler) fDocHandler->resetDocument(); if (fEntityHandler) fEntityHandler->resetEntities(); if (fErrorReporter) fErrorReporter->resetErrors(); // Clear out the id reference list resetValidationContext(); // Reset the Root Element Name if (fRootElemName) { fMemoryManager->deallocate(fRootElemName);//delete [] fRootElemName; } fRootElemName = 0; // Reset the element stack, and give it the latest ids for the special // URIs it has to know about. fElemStack.reset ( fEmptyNamespaceId, fUnknownNamespaceId, fXMLNamespaceId, fXMLNSNamespaceId ); if (!fSchemaNamespaceId) fSchemaNamespaceId = fURIStringPool->addOrFind(SchemaSymbols::fgURI_XSI); // Reset some status flags fInException = false; fStandalone = false; fErrorCount = 0; fHasNoDTD = true; fSeeXsi = false; fDoNamespaces = true; fDoSchema = true; // Reset the validators fSchemaValidator->reset(); fSchemaValidator->setErrorReporter(fErrorReporter); fSchemaValidator->setExitOnFirstFatal(fExitOnFirstFatal); fSchemaValidator->setGrammarResolver(fGrammarResolver); // Handle the creation of the XML reader object for this input source. // This will provide us with transcoding and basic lexing services. XMLReader* newReader = fReaderMgr.createReader ( src , true , XMLReader::RefFrom_NonLiteral , XMLReader::Type_General , XMLReader::Source_External , fCalculateSrcOfs ); if (!newReader) { if (src.getIssueFatalErrorIfNotFound()) ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource, src.getSystemId(), fMemoryManager); else ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource_Warning, src.getSystemId(), fMemoryManager); } // Push this read onto the reader manager fReaderMgr.pushReader(newReader, 0); // and reset security-related things if necessary: if(fSecurityManager != 0) { fEntityExpansionLimit = fSecurityManager->getEntityExpansionLimit(); fEntityExpansionCount = 0; } fElemCount = 0; if (fUIntPoolRowTotal >= 32) { // 8 KB tied up with validating attributes... fAttDefRegistry->removeAll(); recreateUIntPool(); } else { // note that this will implicitly reset the values of the hashtables, // though their buckets will still be tied up resetUIntPool(); } fUndeclaredAttrRegistryNS->removeAll(); }
void XQQuery::importModule(const XMLCh* szUri, VectorOfStrings* locations, StaticContext* context, const LocationInfo *location) { for(ImportedModules::iterator modIt = m_importedModules.begin(); modIt != m_importedModules.end(); ++modIt) { if(XPath2Utils::equals((*modIt)->getModuleTargetNamespace(),szUri)) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("Module for namespace '")); buf.append(szUri); buf.append(X("' has already been imported [err:XQST0047]")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } } if(locations==NULL) locations=context->resolveModuleURI(szUri); if(locations==NULL || locations->empty()) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("Cannot locate module for namespace ")); buf.append(szUri); buf.append(X(" without the 'at <location>' keyword [err:XQST0059]")); XQThrow3(StaticErrorException,X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } bool bFound=false; for(VectorOfStrings::iterator it=locations->begin();it!=locations->end();++it) { InputSource* srcToUse = 0; if (context->getDocumentCache()->getXMLEntityResolver()){ XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, *it, szUri, XMLUni::fgZeroLenString, context->getBaseURI()); srcToUse = context->getDocumentCache()->getXMLEntityResolver()->resolveEntity(&resourceIdentifier); } if(srcToUse==0) { try { XMLURL urlTmp(context->getBaseURI(), *it); if (urlTmp.isRelative()) { throw MalformedURLException(__FILE__, __LINE__, XMLExcepts::URL_NoProtocolPresent); } srcToUse = new URLInputSource(urlTmp); } catch(const MalformedURLException&) { // It's not a URL, so let's assume it's a local file name. const XMLCh* baseUri=context->getBaseURI(); if(baseUri && baseUri[0]) { XMLCh* tmpBuf = XMLPlatformUtils::weavePaths(baseUri, *it); srcToUse = new LocalFileInputSource(tmpBuf); XMLPlatformUtils::fgMemoryManager->deallocate(tmpBuf); } else { srcToUse = new LocalFileInputSource(*it); } } } Janitor<InputSource> janIS(srcToUse); AutoDelete<DynamicContext> ctxGuard(context->createModuleContext()); DynamicContext *moduleCtx = ctxGuard.get(); moduleCtx->setBaseURI(srcToUse->getSystemId()); LoopDetector loopDetector(context->getXMLEntityResolver(), szUri, location); moduleCtx->setXMLEntityResolver(&loopDetector); AutoDelete<XQQuery> pParsedQuery(XQilla::parse(*srcToUse, ctxGuard.adopt(), XQilla::NO_OPTIMIZATION)); if(!pParsedQuery->getIsLibraryModule()) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("The module at ")); buf.append(srcToUse->getSystemId()); buf.append(X(" is not a module")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } if(!XERCES_CPP_NAMESPACE::XMLString::equals(szUri,pParsedQuery->getModuleTargetNamespace())) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("The module at ")); buf.append(srcToUse->getSystemId()); buf.append(X(" specifies a different namespace [err:XQST0059]")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } // now move the variable declarations and the function definitions into my context for(UserFunctions::iterator itFn = pParsedQuery->m_userDefFns.begin(); itFn != pParsedQuery->m_userDefFns.end(); ++itFn) { (*itFn)->setModuleDocumentCache(const_cast<DocumentCache*>(moduleCtx->getDocumentCache())); if((*itFn)->isTemplate()) { context->addTemplate(*itFn); } else if((*itFn)->getName()) { context->addCustomFunction(*itFn); } } for(GlobalVariables::iterator itVar = pParsedQuery->m_userDefVars.begin(); itVar != pParsedQuery->m_userDefVars.end(); ++itVar) { for(ImportedModules::const_iterator modIt = m_importedModules.begin(); modIt != m_importedModules.end(); ++modIt) { for(GlobalVariables::const_iterator varIt = (*modIt)->m_userDefVars.begin(); varIt != (*modIt)->m_userDefVars.end(); ++varIt) { if(XPath2Utils::equals((*varIt)->getVariableURI(), (*itVar)->getVariableURI()) && XPath2Utils::equals((*varIt)->getVariableLocalName(), (*itVar)->getVariableLocalName())) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("An imported variable {")); buf.append((*itVar)->getVariableURI()); buf.append(X("}")); buf.append((*itVar)->getVariableLocalName()); buf.append(X(" conflicts with an already defined global variable [err:XQST0049].")); XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), *varIt); } } } } moduleCtx->setXMLEntityResolver(context->getXMLEntityResolver()); m_importedModules.push_back(pParsedQuery.adopt()); bFound=true; } if(!bFound) { XMLBuffer buf(1023,context->getMemoryManager()); buf.set(X("Cannot locate the module for namespace \"")); buf.append(szUri); buf.append(X("\" [err:XQST0059]")); XQThrow3(StaticErrorException,X("XQQuery::ImportModule"), buf.getRawBuffer(), location); } }
void FaxppDocumentCacheImpl::parseDocument(InputSource &srcToUse, EventHandler *handler, DynamicContext *context) { XPath2MemoryManager *mm = context->getMemoryManager(); if(doPSVI_) { validator_.setNextEventHandler(handler); events_ = &validator_; } else { events_ = handler; } FAXPP_Error err = wrapper_.parseInputSource(srcToUse, mm); if(err == OUT_OF_MEMORY) XQThrow2(XMLParseException, X("FaxppDocumentCacheImpl::loadDocument"), X("Out of memory")); if(err == UNSUPPORTED_ENCODING) { XQThrow2(XMLParseException, X("FaxppDocumentCacheImpl::loadDocument"), X("Unsupported encoding")); } location_.setLocationInfo(srcToUse.getSystemId(), 0, 0); try { unsigned int i; FAXPP_Attribute *attr; while(true) { err = FAXPP_next_event(wrapper_.parser); if(err != NO_ERROR) { // TBD add line and column information - jpcs XMLBuffer buf; buf.append(X("Error parsing document: ")); buf.append(X(FAXPP_err_to_string(err))); XQThrow2(XMLParseException, X("FaxppDocumentCacheImpl::loadDocument"), buf.getRawBuffer()); } const FAXPP_Event *event = FAXPP_get_current_event(wrapper_.parser); LOCATION(event); switch(event->type) { case START_DOCUMENT_EVENT: { // TBD Get encoding from parser if not specified in document - jpcs events_->setLocationInfo(&location_); // Encode space chars in the document URI as %20 const XMLCh *uri = srcToUse.getSystemId(); XMLBuffer encode(XMLString::stringLen(uri) + 1); if(uri != 0) { for(const XMLCh *uptr = uri; *uptr; ++uptr) { if(*uptr != ' ') encode.append(*uptr); else { encode.append('%'); encode.append('2'); encode.append('0'); } } uri = encode.getRawBuffer(); } events_->startDocumentEvent(uri, nullTerm(event->encoding, mm)); break; } case END_DOCUMENT_EVENT: events_->endDocumentEvent(); return; case START_ELEMENT_EVENT: case SELF_CLOSING_ELEMENT_EVENT: events_->startElementEvent(nullTerm(event->prefix, mm), nullTerm(event->uri, mm), nullTerm(event->name, mm)); for(i = 0; i < event->attr_count; ++i) { attr = &event->attrs[i]; LOCATION(attr); if(attr->xmlns_attr) { if(attr->prefix.ptr == 0) events_->namespaceEvent(0, nullTerm(attr->value.value, mm)); else events_->namespaceEvent(nullTerm(attr->name, mm), nullTerm(attr->value.value, mm)); } else { events_->attributeEvent(nullTerm(attr->prefix, mm), nullTerm(attr->uri, mm), nullTerm(attr->name, mm), nullTerm(attr->value.value, mm), SchemaSymbols::fgURI_SCHEMAFORSCHEMA, ATUntypedAtomic::fgDT_UNTYPEDATOMIC); } } if(event->type == START_ELEMENT_EVENT) break; // Fall through case END_ELEMENT_EVENT: events_->endElementEvent(nullTerm(event->prefix, mm), nullTerm(event->uri, mm), nullTerm(event->name, mm), SchemaSymbols::fgURI_SCHEMAFORSCHEMA, DocumentCache::g_szUntyped); break; case IGNORABLE_WHITESPACE_EVENT: // Do nothing break; case ENTITY_REFERENCE_EVENT: case DEC_CHAR_REFERENCE_EVENT: case HEX_CHAR_REFERENCE_EVENT: case CHARACTERS_EVENT: case CDATA_EVENT: events_->textEvent((XMLCh*)event->value.ptr, event->value.len / sizeof(XMLCh)); break; case COMMENT_EVENT: events_->commentEvent(nullTerm(event->value, mm)); break; case PI_EVENT: events_->piEvent(nullTerm(event->name, mm), nullTerm(event->value, mm)); break; case DOCTYPE_EVENT: case ENTITY_REFERENCE_START_EVENT: case ENTITY_REFERENCE_END_EVENT: case START_EXTERNAL_ENTITY_EVENT: case END_EXTERNAL_ENTITY_EVENT: case NO_EVENT: break; } } } catch(XQException& e) { if(e.getXQueryLine() == 0) { e.setXQueryPosition(&location_); } throw e; } }