1 /* percent.c - Percent escaping
2 * Copyright (C) 2008, 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * This file is free software; you can redistribute it and/or modify
7 * it under the terms of either
9 * - the GNU Lesser General Public License as published by the Free
10 * Software Foundation; either version 3 of the License, or (at
11 * your option) any later version.
15 * - the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at
17 * your option) any later version.
19 * or both in parallel, as here.
21 * This file is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <https://www.gnu.org/licenses/>.
39 /* Create a newly alloced string from STRING with all spaces and
40 control characters converted to plus signs or %xx sequences. The
41 function returns the new string or NULL in case of a malloc
44 Note that we also escape the quote character to work around a bug
45 in the mingw32 runtime which does not correcty handle command line
46 quoting. We correctly double the quote mark when calling a program
47 (i.e. gpg-protect-tool), but the pre-main code does not notice the
48 double quote as an escaped quote. We do this also on POSIX systems
51 percent_plus_escape (const char *string)
57 for (length=1, s=string; *s; s++)
59 if (*s == '+' || *s == '\"' || *s == '%'
60 || *(const unsigned char *)s < 0x20)
66 buffer = p = xtrymalloc (length);
70 for (s=string; *s; s++)
72 if (*s == '+' || *s == '\"' || *s == '%'
73 || *(const unsigned char *)s < 0x20)
75 snprintf (p, 4, "%%%02X", *(unsigned char *)s);
90 /* Do the percent and plus/space unescaping from STRING to BUFFER and
91 return the length of the valid buffer. Plus unescaping is only
92 done if WITHPLUS is true. An escaped Nul character will be
93 replaced by NULREPL. */
95 do_unescape (unsigned char *buffer, const unsigned char *string,
96 int withplus, int nulrepl)
98 unsigned char *p = buffer;
102 if (*string == '%' && string[1] && string[2])
105 *p = xtoi_2 (string);
110 else if (*string == '+' && withplus)
122 /* Count space required after unescaping STRING. Note that this will
123 never be larger than strlen (STRING). */
125 count_unescape (const unsigned char *string)
131 if (*string == '%' && string[1] && string[2])
146 do_plus_or_plain_unescape (const char *string, int withplus, int nulrepl)
151 nbytes = count_unescape (string);
152 newstring = xtrymalloc (nbytes+1);
155 n = do_unescape (newstring, string, withplus, nulrepl);
156 assert (n == nbytes);
163 /* Create a new allocated string from STRING with all "%xx" sequences
164 decoded and all plus signs replaced by a space. Embedded Nul
165 characters are replaced by the value of NULREPL. The function
166 returns the new string or NULL in case of a malloc failure. */
168 percent_plus_unescape (const char *string, int nulrepl)
170 return do_plus_or_plain_unescape (string, 1, nulrepl);
174 /* Create a new allocated string from STRING with all "%xx" sequences
175 decoded. Embedded Nul characters are replaced by the value of
176 NULREPL. The function returns the new string or NULL in case of a
179 percent_unescape (const char *string, int nulrepl)
181 return do_plus_or_plain_unescape (string, 0, nulrepl);
186 do_unescape_inplace (char *string, int withplus, int nulrepl)
188 unsigned char *p, *p0;
193 if (*string == '%' && string[1] && string[2])
196 *p = xtoi_2 (string);
201 else if (*string == '+' && withplus)
213 /* Perform percent and plus unescaping in STRING and return the new
214 valid length of the string. Embedded Nul characters are replaced
215 by the value of NULREPL. A terminating Nul character is not
216 inserted; the caller might want to call this function this way:
218 foo[percent_plus_unescape_inplace (foo, 0)] = 0;
221 percent_plus_unescape_inplace (char *string, int nulrepl)
223 return do_unescape_inplace (string, 1, nulrepl);
227 /* Perform percent unescaping in STRING and return the new valid
228 length of the string. Embedded Nul characters are replaced by the
229 value of NULREPL. A terminating Nul character is not inserted; the
230 caller might want to call this function this way:
232 foo[percent_unescape_inplace (foo, 0)] = 0;
235 percent_unescape_inplace (char *string, int nulrepl)
237 return do_unescape_inplace (string, 0, nulrepl);