summaryrefslogtreecommitdiffstats
path: root/third_party/libxslt/libexslt/strings.c
diff options
context:
space:
mode:
authorscottmg <scottmg@chromium.org>2015-06-23 12:00:06 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-23 19:00:46 +0000
commit8285ba172641308c6d4775cc38d637ceacb0422a (patch)
tree0aec9453a5ff67b13da329343bc769600e4b7afe /third_party/libxslt/libexslt/strings.c
parentdea8f652a25ffa68e366529697caee1a5617cf23 (diff)
downloadchromium_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.c332
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;
}
/**