| 2562 | */ |
| 2563 | |
| 2564 | CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW |
| 2565 | char *CPLUnescapeString(const char *pszInput, int *pnLength, int nScheme) |
| 2566 | |
| 2567 | { |
| 2568 | int iOut = 0; |
| 2569 | |
| 2570 | // TODO: Why times 4? |
| 2571 | char *pszOutput = static_cast<char *>(CPLMalloc(4 * strlen(pszInput) + 1)); |
| 2572 | pszOutput[0] = '\0'; |
| 2573 | |
| 2574 | if (nScheme == CPLES_BackslashQuotable) |
| 2575 | { |
| 2576 | for (int iIn = 0; pszInput[iIn] != '\0'; ++iIn) |
| 2577 | { |
| 2578 | if (pszInput[iIn] == '\\') |
| 2579 | { |
| 2580 | ++iIn; |
| 2581 | if (pszInput[iIn] == '\0') |
| 2582 | break; |
| 2583 | if (pszInput[iIn] == 'n') |
| 2584 | pszOutput[iOut++] = '\n'; |
| 2585 | else if (pszInput[iIn] == '0') |
| 2586 | pszOutput[iOut++] = '\0'; |
| 2587 | else |
| 2588 | pszOutput[iOut++] = pszInput[iIn]; |
| 2589 | } |
| 2590 | else |
| 2591 | { |
| 2592 | pszOutput[iOut++] = pszInput[iIn]; |
| 2593 | } |
| 2594 | } |
| 2595 | } |
| 2596 | else if (nScheme == CPLES_XML || nScheme == CPLES_XML_BUT_QUOTES) |
| 2597 | { |
| 2598 | char ch = '\0'; |
| 2599 | for (int iIn = 0; (ch = pszInput[iIn]) != '\0'; ++iIn) |
| 2600 | { |
| 2601 | if (ch != '&') |
| 2602 | { |
| 2603 | pszOutput[iOut++] = ch; |
| 2604 | } |
| 2605 | else if (STARTS_WITH_CI(pszInput + iIn, "<")) |
| 2606 | { |
| 2607 | pszOutput[iOut++] = '<'; |
| 2608 | iIn += 3; |
| 2609 | } |
| 2610 | else if (STARTS_WITH_CI(pszInput + iIn, ">")) |
| 2611 | { |
| 2612 | pszOutput[iOut++] = '>'; |
| 2613 | iIn += 3; |
| 2614 | } |
| 2615 | else if (STARTS_WITH_CI(pszInput + iIn, "&")) |
| 2616 | { |
| 2617 | pszOutput[iOut++] = '&'; |
| 2618 | iIn += 4; |
| 2619 | } |
| 2620 | else if (STARTS_WITH_CI(pszInput + iIn, "'")) |
| 2621 | { |