Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: third_party/libxslt/libexslt/strings.c

Issue 1193533007: Upgrade to libxml 2.9.2 and libxslt 1.1.28 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: no iconv Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libxslt/libexslt/saxon.c ('k') | third_party/libxslt/libxslt.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #define IN_LIBEXSLT 1 #define IN_LIBEXSLT
2 #include "libexslt/libexslt.h" 2 #include "libexslt/libexslt.h"
3 3
4 #if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) 4 #if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__)
5 #include <win32config.h> 5 #include <win32config.h>
6 #else 6 #else
7 #include "config.h" 7 #include "config.h"
8 #endif 8 #endif
9 9
10 #include <libxml/tree.h> 10 #include <libxml/tree.h>
11 #include <libxml/xpath.h> 11 #include <libxml/xpath.h>
12 #include <libxml/xpathInternals.h> 12 #include <libxml/xpathInternals.h>
13 #include <libxml/parser.h> 13 #include <libxml/parser.h>
14 #include <libxml/encoding.h> 14 #include <libxml/encoding.h>
15 #include <libxml/uri.h> 15 #include <libxml/uri.h>
16 16
17 #include <libxslt/xsltconfig.h> 17 #include <libxslt/xsltconfig.h>
18 #include <libxslt/xsltutils.h> 18 #include <libxslt/xsltutils.h>
19 #include <libxslt/xsltInternals.h> 19 #include <libxslt/xsltInternals.h>
20 #include <libxslt/extensions.h> 20 #include <libxslt/extensions.h>
21 21
22 #include "exslt.h" 22 #include "exslt.h"
23 23
24 /** 24 /**
25 * exsltStrTokenizeFunction: 25 * exsltStrTokenizeFunction:
26 * @ctxt: an XPath parser context 26 * @ctxt: an XPath parser context
27 * @nargs: the number of arguments 27 * @nargs: the number of arguments
28 * 28 *
29 * Splits up a string on the characters of the delimiter string and returns a 29 * Splits up a string on the characters of the delimiter string and returns a
30 * node set of token elements, each containing one token from the string. 30 * node set of token elements, each containing one token from the string.
31 */ 31 */
32 static void 32 static void
33 exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs) 33 exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs)
34 { 34 {
35 xsltTransformContextPtr tctxt; 35 xsltTransformContextPtr tctxt;
36 xmlChar *str, *delimiters, *cur; 36 xmlChar *str, *delimiters, *cur;
37 const xmlChar *token, *delimiter; 37 const xmlChar *token, *delimiter;
38 xmlNodePtr node; 38 xmlNodePtr node;
39 xmlDocPtr container; 39 xmlDocPtr container;
40 xmlXPathObjectPtr ret = NULL; 40 xmlXPathObjectPtr ret = NULL;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 (const xmlChar *) "token", token); 99 (const xmlChar *) "token", token);
100 xmlAddChild((xmlNodePtr) container, node); 100 xmlAddChild((xmlNodePtr) container, node);
101 xmlXPathNodeSetAddUnique(ret->nodesetval, node); 101 xmlXPathNodeSetAddUnique(ret->nodesetval, node);
102 *cur = *delimiter; /* restore the changed byte */ 102 *cur = *delimiter; /* restore the changed byte */
103 token = cur + clen; 103 token = cur + clen;
104 break; 104 break;
105 } 105 }
106 } 106 }
107 } 107 }
108 if (token != cur) { 108 if (token != cur) {
109 » » node = xmlNewDocRawNode(container, NULL, 109 » » node = xmlNewDocRawNode(container, NULL,
110 (const xmlChar *) "token", token); 110 (const xmlChar *) "token", token);
111 xmlAddChild((xmlNodePtr) container, node); 111 xmlAddChild((xmlNodePtr) container, node);
112 xmlXPathNodeSetAddUnique(ret->nodesetval, node); 112 xmlXPathNodeSetAddUnique(ret->nodesetval, node);
113 } 113 }
114 /* 114 /*
115 * Mark it as a function result in order to avoid garbage 115 * Mark it as a function result in order to avoid garbage
116 * collecting of tree fragments 116 * collecting of tree fragments
117 */ 117 */
118 xsltExtensionInstructionResultRegister(tctxt, ret); 118 xsltExtensionInstructionResultRegister(tctxt, ret);
119 } 119 }
120 } 120 }
121 121
122 fail: 122 fail:
123 if (str != NULL) 123 if (str != NULL)
124 xmlFree(str); 124 xmlFree(str);
125 if (delimiters != NULL) 125 if (delimiters != NULL)
126 xmlFree(delimiters); 126 xmlFree(delimiters);
127 if (ret != NULL) 127 if (ret != NULL)
128 valuePush(ctxt, ret); 128 valuePush(ctxt, ret);
129 else 129 else
130 valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 130 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
131 } 131 }
132 132
133 /** 133 /**
134 * exsltStrSplitFunction: 134 * exsltStrSplitFunction:
135 * @ctxt: an XPath parser context 135 * @ctxt: an XPath parser context
136 * @nargs: the number of arguments 136 * @nargs: the number of arguments
137 * 137 *
138 * Splits up a string on a delimiting string and returns a node set of token 138 * Splits up a string on a delimiting string and returns a node set of token
139 * elements, each containing one token from the string. 139 * elements, each containing one token from the string.
140 */ 140 */
141 static void 141 static void
142 exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) { 142 exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) {
143 xsltTransformContextPtr tctxt; 143 xsltTransformContextPtr tctxt;
144 xmlChar *str, *delimiter, *cur; 144 xmlChar *str, *delimiter, *cur;
145 const xmlChar *token; 145 const xmlChar *token;
146 xmlNodePtr node; 146 xmlNodePtr node;
147 xmlDocPtr container; 147 xmlDocPtr container;
148 xmlXPathObjectPtr ret = NULL; 148 xmlXPathObjectPtr ret = NULL;
149 int delimiterLength; 149 int delimiterLength;
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 328
329 ret = (xmlChar *) xmlURIUnescapeString((const char *)str,0,NULL); 329 ret = (xmlChar *) xmlURIUnescapeString((const char *)str,0,NULL);
330 if (!xmlCheckUTF8(ret)) { 330 if (!xmlCheckUTF8(ret)) {
331 /* FIXME: instead of throwing away the whole URI, we should 331 /* FIXME: instead of throwing away the whole URI, we should
332 only discard the invalid sequence(s). How to do that? */ 332 only discard the invalid sequence(s). How to do that? */
333 xmlXPathReturnEmptyString(ctxt); 333 xmlXPathReturnEmptyString(ctxt);
334 xmlFree(str); 334 xmlFree(str);
335 xmlFree(ret); 335 xmlFree(ret);
336 return; 336 return;
337 } 337 }
338 338
339 xmlXPathReturnString(ctxt, ret); 339 xmlXPathReturnString(ctxt, ret);
340 340
341 if (str != NULL) 341 if (str != NULL)
342 xmlFree(str); 342 xmlFree(str);
343 } 343 }
344 344
345 /** 345 /**
346 * exsltStrPaddingFunction: 346 * exsltStrPaddingFunction:
347 * @ctxt: an XPath parser context 347 * @ctxt: an XPath parser context
348 * @nargs: the number of arguments 348 * @nargs: the number of arguments
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 498
499 xmlFree(tmp); 499 xmlFree(tmp);
500 } 500 }
501 501
502 xmlXPathFreeObject (obj); 502 xmlXPathFreeObject (obj);
503 503
504 xmlXPathReturnString(ctxt, ret); 504 xmlXPathReturnString(ctxt, ret);
505 } 505 }
506 506
507 /** 507 /**
508 * exsltStrReplaceInternal: 508 * exsltStrReturnString:
509 * @str: string to modify 509 * @ctxt: an XPath parser context
510 * @searchStr: string to find 510 * @str: a string
511 * @replaceStr: string to replace occurrences of searchStr 511 * @len: length of string
512 * 512 *
513 * Search and replace string function used by exsltStrReplaceFunction 513 * Returns a string as a node set.
514 */ 514 */
515 static xmlChar* 515 static int
516 exsltStrReplaceInternal(const xmlChar* str, const xmlChar* searchStr, 516 exsltStrReturnString(xmlXPathParserContextPtr ctxt, const xmlChar *str,
517 const xmlChar* replaceStr) 517 int len)
518 { 518 {
519 const xmlChar *curr, *next; 519 xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
520 xmlChar *ret = NULL; 520 xmlDocPtr container;
521 int searchStrSize; 521 xmlNodePtr text_node;
522 522 xmlXPathObjectPtr ret;
523 curr = str; 523
524 searchStrSize = xmlStrlen(searchStr); 524 container = xsltCreateRVT(tctxt);
525 525 if (container == NULL) {
526 do { 526 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
527 next = xmlStrstr(curr, searchStr); 527 return(-1);
528 if (next == NULL) { 528 }
529 ret = xmlStrcat (ret, curr); 529 xsltRegisterLocalRVT(tctxt, container);
530 break; 530
531 } 531 text_node = xmlNewTextLen(str, len);
532 532 if (text_node == NULL) {
533 ret = xmlStrncat (ret, curr, next - curr); 533 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
534 ret = xmlStrcat (ret, replaceStr); 534 return(-1);
535 curr = next + searchStrSize; 535 }
536 } while (*curr != 0); 536 xmlAddChild((xmlNodePtr) container, text_node);
537 537
538 return ret; 538 ret = xmlXPathNewNodeSet(text_node);
539 if (ret == NULL) {
540 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
541 return(-1);
542 }
543
544 xsltExtensionInstructionResultRegister(tctxt, ret);
545 valuePush(ctxt, ret);
546
547 return(0);
539 } 548 }
549
540 /** 550 /**
541 * exsltStrReplaceFunction: 551 * exsltStrReplaceFunction:
542 * @ctxt: an XPath parser context 552 * @ctxt: an XPath parser context
543 * @nargs: the number of arguments 553 * @nargs: the number of arguments
544 * 554 *
545 * Takes a string, and two node sets and returns the string with all strings in 555 * Takes a string, and two node sets and returns the string with all strings in
546 * the first node set replaced by all strings in the second node set. 556 * the first node set replaced by all strings in the second node set.
547 */ 557 */
548 static void 558 static void
549 exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) { 559 exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) {
550 xmlChar *str = NULL, *searchStr = NULL, *replaceStr = NULL; 560 int i, i_empty, n, slen0, rlen0, *slen, *rlen;
551 xmlNodeSetPtr replaceSet = NULL, searchSet = NULL; 561 void *mem = NULL;
552 xmlChar *ret = NULL, *retSwap = NULL; 562 const xmlChar *src, *start;
553 int i; 563 xmlChar *string, *search_str = NULL, *replace_str = NULL;
564 xmlChar **search, **replace;
565 xmlNodeSetPtr search_set = NULL, replace_set = NULL;
566 xmlBufferPtr buf;
554 567
555 if (nargs != 3) { 568 if (nargs != 3) {
556 xmlXPathSetArityError(ctxt); 569 xmlXPathSetArityError(ctxt);
557 return; 570 return;
558 } 571 }
559 572
560 /* pull out replace argument */ 573 /* get replace argument */
574
575 if (!xmlXPathStackIsNodeSet(ctxt))
576 replace_str = xmlXPathPopString(ctxt);
577 else
578 replace_set = xmlXPathPopNodeSet(ctxt);
579
580 if (xmlXPathCheckError(ctxt))
581 goto fail_replace;
582
583 /* get search argument */
584
561 if (!xmlXPathStackIsNodeSet(ctxt)) { 585 if (!xmlXPathStackIsNodeSet(ctxt)) {
562 replaceStr = xmlXPathPopString(ctxt); 586 search_str = xmlXPathPopString(ctxt);
563 } 587 n = 1;
564 » » else { 588 }
565 replaceSet = xmlXPathPopNodeSet(ctxt); 589 else {
566 if (xmlXPathCheckError(ctxt)) { 590 search_set = xmlXPathPopNodeSet(ctxt);
567 xmlXPathSetTypeError(ctxt); 591 n = search_set != NULL ? search_set->nodeNr : 0;
568 goto fail; 592 }
569 } 593
570 } 594 if (xmlXPathCheckError(ctxt))
571 595 goto fail_search;
572 /* behavior driven by search argument from here on */ 596
573 if (!xmlXPathStackIsNodeSet(ctxt)) { 597 /* get string argument */
574 searchStr = xmlXPathPopString(ctxt); 598
575 str = xmlXPathPopString(ctxt); 599 string = xmlXPathPopString(ctxt);
576 600 if (xmlXPathCheckError(ctxt))
577 if (replaceStr == NULL) { 601 goto fail_string;
578 xmlXPathSetTypeError(ctxt); 602
579 goto fail; 603 /* check for empty search node list */
580 } 604
581 605 if (n <= 0) {
582 ret = exsltStrReplaceInternal(str, searchStr, replaceStr); 606 exsltStrReturnString(ctxt, string, xmlStrlen(string));
583 } 607 goto done_empty_search;
584 » » else { 608 }
585 searchSet = xmlXPathPopNodeSet(ctxt); 609
586 if (searchSet == NULL || xmlXPathCheckError(ctxt)) { 610 /* allocate memory for string pointer and length arrays */
587 xmlXPathSetTypeError(ctxt); 611
588 goto fail; 612 if (n == 1) {
589 } 613 search = &search_str;
590 614 replace = &replace_str;
591 str = xmlXPathPopString(ctxt); 615 slen = &slen0;
592 ret = xmlStrdup(str); 616 rlen = &rlen0;
593 617 }
594 for (i = 0; i < searchSet->nodeNr; i++) { 618 else {
595 » searchStr = xmlXPathCastNodeToString(searchSet->nodeTab[i]); 619 mem = xmlMalloc(2 * n * (sizeof(const xmlChar *) + sizeof(int)));
596 620 if (mem == NULL) {
597 if (replaceSet != NULL) { 621 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
598 replaceStr = NULL; 622 goto fail_malloc;
599 if (i < replaceSet->nodeNr) { 623 }
600 replaceStr = xmlXPathCastNodeToString(replaceSet->nodeTab[i]); 624 search = (xmlChar **) mem;
601 } 625 replace = search + n;
602 626 slen = (int *) (replace + n);
603 retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); 627 rlen = slen + n;
604 628 }
605 if (replaceStr != NULL) { 629
606 xmlFree(replaceStr); 630 /* process arguments */
607 replaceStr = NULL; 631
608 } 632 i_empty = -1;
633
634 for (i=0; i<n; ++i) {
635 if (search_set != NULL) {
636 search[i] = xmlXPathCastNodeToString(search_set->nodeTab[i]);
637 if (search[i] == NULL) {
638 n = i;
639 goto fail_process_args;
640 }
641 }
642
643 slen[i] = xmlStrlen(search[i]);
644 if (i_empty < 0 && slen[i] == 0)
645 i_empty = i;
646
647 if (replace_set != NULL) {
648 if (i < replace_set->nodeNr) {
649 replace[i] = xmlXPathCastNodeToString(replace_set->nodeTab[i]);
650 if (replace[i] == NULL) {
651 n = i + 1;
652 goto fail_process_args;
653 }
654 }
655 else
656 replace[i] = NULL;
609 } 657 }
610 else { 658 else {
611 retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); 659 if (i == 0)
612 } 660 replace[i] = replace_str;
613 661 else
614 » » » » xmlFree(ret); 662 replace[i] = NULL;
615 if (searchStr != NULL) { 663 }
616 xmlFree(searchStr); 664
617 searchStr = NULL; 665 if (replace[i] == NULL)
618 } 666 rlen[i] = 0;
619 667 else
620 » » » » ret = retSwap; 668 rlen[i] = xmlStrlen(replace[i]);
621 » » » } 669 }
622 670
623 if (replaceSet != NULL) 671 if (i_empty >= 0 && rlen[i_empty] == 0)
624 xmlXPathFreeNodeSet(replaceSet); 672 i_empty = -1;
625 673
626 if (searchSet != NULL) 674 /* replace operation */
627 xmlXPathFreeNodeSet(searchSet); 675
628 » » } 676 buf = xmlBufferCreate();
629 677 if (buf == NULL) {
630 xmlXPathReturnString(ctxt, ret); 678 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
631 679 goto fail_buffer;
632 fail: 680 }
633 if (replaceStr != NULL) 681 src = string;
634 xmlFree(replaceStr); 682 start = string;
635 683
636 if (searchStr != NULL) 684 while (*src != 0) {
637 xmlFree(searchStr); 685 int max_len = 0, i_match = 0;
638 686
639 if (str != NULL) 687 for (i=0; i<n; ++i) {
640 xmlFree(str); 688 if (*src == search[i][0] &&
689 slen[i] > max_len &&
690 xmlStrncmp(src, search[i], slen[i]) == 0)
691 {
692 i_match = i;
693 max_len = slen[i];
694 }
695 }
696
697 if (max_len == 0) {
698 if (i_empty >= 0 && start < src) {
699 if (xmlBufferAdd(buf, start, src - start) ||
700 xmlBufferAdd(buf, replace[i_empty], rlen[i_empty]))
701 {
702 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
703 goto fail_buffer_add;
704 }
705 start = src;
706 }
707
708 src += xmlUTF8Size(src);
709 }
710 else {
711 if ((start < src &&
712 xmlBufferAdd(buf, start, src - start)) ||
713 (rlen[i_match] &&
714 xmlBufferAdd(buf, replace[i_match], rlen[i_match])))
715 {
716 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
717 goto fail_buffer_add;
718 }
719
720 src += slen[i_match];
721 start = src;
722 }
723 }
724
725 if (start < src && xmlBufferAdd(buf, start, src - start)) {
726 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
727 goto fail_buffer_add;
728 }
729
730 /* create result node set */
731
732 exsltStrReturnString(ctxt, xmlBufferContent(buf), xmlBufferLength(buf));
733
734 /* clean up */
735
736 fail_buffer_add:
737 xmlBufferFree(buf);
738
739 fail_buffer:
740 fail_process_args:
741 if (search_set != NULL) {
742 for (i=0; i<n; ++i)
743 xmlFree(search[i]);
744 }
745 if (replace_set != NULL) {
746 for (i=0; i<n; ++i) {
747 if (replace[i] != NULL)
748 xmlFree(replace[i]);
749 }
750 }
751
752 if (mem != NULL)
753 xmlFree(mem);
754
755 fail_malloc:
756 done_empty_search:
757 xmlFree(string);
758
759 fail_string:
760 if (search_set != NULL)
761 xmlXPathFreeNodeSet(search_set);
762 else
763 xmlFree(search_str);
764
765 fail_search:
766 if (replace_set != NULL)
767 xmlXPathFreeNodeSet(replace_set);
768 else
769 xmlFree(replace_str);
770
771 fail_replace:
772 return;
641 } 773 }
642 774
643 /** 775 /**
644 * exsltStrRegister: 776 * exsltStrRegister:
645 * 777 *
646 * Registers the EXSLT - Strings module 778 * Registers the EXSLT - Strings module
647 */ 779 */
648 780
649 void 781 void
650 exsltStrRegister (void) { 782 exsltStrRegister (void) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, 840 (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
709 exsltStrConcatFunction) 841 exsltStrConcatFunction)
710 && !xmlXPathRegisterFuncNS(ctxt, 842 && !xmlXPathRegisterFuncNS(ctxt,
711 (const xmlChar *) "replace", 843 (const xmlChar *) "replace",
712 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, 844 (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
713 exsltStrReplaceFunction)) { 845 exsltStrReplaceFunction)) {
714 return 0; 846 return 0;
715 } 847 }
716 return -1; 848 return -1;
717 } 849 }
OLDNEW
« no previous file with comments | « third_party/libxslt/libexslt/saxon.c ('k') | third_party/libxslt/libxslt.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698