1 /* percent.c - Percent escaping
2 * Copyright (C) 2008, 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
29 /* Create a newly alloced string from STRING with all spaces and
30 control characters converted to plus signs or %xx sequences. The
31 function returns the new string or NULL in case of a malloc
34 Note that we also escape the quote character to work around a bug
35 in the mingw32 runtime which does not correcty handle command line
36 quoting. We correctly double the quote mark when calling a program
37 (i.e. gpg-protect-tool), but the pre-main code does not notice the
38 double quote as an escaped quote. We do this also on POSIX systems
41 percent_plus_escape (const char *string
)
47 for (length
=1, s
=string
; *s
; s
++)
49 if (*s
== '+' || *s
== '\"' || *s
== '%'
50 || *(const unsigned char *)s
< 0x20)
56 buffer
= p
= xtrymalloc (length
);
60 for (s
=string
; *s
; s
++)
62 if (*s
== '+' || *s
== '\"' || *s
== '%'
63 || *(const unsigned char *)s
< 0x20)
65 snprintf (p
, 4, "%%%02X", *(unsigned char *)s
);
80 /* Do the percent and plus/space unescaping from STRING to BUFFER and
81 return the length of the valid buffer. Plus unescaping is only
82 done if WITHPLUS is true. An escaped Nul character will be
83 replaced by NULREPL. */
85 do_unescape (unsigned char *buffer
, const unsigned char *string
,
86 int withplus
, int nulrepl
)
88 unsigned char *p
= buffer
;
92 if (*string
== '%' && string
[1] && string
[2])
100 else if (*string
== '+' && withplus
)
112 /* Count space required after unescaping STRING. Note that this will
113 never be larger than strlen (STRING). */
115 count_unescape (const unsigned char *string
)
121 if (*string
== '%' && string
[1] && string
[2])
136 do_plus_or_plain_unescape (const char *string
, int withplus
, int nulrepl
)
141 nbytes
= count_unescape (string
);
142 newstring
= xtrymalloc (nbytes
+1);
145 n
= do_unescape (newstring
, string
, withplus
, nulrepl
);
146 assert (n
== nbytes
);
153 /* Create a new allocated string from STRING with all "%xx" sequences
154 decoded and all plus signs replaced by a space. Embedded Nul
155 characters are replaced by the value of NULREPL. The function
156 returns the new string or NULL in case of a malloc failure. */
158 percent_plus_unescape (const char *string
, int nulrepl
)
160 return do_plus_or_plain_unescape (string
, 1, nulrepl
);
164 /* Create a new allocated string from STRING with all "%xx" sequences
165 decoded. Embedded Nul characters are replaced by the value of
166 NULREPL. The function returns the new string or NULL in case of a
169 percent_unescape (const char *string
, int nulrepl
)
171 return do_plus_or_plain_unescape (string
, 0, nulrepl
);
176 do_unescape_inplace (char *string
, int withplus
, int nulrepl
)
178 unsigned char *p
, *p0
;
183 if (*string
== '%' && string
[1] && string
[2])
186 *p
= xtoi_2 (string
);
191 else if (*string
== '+' && withplus
)
203 /* Perform percent and plus unescaping in STRING and return the new
204 valid length of the string. Embedded Nul characters are replaced
205 by the value of NULREPL. A terminating Nul character is not
206 inserted; the caller might want to call this function this way:
208 foo[percent_plus_unescape_inplace (foo, 0)] = 0;
211 percent_plus_unescape_inplace (char *string
, int nulrepl
)
213 return do_unescape_inplace (string
, 1, nulrepl
);
217 /* Perform percent unescaping in STRING and return the new valid
218 length of the string. Embedded Nul characters are replaced by the
219 value of NULREPL. A terminating Nul character is not inserted; the
220 caller might want to call this function this way:
222 foo[percent_unescape_inplace (foo, 0)] = 0;
225 percent_unescape_inplace (char *string
, int nulrepl
)
227 return do_unescape_inplace (string
, 0, nulrepl
);