* xmlXPathTranslateFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the translate() XPath function * string translate(string, string, string) * The translate function returns the first argument string with * occurrences of characters in the second argument string replaced * by the character at the corresponding position in the third argument
| 8293 | * argument string, then excess characters are ignored. |
| 8294 | */ |
| 8295 | void |
| 8296 | xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) { |
| 8297 | xmlXPathObjectPtr str = NULL; |
| 8298 | xmlXPathObjectPtr from = NULL; |
| 8299 | xmlXPathObjectPtr to = NULL; |
| 8300 | xmlBufPtr target; |
| 8301 | int offset, max; |
| 8302 | int ch; |
| 8303 | const xmlChar *point; |
| 8304 | xmlChar *cptr, *content; |
| 8305 | |
| 8306 | CHECK_ARITY(3); |
| 8307 | |
| 8308 | CAST_TO_STRING; |
| 8309 | to = valuePop(ctxt); |
| 8310 | CAST_TO_STRING; |
| 8311 | from = valuePop(ctxt); |
| 8312 | CAST_TO_STRING; |
| 8313 | str = valuePop(ctxt); |
| 8314 | if (ctxt->error != 0) |
| 8315 | goto error; |
| 8316 | |
| 8317 | /* |
| 8318 | * Account for quadratic runtime |
| 8319 | */ |
| 8320 | if (ctxt->context->opLimit != 0) { |
| 8321 | unsigned long f1 = xmlStrlen(from->stringval); |
| 8322 | unsigned long f2 = xmlStrlen(str->stringval); |
| 8323 | |
| 8324 | if ((f1 > 0) && (f2 > 0)) { |
| 8325 | unsigned long p; |
| 8326 | |
| 8327 | f1 = f1 / 10 + 1; |
| 8328 | f2 = f2 / 10 + 1; |
| 8329 | p = f1 > ULONG_MAX / f2 ? ULONG_MAX : f1 * f2; |
| 8330 | if (xmlXPathCheckOpLimit(ctxt, p) < 0) |
| 8331 | goto error; |
| 8332 | } |
| 8333 | } |
| 8334 | |
| 8335 | target = xmlBufCreateSize(64); |
| 8336 | if (target == NULL) { |
| 8337 | xmlXPathPErrMemory(ctxt); |
| 8338 | goto error; |
| 8339 | } |
| 8340 | |
| 8341 | max = xmlUTF8Strlen(to->stringval); |
| 8342 | for (cptr = str->stringval; (ch=*cptr); ) { |
| 8343 | offset = xmlUTF8Strloc(from->stringval, cptr); |
| 8344 | if (offset >= 0) { |
| 8345 | if (offset < max) { |
| 8346 | point = xmlUTF8Strpos(to->stringval, offset); |
| 8347 | if (point) |
| 8348 | xmlBufAdd(target, point, xmlUTF8Strsize(point, 1)); |
| 8349 | } |
| 8350 | } else |
| 8351 | xmlBufAdd(target, cptr, xmlUTF8Strsize(cptr, 1)); |
| 8352 |
nothing calls this directly
no test coverage detected