/** * xmlDictFree: * @dict: the dictionnary * * Free the hash @dict and its contents. The userdata is * deallocated with @f if provided. */ void xmlDictFree(xmlDictPtr dict) { int i; xmlDictEntryPtr iter; xmlDictEntryPtr next; int inside_dict = 0; xmlDictStringsPtr pool, nextp; if (dict == NULL) return; if (!xmlDictInitialized) if (!xmlInitializeDict()) return; /* decrement the counter, it may be shared by a parser and docs */ xmlRMutexLock(xmlDictMutex); dict->ref_counter--; if (dict->ref_counter > 0) { xmlRMutexUnlock(xmlDictMutex); return; } xmlRMutexUnlock(xmlDictMutex); if (dict->subdict != NULL) { xmlDictFree(dict->subdict); } if (dict->dict) { for (i = 0; ((i < dict->size) && (dict->nbElems > 0)); i++) { iter = &(dict->dict[i]); if (iter->valid == 0) continue; inside_dict = 1; while (iter) { next = iter->next; if (!inside_dict) xmlFree(iter); dict->nbElems--; inside_dict = 0; iter = next; } inside_dict = 0; } xmlFree(dict->dict); } pool = dict->strings; while (pool != NULL) { nextp = pool->next; xmlFree(pool); pool = nextp; } xmlFreeRMutex(dict->mutex); xmlFree(dict); }
/** * xmlSchematronFreeValidCtxt: * @ctxt: the schema validation context * * Free the resources associated to the schema validation context */ void xmlSchematronFreeValidCtxt(xmlSchematronValidCtxtPtr ctxt) { if (ctxt == NULL) return; if (ctxt->xctxt != NULL) xmlXPathFreeContext(ctxt->xctxt); if (ctxt->dict != NULL) xmlDictFree(ctxt->dict); xmlFree(ctxt); }
/** * xmlDictFree: * @param dict the dictionnary * * Free the hash dict and its contents. The userdata is * deallocated with f if provided. */ XMLPUBFUNEXPORT void xmlDictFree(xmlDictPtr dict) { int i; xmlDictEntryPtr iter; xmlDictEntryPtr next; int inside_dict = 0; xmlDictStringsPtr pool, nextp; if (!dict) return; /* decrement the counter, it may be shared by a parser and docs */ dict->ref_counter--; if (dict->ref_counter > 0) return; if (dict->subdict) { xmlDictFree(dict->subdict); } if (dict->dict) { for(i = 0; ((i < dict->size) && (dict->nbElems > 0)); i++) { iter = &(dict->dict[i]); if (iter->valid == 0) continue; inside_dict = 1; while (iter) { next = iter->next; if (!inside_dict) xmlFree(iter); dict->nbElems--; inside_dict = 0; iter = next; } inside_dict = 0; } xmlFree(dict->dict); } pool = dict->strings; while (pool) { nextp = pool->next; xmlFree(pool); pool = nextp; } xmlFree(dict); }
bool XSLStyleSheet::parseString(const String& string, bool) { // Parse in a single chunk into an xmlDocPtr const UChar BOM = 0xFEFF; const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM); setLoaderForLibXMLCallbacks(docLoader()); if (!m_stylesheetDocTaken) xmlFreeDoc(m_stylesheetDoc); m_stylesheetDocTaken = false; #if ENABLE(INSPECTOR) Console* console = 0; if (Frame* frame = ownerDocument()->frame()) console = frame->domWindow()->console(); xmlSetStructuredErrorFunc(console, XSLTProcessor::parseErrorFunc); xmlSetGenericErrorFunc(console, XSLTProcessor::genericErrorFunc); #endif const char* buffer = reinterpret_cast<const char*>(string.characters()); int size = string.length() * sizeof(UChar); xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(buffer, size); if (m_parentStyleSheet) { // The XSL transform may leave the newly-transformed document // with references to the symbol dictionaries of the style sheet // and any of its children. XML document disposal can corrupt memory // if a document uses more than one symbol dictionary, so we // ensure that all child stylesheets use the same dictionaries as their // parents. xmlDictFree(ctxt->dict); ctxt->dict = m_parentStyleSheet->m_stylesheetDoc->dict; xmlDictReference(ctxt->dict); } m_stylesheetDoc = xmlCtxtReadMemory(ctxt, buffer, size, href().utf8().data(), BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_NOWARNING | XML_PARSE_NOCDATA); xmlFreeParserCtxt(ctxt); loadChildSheets(); xmlSetStructuredErrorFunc(0, 0); xmlSetGenericErrorFunc(0, 0); setLoaderForLibXMLCallbacks(0); return m_stylesheetDoc; }
/** * xmlSchematronFreeParserCtxt: * @ctxt: the schema parser context * * Free the resources associated to the schema parser context */ void xmlSchematronFreeParserCtxt(xmlSchematronParserCtxtPtr ctxt) { if (ctxt == NULL) return; if (ctxt->doc != NULL && !ctxt->preserve) xmlFreeDoc(ctxt->doc); if (ctxt->xctxt != NULL) { xmlXPathFreeContext(ctxt->xctxt); } if (ctxt->namespaces != NULL) xmlFree((char **) ctxt->namespaces); xmlDictFree(ctxt->dict); xmlFree(ctxt); }
/** * xmlSchematronFree: * @schema: a schema structure * * Deallocate a Schematron structure. */ void xmlSchematronFree(xmlSchematronPtr schema) { if (schema == NULL) return; if ((schema->doc != NULL) && (!(schema->preserve))) xmlFreeDoc(schema->doc); if (schema->namespaces != NULL) xmlFree((char **) schema->namespaces); xmlSchematronFreeRules(schema->rules); xmlSchematronFreePatterns(schema->patterns); xmlDictFree(schema->dict); xmlFree(schema); }
bool XSLStyleSheet::parseString(const String& string) { // Parse in a single chunk into an xmlDocPtr const UChar BOM = 0xFEFF; const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM); if (!m_stylesheetDocTaken) xmlFreeDoc(m_stylesheetDoc); m_stylesheetDocTaken = false; PageConsoleClient* console = nullptr; Frame* frame = ownerDocument()->frame(); if (frame && frame->page()) console = &frame->page()->console(); XMLDocumentParserScope scope(cachedResourceLoader(), XSLTProcessor::genericErrorFunc, XSLTProcessor::parseErrorFunc, console); auto upconvertedCharacters = StringView(string).upconvertedCharacters(); const char* buffer = reinterpret_cast<const char*>(upconvertedCharacters.get()); int size = string.length() * sizeof(UChar); xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(buffer, size); if (!ctxt) return 0; if (m_parentStyleSheet) { // The XSL transform may leave the newly-transformed document // with references to the symbol dictionaries of the style sheet // and any of its children. XML document disposal can corrupt memory // if a document uses more than one symbol dictionary, so we // ensure that all child stylesheets use the same dictionaries as their // parents. xmlDictFree(ctxt->dict); ctxt->dict = m_parentStyleSheet->m_stylesheetDoc->dict; xmlDictReference(ctxt->dict); } m_stylesheetDoc = xmlCtxtReadMemory(ctxt, buffer, size, finalURL().string().utf8().data(), BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_NOWARNING | XML_PARSE_NOCDATA); xmlFreeParserCtxt(ctxt); loadChildSheets(); return m_stylesheetDoc; }
bool XSLStyleSheet::parseString(const String& source) { // Parse in a single chunk into an xmlDocPtr if (!m_stylesheetDocTaken) xmlFreeDoc(m_stylesheetDoc); m_stylesheetDocTaken = false; PageConsole* console = 0; Frame* frame = ownerDocument()->frame(); if (frame && frame->host()) console = &frame->host()->console(); XMLDocumentParserScope scope(fetcher(), XSLTProcessor::genericErrorFunc, XSLTProcessor::parseErrorFunc, console); XMLParserInput input(source); xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(input.data(), input.size()); if (!ctxt) return 0; if (m_parentStyleSheet) { // The XSL transform may leave the newly-transformed document // with references to the symbol dictionaries of the style sheet // and any of its children. XML document disposal can corrupt memory // if a document uses more than one symbol dictionary, so we // ensure that all child stylesheets use the same dictionaries as their // parents. xmlDictFree(ctxt->dict); ctxt->dict = m_parentStyleSheet->m_stylesheetDoc->dict; xmlDictReference(ctxt->dict); } m_stylesheetDoc = xmlCtxtReadMemory(ctxt, input.data(), input.size(), finalURL().string().utf8().data(), input.encoding(), XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_NOWARNING | XML_PARSE_NOCDATA); xmlFreeParserCtxt(ctxt); loadChildSheets(); return m_stylesheetDoc; }
/* * Test a single dictionary */ static int run_test1(void) { int i, j; xmlDictPtr dict; int ret = 0; xmlChar prefix[40]; xmlChar *cur, *pref; const xmlChar *tmp; dict = xmlDictCreate(); if (dict == NULL) { fprintf(stderr, "Out of memory while creating dictionary\n"); exit(1); } memset(test1, 0, sizeof(test1)); /* * Fill in NB_STRINGS_MIN, at this point the dictionary should not grow * and we allocate all those doing the fast key computations */ for (i = 0;i < NB_STRINGS_MIN;i++) { test1[i] = xmlDictLookup(dict, strings1[i], -1); if (test1[i] == NULL) { fprintf(stderr, "Failed lookup for '%s'\n", strings1[i]); ret = 1; nbErrors++; } } j = NB_STRINGS_MAX - NB_STRINGS_NS; /* ":foo" like strings1 */ for (i = 0;i < NB_STRINGS_MIN;i++, j++) { test1[j] = xmlDictLookup(dict, strings1[j], xmlStrlen(strings1[j])); if (test1[j] == NULL) { fprintf(stderr, "Failed lookup for '%s'\n", strings1[j]); ret = 1; nbErrors++; } } /* "a:foo" like strings1 */ j = NB_STRINGS_MAX - NB_STRINGS_MIN; for (i = 0;i < NB_STRINGS_MIN;i++, j++) { test1[j] = xmlDictLookup(dict, strings1[j], xmlStrlen(strings1[j])); if (test1[j] == NULL) { fprintf(stderr, "Failed lookup for '%s'\n", strings1[j]); ret = 1; nbErrors++; } } /* * At this point allocate all the strings * the dictionary will grow in the process, reallocate more string tables * and switch to the better key generator */ for (i = 0;i < NB_STRINGS_MAX;i++) { if (test1[i] != NULL) continue; test1[i] = xmlDictLookup(dict, strings1[i], -1); if (test1[i] == NULL) { fprintf(stderr, "Failed lookup for '%s'\n", strings1[i]); ret = 1; nbErrors++; } } /* * Now we can start to test things, first that all strings1 belongs to * the dict */ for (i = 0;i < NB_STRINGS_MAX;i++) { if (!xmlDictOwns(dict, test1[i])) { fprintf(stderr, "Failed ownership failure for '%s'\n", strings1[i]); ret = 1; nbErrors++; } } /* * Then that another lookup to the string will return the same */ for (i = 0;i < NB_STRINGS_MAX;i++) { if (xmlDictLookup(dict, strings1[i], -1) != test1[i]) { fprintf(stderr, "Failed re-lookup check for %d, '%s'\n", i, strings1[i]); ret = 1; nbErrors++; } } /* * More complex, check the QName lookups */ for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) { cur = strings1[i]; pref = &prefix[0]; while (*cur != ':') *pref++ = *cur++; cur++; *pref = 0; tmp = xmlDictQLookup(dict, &prefix[0], cur); if (tmp != test1[i]) { fprintf(stderr, "Failed lookup check for '%s':'%s'\n", &prefix[0], cur); ret = 1; nbErrors++; } } run_test2(dict); xmlDictFree(dict); return(ret); }
/* * This tests the sub-dictionary support */ static int run_test2(xmlDictPtr parent) { int i, j; xmlDictPtr dict; int ret = 0; xmlChar prefix[40]; xmlChar *cur, *pref; const xmlChar *tmp; dict = xmlDictCreateSub(parent); if (dict == NULL) { fprintf(stderr, "Out of memory while creating sub-dictionary\n"); exit(1); } memset(test2, 0, sizeof(test2)); /* * Fill in NB_STRINGS_MIN, at this point the dictionary should not grow * and we allocate all those doing the fast key computations * All the strings are based on a different seeds subset so we know * they are allocated in the main dictionary, not coming from the parent */ for (i = 0;i < NB_STRINGS_MIN;i++) { test2[i] = xmlDictLookup(dict, strings2[i], -1); if (test2[i] == NULL) { fprintf(stderr, "Failed lookup for '%s'\n", strings2[i]); ret = 1; nbErrors++; } } j = NB_STRINGS_MAX - NB_STRINGS_NS; /* ":foo" like strings2 */ for (i = 0;i < NB_STRINGS_MIN;i++, j++) { test2[j] = xmlDictLookup(dict, strings2[j], xmlStrlen(strings2[j])); if (test2[j] == NULL) { fprintf(stderr, "Failed lookup for '%s'\n", strings2[j]); ret = 1; nbErrors++; } } /* "a:foo" like strings2 */ j = NB_STRINGS_MAX - NB_STRINGS_MIN; for (i = 0;i < NB_STRINGS_MIN;i++, j++) { test2[j] = xmlDictLookup(dict, strings2[j], xmlStrlen(strings2[j])); if (test2[j] == NULL) { fprintf(stderr, "Failed lookup for '%s'\n", strings2[j]); ret = 1; nbErrors++; } } /* * At this point allocate all the strings * the dictionary will grow in the process, reallocate more string tables * and switch to the better key generator */ for (i = 0;i < NB_STRINGS_MAX;i++) { if (test2[i] != NULL) continue; test2[i] = xmlDictLookup(dict, strings2[i], -1); if (test2[i] == NULL) { fprintf(stderr, "Failed lookup for '%s'\n", strings2[i]); ret = 1; nbErrors++; } } /* * Now we can start to test things, first that all strings2 belongs to * the dict, and that none of them was actually allocated in the parent */ for (i = 0;i < NB_STRINGS_MAX;i++) { if (!xmlDictOwns(dict, test2[i])) { fprintf(stderr, "Failed ownership failure for '%s'\n", strings2[i]); ret = 1; nbErrors++; } if (xmlDictOwns(parent, test2[i])) { fprintf(stderr, "Failed parent ownership failure for '%s'\n", strings2[i]); ret = 1; nbErrors++; } } /* * Also verify that all strings from the parent are seen from the subdict */ for (i = 0;i < NB_STRINGS_MAX;i++) { if (!xmlDictOwns(dict, test1[i])) { fprintf(stderr, "Failed sub-ownership failure for '%s'\n", strings1[i]); ret = 1; nbErrors++; } } /* * Then that another lookup to the string in sub will return the same */ for (i = 0;i < NB_STRINGS_MAX;i++) { if (xmlDictLookup(dict, strings2[i], -1) != test2[i]) { fprintf(stderr, "Failed re-lookup check for %d, '%s'\n", i, strings2[i]); ret = 1; nbErrors++; } } /* * But also that any lookup for a string in the parent will be provided * as in the parent */ for (i = 0;i < NB_STRINGS_MAX;i++) { if (xmlDictLookup(dict, strings1[i], -1) != test1[i]) { fprintf(stderr, "Failed parent string lookup check for %d, '%s'\n", i, strings1[i]); ret = 1; nbErrors++; } } /* * check the QName lookups */ for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) { cur = strings2[i]; pref = &prefix[0]; while (*cur != ':') *pref++ = *cur++; cur++; *pref = 0; tmp = xmlDictQLookup(dict, &prefix[0], cur); if (tmp != test2[i]) { fprintf(stderr, "Failed lookup check for '%s':'%s'\n", &prefix[0], cur); ret = 1; nbErrors++; } } /* * check the QName lookups for strings from the parent */ for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) { cur = strings1[i]; pref = &prefix[0]; while (*cur != ':') *pref++ = *cur++; cur++; *pref = 0; tmp = xmlDictQLookup(dict, &prefix[0], cur); if (xmlDictQLookup(dict, &prefix[0], cur) != test1[i]) { fprintf(stderr, "Failed parent lookup check for '%s':'%s'\n", &prefix[0], cur); ret = 1; nbErrors++; } } xmlDictFree(dict); return(ret); }