diff --git a/result/XPath/expr/strings b/result/XPath/expr/strings index 5527b506..9da0b8ed 100644 --- a/result/XPath/expr/strings +++ b/result/XPath/expr/strings @@ -143,6 +143,22 @@ Object is a string : 12 Expression: substring("12345",-5000000000,5000000004) Object is a string : 123 +======================== +Expression: substring-after("12345678","345") +Object is a string : 678 + +======================== +Expression: substring-after("12345678","999") +Object is a string : + +======================== +Expression: substring-before("12345678","345") +Object is a string : 12 + +======================== +Expression: substring-before("12345678","999") +Object is a string : + ======================== Expression: string-length("") Object is a number : 0 diff --git a/test/XPath/expr/strings b/test/XPath/expr/strings index ef292514..04ae15f3 100644 --- a/test/XPath/expr/strings +++ b/test/XPath/expr/strings @@ -34,6 +34,10 @@ substring("12345",-1 div 0, 1 div 0) substring("12345",-1 div 0,5) substring("12345",-0.7,4) substring("12345",-5000000000,5000000004) +substring-after("12345678","345") +substring-after("12345678","999") +substring-before("12345678","345") +substring-before("12345678","999") string-length("") string-length("titi") normalize-space(" abc def ") diff --git a/xpath.c b/xpath.c index 323e12f0..c2b0f6d0 100644 --- a/xpath.c +++ b/xpath.c @@ -8141,30 +8141,34 @@ xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) { */ void xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathObjectPtr str; - xmlXPathObjectPtr find; - xmlBufPtr target; - const xmlChar *point; - int offset; + xmlXPathObjectPtr str = NULL; + xmlXPathObjectPtr find = NULL; + const xmlChar *point; + xmlChar *result; - CHECK_ARITY(2); - CAST_TO_STRING; - find = valuePop(ctxt); - CAST_TO_STRING; - str = valuePop(ctxt); + CHECK_ARITY(2); + CAST_TO_STRING; + find = valuePop(ctxt); + CAST_TO_STRING; + str = valuePop(ctxt); + if (ctxt->error != 0) + goto error; - target = xmlBufCreate(); - if (target) { point = xmlStrstr(str->stringval, find->stringval); - if (point) { - offset = point - str->stringval; - xmlBufAdd(target, str->stringval, offset); + if (point == NULL) { + result = xmlStrdup(BAD_CAST ""); + } else { + result = xmlStrndup(str->stringval, point - str->stringval); } - valuePush(ctxt, xmlXPathCacheNewString(ctxt, xmlBufContent(target))); - xmlBufFree(target); - } - xmlXPathReleaseObject(ctxt->context, str); - xmlXPathReleaseObject(ctxt->context, find); + if (result == NULL) { + xmlXPathPErrMemory(ctxt); + goto error; + } + valuePush(ctxt, xmlXPathCacheWrapString(ctxt, result)); + +error: + xmlXPathReleaseObject(ctxt->context, str); + xmlXPathReleaseObject(ctxt->context, find); } /** @@ -8176,38 +8180,41 @@ xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { * string substring-after(string, string) * The substring-after function returns the substring of the first * argument string that follows the first occurrence of the second - * argument string in the first argument string, or the empty stringi + * argument string in the first argument string, or the empty string * if the first argument string does not contain the second argument * string. For example, substring-after("1999/04/01","/") returns 04/01, * and substring-after("1999/04/01","19") returns 99/04/01. */ void xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathObjectPtr str; - xmlXPathObjectPtr find; - xmlBufPtr target; - const xmlChar *point; - int offset; + xmlXPathObjectPtr str = NULL; + xmlXPathObjectPtr find = NULL; + const xmlChar *point; + xmlChar *result; - CHECK_ARITY(2); - CAST_TO_STRING; - find = valuePop(ctxt); - CAST_TO_STRING; - str = valuePop(ctxt); + CHECK_ARITY(2); + CAST_TO_STRING; + find = valuePop(ctxt); + CAST_TO_STRING; + str = valuePop(ctxt); + if (ctxt->error != 0) + goto error; - target = xmlBufCreate(); - if (target) { point = xmlStrstr(str->stringval, find->stringval); - if (point) { - offset = point - str->stringval + xmlStrlen(find->stringval); - xmlBufAdd(target, &str->stringval[offset], - xmlStrlen(str->stringval) - offset); + if (point == NULL) { + result = xmlStrdup(BAD_CAST ""); + } else { + result = xmlStrdup(point + xmlStrlen(find->stringval)); } - valuePush(ctxt, xmlXPathCacheNewString(ctxt, xmlBufContent(target))); - xmlBufFree(target); - } - xmlXPathReleaseObject(ctxt->context, str); - xmlXPathReleaseObject(ctxt->context, find); + if (result == NULL) { + xmlXPathPErrMemory(ctxt); + goto error; + } + valuePush(ctxt, xmlXPathCacheWrapString(ctxt, result)); + +error: + xmlXPathReleaseObject(ctxt->context, str); + xmlXPathReleaseObject(ctxt->context, find); } /**