* Given a string, replace any bare " with \" . */
| 2522 | * Given a string, replace any bare " with \" . |
| 2523 | */ |
| 2524 | AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring) |
| 2525 | { |
| 2526 | apr_size_t size, extra = 0; |
| 2527 | const char *inchr = instring; |
| 2528 | char *outchr, *outstring; |
| 2529 | |
| 2530 | /* |
| 2531 | * Look through the input string, jogging the length of the output |
| 2532 | * string up by an extra byte each time we find an unescaped ". |
| 2533 | */ |
| 2534 | while (*inchr != '\0') { |
| 2535 | if (*inchr == '"') { |
| 2536 | extra++; |
| 2537 | } |
| 2538 | /* |
| 2539 | * If we find a slosh, and it's not the last byte in the string, |
| 2540 | * it's escaping something - advance past both bytes. |
| 2541 | */ |
| 2542 | else if ((*inchr == '\\') && (inchr[1] != '\0')) { |
| 2543 | inchr++; |
| 2544 | } |
| 2545 | inchr++; |
| 2546 | } |
| 2547 | |
| 2548 | if (!extra) { |
| 2549 | return apr_pstrdup(p, instring); |
| 2550 | } |
| 2551 | |
| 2552 | /* How large will the string become, once we escaped all the quotes? |
| 2553 | * The tricky cases are |
| 2554 | * - an `instring` that is already longer than `ptrdiff_t` |
| 2555 | * can hold (which is an undefined case in C, as C defines ptrdiff_t as |
| 2556 | * a signed difference between pointers into the same array and one index |
| 2557 | * beyond). |
| 2558 | * - an `instring` that, including the `extra` chars we want to add, becomes |
| 2559 | * even larger than apr_size_t can handle. |
| 2560 | * Since this function was not designed to ever return NULL for failure, we |
| 2561 | * can only trigger a hard assertion failure. It seems more a programming |
| 2562 | * mistake (or failure to verify the input causing this) that leads to this |
| 2563 | * situation. |
| 2564 | */ |
| 2565 | ap_assert(inchr - instring > 0); |
| 2566 | size = ((apr_size_t)(inchr - instring)) + 1; |
| 2567 | ap_assert(size + extra > size); |
| 2568 | |
| 2569 | outstring = apr_palloc(p, size + extra); |
| 2570 | inchr = instring; |
| 2571 | outchr = outstring; |
| 2572 | /* |
| 2573 | * Now copy the input string to the output string, inserting a slosh |
| 2574 | * in front of every " that doesn't already have one. |
| 2575 | */ |
| 2576 | while (*inchr != '\0') { |
| 2577 | if (*inchr == '"') { |
| 2578 | *outchr++ = '\\'; |
| 2579 | } |
| 2580 | else if ((*inchr == '\\') && (inchr[1] != '\0')) { |
| 2581 | *outchr++ = *inchr++; |
no outgoing calls
no test coverage detected