* * * Extra functions not pertaining to the XPath spec * * * ************************************************************************/ * xmlXPathEscapeUriFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the escape-uri() XPath function * string escape-uri(string $str, bool $escape-reserved) * * This function applies the URI
| 13426 | * |
| 13427 | */ |
| 13428 | static void |
| 13429 | xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { |
| 13430 | xmlXPathObjectPtr str; |
| 13431 | int escape_reserved; |
| 13432 | xmlBufPtr target; |
| 13433 | xmlChar *cptr; |
| 13434 | xmlChar escape[4]; |
| 13435 | |
| 13436 | CHECK_ARITY(2); |
| 13437 | |
| 13438 | escape_reserved = xmlXPathPopBoolean(ctxt); |
| 13439 | |
| 13440 | CAST_TO_STRING; |
| 13441 | str = valuePop(ctxt); |
| 13442 | |
| 13443 | target = xmlBufCreateSize(64); |
| 13444 | |
| 13445 | escape[0] = '%'; |
| 13446 | escape[3] = 0; |
| 13447 | |
| 13448 | if (target) { |
| 13449 | for (cptr = str->stringval; *cptr; cptr++) { |
| 13450 | if ((*cptr >= 'A' && *cptr <= 'Z') || |
| 13451 | (*cptr >= 'a' && *cptr <= 'z') || |
| 13452 | (*cptr >= '0' && *cptr <= '9') || |
| 13453 | *cptr == '-' || *cptr == '_' || *cptr == '.' || |
| 13454 | *cptr == '!' || *cptr == '~' || *cptr == '*' || |
| 13455 | *cptr == '\''|| *cptr == '(' || *cptr == ')' || |
| 13456 | (*cptr == '%' && |
| 13457 | ((cptr[1] >= 'A' && cptr[1] <= 'F') || |
| 13458 | (cptr[1] >= 'a' && cptr[1] <= 'f') || |
| 13459 | (cptr[1] >= '0' && cptr[1] <= '9')) && |
| 13460 | ((cptr[2] >= 'A' && cptr[2] <= 'F') || |
| 13461 | (cptr[2] >= 'a' && cptr[2] <= 'f') || |
| 13462 | (cptr[2] >= '0' && cptr[2] <= '9'))) || |
| 13463 | (!escape_reserved && |
| 13464 | (*cptr == ';' || *cptr == '/' || *cptr == '?' || |
| 13465 | *cptr == ':' || *cptr == '@' || *cptr == '&' || |
| 13466 | *cptr == '=' || *cptr == '+' || *cptr == '$' || |
| 13467 | *cptr == ','))) { |
| 13468 | xmlBufAdd(target, cptr, 1); |
| 13469 | } else { |
| 13470 | if ((*cptr >> 4) < 10) |
| 13471 | escape[1] = '0' + (*cptr >> 4); |
| 13472 | else |
| 13473 | escape[1] = 'A' - 10 + (*cptr >> 4); |
| 13474 | if ((*cptr & 0xF) < 10) |
| 13475 | escape[2] = '0' + (*cptr & 0xF); |
| 13476 | else |
| 13477 | escape[2] = 'A' - 10 + (*cptr & 0xF); |
| 13478 | |
| 13479 | xmlBufAdd(target, &escape[0], 3); |
| 13480 | } |
| 13481 | } |
| 13482 | } |
| 13483 | valuePush(ctxt, xmlXPathCacheNewString(ctxt, xmlBufContent(target))); |
| 13484 | xmlBufFree(target); |
| 13485 | xmlXPathReleaseObject(ctxt->context, str); |
nothing calls this directly
no test coverage detected