strescape.c revision 4d3e576109a91270c04821f8d727cd1afec8c801
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch/*
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch Copyright (c) 2003 Timo Sirainen
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch Permission is hereby granted, free of charge, to any person obtaining
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch a copy of this software and associated documentation files (the
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch "Software"), to deal in the Software without restriction, including
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch without limitation the rights to use, copy, modify, merge, publish,
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch distribute, sublicense, and/or sell copies of the Software, and to
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch permit persons to whom the Software is furnished to do so, subject to
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch the following conditions:
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch The above copyright notice and this permission notice shall be
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch included in all copies or substantial portions of the Software.
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch*/
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch#include "lib.h"
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch#include "str.h"
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch#include "strescape.h"
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Boschconst char *str_escape(const char *str)
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch{
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch char *ret, *p;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen size_t i, esc;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen /* get length of string and number of chars to escape */
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch esc = 0;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch for (i = 0; str[i] != '\0'; i++) {
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch if (IS_ESCAPED_CHAR(str[i]))
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch esc++;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch }
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch if (esc == 0)
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch return str;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch /* @UNSAFE: escape them */
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch p = ret = t_malloc(i + esc + 1);
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch for (; *str != '\0'; str++) {
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch if (IS_ESCAPED_CHAR(*str))
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch *p++ = '\\';
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch *p++ = *str;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch }
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch *p = '\0';
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch return ret;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch}
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Boschvoid str_append_unescaped(string_t *dest, const void *src, size_t src_size)
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch{
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch const unsigned char *src_c = src;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch size_t start = 0, i = 0;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch while (i < src_size) {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen start = i;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen for (; i < src_size; i++) {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen if (src_c[i] == '\\')
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen break;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen }
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen str_append_n(dest, src_c + start, i-start);
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen if (src_c[i] == '\\')
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen i++;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch start = i;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch }
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch}
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Boschchar *str_unescape(char *str)
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch{
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch /* @UNSAFE */
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch char *dest, *start = str;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch while (*str != '\\') {
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch if (*str == '\0')
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch return start;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch str++;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch }
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch for (dest = str; *str != '\0'; str++) {
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch if (*str != '\\' || str[1] == '\0')
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch *dest++ = *str;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch }
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch *dest = '\0';
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch return start;
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch}
0fe2992e4d09f3ae4cceea88c9871c832d67b461Stephan Bosch