diff options
author | scottmg <scottmg@chromium.org> | 2015-06-23 12:00:06 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-23 19:00:46 +0000 |
commit | 8285ba172641308c6d4775cc38d637ceacb0422a (patch) | |
tree | 0aec9453a5ff67b13da329343bc769600e4b7afe /third_party/libxslt/libexslt/strings.c | |
parent | dea8f652a25ffa68e366529697caee1a5617cf23 (diff) | |
download | chromium_src-8285ba172641308c6d4775cc38d637ceacb0422a.zip chromium_src-8285ba172641308c6d4775cc38d637ceacb0422a.tar.gz chromium_src-8285ba172641308c6d4775cc38d637ceacb0422a.tar.bz2 |
Upgrade to libxml 2.9.2 and libxslt 1.1.28
The previous version of libxml was released in 2008, so this is a large
jump.
One notable functionality change is that the parser no longer accepts
<stuff xmlns:stream="a"xmlns="b">
(with no space between the end quote of "a" and the xmlns= attribute).
This seems correct to not accept, but could potentially cause some minor
compatibility differences. This is the change in
xmpp_login_handler_unittest.js.
A second difference is that the column number reported in error
conditions has changed in some cases. This causes some expected-error
LayoutTests to differ in textual output. These seem reasonable and
should hopefully not cause any major compatibility issues.
Blink suppressions at https://codereview.chromium.org/1181403003/ which
need to land first.
BUG=463958,502468
Review URL: https://codereview.chromium.org/1193533007
Cr-Commit-Position: refs/heads/master@{#335721}
Diffstat (limited to 'third_party/libxslt/libexslt/strings.c')
-rw-r--r-- | third_party/libxslt/libexslt/strings.c | 332 |
1 files changed, 232 insertions, 100 deletions
diff --git a/third_party/libxslt/libexslt/strings.c b/third_party/libxslt/libexslt/strings.c index 1a11976..045cc14 100644 --- a/third_party/libxslt/libexslt/strings.c +++ b/third_party/libxslt/libexslt/strings.c @@ -27,7 +27,7 @@ * @nargs: the number of arguments * * Splits up a string on the characters of the delimiter string and returns a - * node set of token elements, each containing one token from the string. + * node set of token elements, each containing one token from the string. */ static void exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs) @@ -106,7 +106,7 @@ exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs) } } if (token != cur) { - node = xmlNewDocRawNode(container, NULL, + node = xmlNewDocRawNode(container, NULL, (const xmlChar *) "token", token); xmlAddChild((xmlNodePtr) container, node); xmlXPathNodeSetAddUnique(ret->nodesetval, node); @@ -136,7 +136,7 @@ fail: * @nargs: the number of arguments * * Splits up a string on a delimiting string and returns a node set of token - * elements, each containing one token from the string. + * elements, each containing one token from the string. */ static void exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) { @@ -335,7 +335,7 @@ exsltStrDecodeUriFunction (xmlXPathParserContextPtr ctxt, int nargs) { xmlFree(ret); return; } - + xmlXPathReturnString(ctxt, ret); if (str != NULL) @@ -505,139 +505,271 @@ exsltStrConcatFunction (xmlXPathParserContextPtr ctxt, int nargs) { } /** - * exsltStrReplaceInternal: - * @str: string to modify - * @searchStr: string to find - * @replaceStr: string to replace occurrences of searchStr + * exsltStrReturnString: + * @ctxt: an XPath parser context + * @str: a string + * @len: length of string * - * Search and replace string function used by exsltStrReplaceFunction + * Returns a string as a node set. */ -static xmlChar* -exsltStrReplaceInternal(const xmlChar* str, const xmlChar* searchStr, - const xmlChar* replaceStr) +static int +exsltStrReturnString(xmlXPathParserContextPtr ctxt, const xmlChar *str, + int len) { - const xmlChar *curr, *next; - xmlChar *ret = NULL; - int searchStrSize; + xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); + xmlDocPtr container; + xmlNodePtr text_node; + xmlXPathObjectPtr ret; - curr = str; - searchStrSize = xmlStrlen(searchStr); + container = xsltCreateRVT(tctxt); + if (container == NULL) { + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + return(-1); + } + xsltRegisterLocalRVT(tctxt, container); + + text_node = xmlNewTextLen(str, len); + if (text_node == NULL) { + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + return(-1); + } + xmlAddChild((xmlNodePtr) container, text_node); - do { - next = xmlStrstr(curr, searchStr); - if (next == NULL) { - ret = xmlStrcat (ret, curr); - break; - } + ret = xmlXPathNewNodeSet(text_node); + if (ret == NULL) { + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + return(-1); + } - ret = xmlStrncat (ret, curr, next - curr); - ret = xmlStrcat (ret, replaceStr); - curr = next + searchStrSize; - } while (*curr != 0); + xsltExtensionInstructionResultRegister(tctxt, ret); + valuePush(ctxt, ret); - return ret; + return(0); } + /** * exsltStrReplaceFunction: * @ctxt: an XPath parser context * @nargs: the number of arguments * - * Takes a string, and two node sets and returns the string with all strings in + * Takes a string, and two node sets and returns the string with all strings in * the first node set replaced by all strings in the second node set. */ static void exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) { - xmlChar *str = NULL, *searchStr = NULL, *replaceStr = NULL; - xmlNodeSetPtr replaceSet = NULL, searchSet = NULL; - xmlChar *ret = NULL, *retSwap = NULL; - int i; + int i, i_empty, n, slen0, rlen0, *slen, *rlen; + void *mem = NULL; + const xmlChar *src, *start; + xmlChar *string, *search_str = NULL, *replace_str = NULL; + xmlChar **search, **replace; + xmlNodeSetPtr search_set = NULL, replace_set = NULL; + xmlBufferPtr buf; if (nargs != 3) { - xmlXPathSetArityError(ctxt); - return; + xmlXPathSetArityError(ctxt); + return; } - /* pull out replace argument */ + /* get replace argument */ + + if (!xmlXPathStackIsNodeSet(ctxt)) + replace_str = xmlXPathPopString(ctxt); + else + replace_set = xmlXPathPopNodeSet(ctxt); + + if (xmlXPathCheckError(ctxt)) + goto fail_replace; + + /* get search argument */ + if (!xmlXPathStackIsNodeSet(ctxt)) { - replaceStr = xmlXPathPopString(ctxt); + search_str = xmlXPathPopString(ctxt); + n = 1; } - else { - replaceSet = xmlXPathPopNodeSet(ctxt); - if (xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - goto fail; - } + else { + search_set = xmlXPathPopNodeSet(ctxt); + n = search_set != NULL ? search_set->nodeNr : 0; } - /* behavior driven by search argument from here on */ - if (!xmlXPathStackIsNodeSet(ctxt)) { - searchStr = xmlXPathPopString(ctxt); - str = xmlXPathPopString(ctxt); - - if (replaceStr == NULL) { - xmlXPathSetTypeError(ctxt); - goto fail; - } - - ret = exsltStrReplaceInternal(str, searchStr, replaceStr); - } - else { - searchSet = xmlXPathPopNodeSet(ctxt); - if (searchSet == NULL || xmlXPathCheckError(ctxt)) { - xmlXPathSetTypeError(ctxt); - goto fail; - } - - str = xmlXPathPopString(ctxt); - ret = xmlStrdup(str); - - for (i = 0; i < searchSet->nodeNr; i++) { - searchStr = xmlXPathCastNodeToString(searchSet->nodeTab[i]); - - if (replaceSet != NULL) { - replaceStr = NULL; - if (i < replaceSet->nodeNr) { - replaceStr = xmlXPathCastNodeToString(replaceSet->nodeTab[i]); - } - - retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); - - if (replaceStr != NULL) { - xmlFree(replaceStr); - replaceStr = NULL; - } + if (xmlXPathCheckError(ctxt)) + goto fail_search; + + /* get string argument */ + + string = xmlXPathPopString(ctxt); + if (xmlXPathCheckError(ctxt)) + goto fail_string; + + /* check for empty search node list */ + + if (n <= 0) { + exsltStrReturnString(ctxt, string, xmlStrlen(string)); + goto done_empty_search; + } + + /* allocate memory for string pointer and length arrays */ + + if (n == 1) { + search = &search_str; + replace = &replace_str; + slen = &slen0; + rlen = &rlen0; + } + else { + mem = xmlMalloc(2 * n * (sizeof(const xmlChar *) + sizeof(int))); + if (mem == NULL) { + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + goto fail_malloc; + } + search = (xmlChar **) mem; + replace = search + n; + slen = (int *) (replace + n); + rlen = slen + n; + } + + /* process arguments */ + + i_empty = -1; + + for (i=0; i<n; ++i) { + if (search_set != NULL) { + search[i] = xmlXPathCastNodeToString(search_set->nodeTab[i]); + if (search[i] == NULL) { + n = i; + goto fail_process_args; + } + } + + slen[i] = xmlStrlen(search[i]); + if (i_empty < 0 && slen[i] == 0) + i_empty = i; + + if (replace_set != NULL) { + if (i < replace_set->nodeNr) { + replace[i] = xmlXPathCastNodeToString(replace_set->nodeTab[i]); + if (replace[i] == NULL) { + n = i + 1; + goto fail_process_args; + } + } + else + replace[i] = NULL; } else { - retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); + if (i == 0) + replace[i] = replace_str; + else + replace[i] = NULL; } - xmlFree(ret); - if (searchStr != NULL) { - xmlFree(searchStr); - searchStr = NULL; + if (replace[i] == NULL) + rlen[i] = 0; + else + rlen[i] = xmlStrlen(replace[i]); + } + + if (i_empty >= 0 && rlen[i_empty] == 0) + i_empty = -1; + + /* replace operation */ + + buf = xmlBufferCreate(); + if (buf == NULL) { + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + goto fail_buffer; + } + src = string; + start = string; + + while (*src != 0) { + int max_len = 0, i_match = 0; + + for (i=0; i<n; ++i) { + if (*src == search[i][0] && + slen[i] > max_len && + xmlStrncmp(src, search[i], slen[i]) == 0) + { + i_match = i; + max_len = slen[i]; + } } - ret = retSwap; - } + if (max_len == 0) { + if (i_empty >= 0 && start < src) { + if (xmlBufferAdd(buf, start, src - start) || + xmlBufferAdd(buf, replace[i_empty], rlen[i_empty])) + { + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + goto fail_buffer_add; + } + start = src; + } - if (replaceSet != NULL) - xmlXPathFreeNodeSet(replaceSet); + src += xmlUTF8Size(src); + } + else { + if ((start < src && + xmlBufferAdd(buf, start, src - start)) || + (rlen[i_match] && + xmlBufferAdd(buf, replace[i_match], rlen[i_match]))) + { + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + goto fail_buffer_add; + } - if (searchSet != NULL) - xmlXPathFreeNodeSet(searchSet); - } + src += slen[i_match]; + start = src; + } + } - xmlXPathReturnString(ctxt, ret); + if (start < src && xmlBufferAdd(buf, start, src - start)) { + xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); + goto fail_buffer_add; + } - fail: - if (replaceStr != NULL) - xmlFree(replaceStr); + /* create result node set */ - if (searchStr != NULL) - xmlFree(searchStr); + exsltStrReturnString(ctxt, xmlBufferContent(buf), xmlBufferLength(buf)); - if (str != NULL) - xmlFree(str); + /* clean up */ + +fail_buffer_add: + xmlBufferFree(buf); + +fail_buffer: +fail_process_args: + if (search_set != NULL) { + for (i=0; i<n; ++i) + xmlFree(search[i]); + } + if (replace_set != NULL) { + for (i=0; i<n; ++i) { + if (replace[i] != NULL) + xmlFree(replace[i]); + } + } + + if (mem != NULL) + xmlFree(mem); + +fail_malloc: +done_empty_search: + xmlFree(string); + +fail_string: + if (search_set != NULL) + xmlXPathFreeNodeSet(search_set); + else + xmlFree(search_str); + +fail_search: + if (replace_set != NULL) + xmlXPathFreeNodeSet(replace_set); + else + xmlFree(replace_str); + +fail_replace: + return; } /** |