Skip to content

Commit b8313b5

Browse files
committed
xpath: Rewrite substring-before and substring-after
Don't use buffers. Check malloc failures.
1 parent 3874e5d commit b8313b5

File tree

3 files changed

+73
-46
lines changed

3 files changed

+73
-46
lines changed

result/XPath/expr/strings

+16
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,22 @@ Object is a string : 12
143143
Expression: substring("12345",-5000000000,5000000004)
144144
Object is a string : 123
145145

146+
========================
147+
Expression: substring-after("12345678","345")
148+
Object is a string : 678
149+
150+
========================
151+
Expression: substring-after("12345678","999")
152+
Object is a string :
153+
154+
========================
155+
Expression: substring-before("12345678","345")
156+
Object is a string : 12
157+
158+
========================
159+
Expression: substring-before("12345678","999")
160+
Object is a string :
161+
146162
========================
147163
Expression: string-length("")
148164
Object is a number : 0

test/XPath/expr/strings

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ substring("12345",-1 div 0, 1 div 0)
3434
substring("12345",-1 div 0,5)
3535
substring("12345",-0.7,4)
3636
substring("12345",-5000000000,5000000004)
37+
substring-after("12345678","345")
38+
substring-after("12345678","999")
39+
substring-before("12345678","345")
40+
substring-before("12345678","999")
3741
string-length("")
3842
string-length("titi")
3943
normalize-space(" abc def ")

xpath.c

+53-46
Original file line numberDiff line numberDiff line change
@@ -8141,30 +8141,34 @@ xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
81418141
*/
81428142
void
81438143
xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8144-
xmlXPathObjectPtr str;
8145-
xmlXPathObjectPtr find;
8146-
xmlBufPtr target;
8147-
const xmlChar *point;
8148-
int offset;
8149-
8150-
CHECK_ARITY(2);
8151-
CAST_TO_STRING;
8152-
find = valuePop(ctxt);
8153-
CAST_TO_STRING;
8154-
str = valuePop(ctxt);
8155-
8156-
target = xmlBufCreate();
8157-
if (target) {
8144+
xmlXPathObjectPtr str = NULL;
8145+
xmlXPathObjectPtr find = NULL;
8146+
const xmlChar *point;
8147+
xmlChar *result;
8148+
8149+
CHECK_ARITY(2);
8150+
CAST_TO_STRING;
8151+
find = valuePop(ctxt);
8152+
CAST_TO_STRING;
8153+
str = valuePop(ctxt);
8154+
if (ctxt->error != 0)
8155+
goto error;
8156+
81588157
point = xmlStrstr(str->stringval, find->stringval);
8159-
if (point) {
8160-
offset = point - str->stringval;
8161-
xmlBufAdd(target, str->stringval, offset);
8158+
if (point == NULL) {
8159+
result = xmlStrdup(BAD_CAST "");
8160+
} else {
8161+
result = xmlStrndup(str->stringval, point - str->stringval);
81628162
}
8163-
valuePush(ctxt, xmlXPathCacheNewString(ctxt, xmlBufContent(target)));
8164-
xmlBufFree(target);
8165-
}
8166-
xmlXPathReleaseObject(ctxt->context, str);
8167-
xmlXPathReleaseObject(ctxt->context, find);
8163+
if (result == NULL) {
8164+
xmlXPathPErrMemory(ctxt);
8165+
goto error;
8166+
}
8167+
valuePush(ctxt, xmlXPathCacheWrapString(ctxt, result));
8168+
8169+
error:
8170+
xmlXPathReleaseObject(ctxt->context, str);
8171+
xmlXPathReleaseObject(ctxt->context, find);
81688172
}
81698173

81708174
/**
@@ -8176,38 +8180,41 @@ xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
81768180
* string substring-after(string, string)
81778181
* The substring-after function returns the substring of the first
81788182
* argument string that follows the first occurrence of the second
8179-
* argument string in the first argument string, or the empty stringi
8183+
* argument string in the first argument string, or the empty string
81808184
* if the first argument string does not contain the second argument
81818185
* string. For example, substring-after("1999/04/01","/") returns 04/01,
81828186
* and substring-after("1999/04/01","19") returns 99/04/01.
81838187
*/
81848188
void
81858189
xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8186-
xmlXPathObjectPtr str;
8187-
xmlXPathObjectPtr find;
8188-
xmlBufPtr target;
8189-
const xmlChar *point;
8190-
int offset;
8191-
8192-
CHECK_ARITY(2);
8193-
CAST_TO_STRING;
8194-
find = valuePop(ctxt);
8195-
CAST_TO_STRING;
8196-
str = valuePop(ctxt);
8197-
8198-
target = xmlBufCreate();
8199-
if (target) {
8190+
xmlXPathObjectPtr str = NULL;
8191+
xmlXPathObjectPtr find = NULL;
8192+
const xmlChar *point;
8193+
xmlChar *result;
8194+
8195+
CHECK_ARITY(2);
8196+
CAST_TO_STRING;
8197+
find = valuePop(ctxt);
8198+
CAST_TO_STRING;
8199+
str = valuePop(ctxt);
8200+
if (ctxt->error != 0)
8201+
goto error;
8202+
82008203
point = xmlStrstr(str->stringval, find->stringval);
8201-
if (point) {
8202-
offset = point - str->stringval + xmlStrlen(find->stringval);
8203-
xmlBufAdd(target, &str->stringval[offset],
8204-
xmlStrlen(str->stringval) - offset);
8204+
if (point == NULL) {
8205+
result = xmlStrdup(BAD_CAST "");
8206+
} else {
8207+
result = xmlStrdup(point + xmlStrlen(find->stringval));
82058208
}
8206-
valuePush(ctxt, xmlXPathCacheNewString(ctxt, xmlBufContent(target)));
8207-
xmlBufFree(target);
8208-
}
8209-
xmlXPathReleaseObject(ctxt->context, str);
8210-
xmlXPathReleaseObject(ctxt->context, find);
8209+
if (result == NULL) {
8210+
xmlXPathPErrMemory(ctxt);
8211+
goto error;
8212+
}
8213+
valuePush(ctxt, xmlXPathCacheWrapString(ctxt, result));
8214+
8215+
error:
8216+
xmlXPathReleaseObject(ctxt->context, str);
8217+
xmlXPathReleaseObject(ctxt->context, find);
82118218
}
82128219

82138220
/**

0 commit comments

Comments
 (0)