static gchar * file_utils_unescape_uri (const gchar *escaped, gint len, const gchar *illegal_escaped_characters, gboolean ascii_must_not_be_escaped) { const gchar *in, *in_end; gchar *out, *result; gint c; if (escaped == NULL) return NULL; if (len < 0) len = strlen (escaped); result = g_malloc (len + 1); out = result; for (in = escaped, in_end = escaped + len; in < in_end; in++) { c = *in; if (c == '%') { /* catch partial escape sequences past the end of the substring */ if (in + 3 > in_end) break; c = unescape_character (in + 1); /* catch bad escape sequences and NUL characters */ if (c <= 0) break; /* catch escaped ASCII */ if (ascii_must_not_be_escaped && c <= 0x7F) break; /* catch other illegal escaped characters */ if (strchr (illegal_escaped_characters, c) != NULL) break; in += 2; } *out++ = c; } g_assert (out - result <= len); *out = '\0'; if (in != in_end) { g_free (result); return NULL; } return result; }
gboolean g_string_unescape (GString * string, const char *illegal_characters) { const char *in; char *out; gint character; if (string == NULL) { return FALSE; } for (in = out = string->str; *in != '\0'; in++) { character = *in; if (*in == HEX_ESCAPE) { character = unescape_character (in + 1); /* Check for an illegal character. We consider '\0' illegal here. */ if (character <= 0 || (illegal_characters != NULL && strchr (illegal_characters, (char) character) != NULL)) { return FALSE; } in += 2; } *out++ = (char) character; } *out = '\0'; return TRUE; }
/** * g_uri_unescape_segment: * @escaped_string: a string. * @escaped_string_end: a string. * @illegal_characters: an optional string of illegal characters not to be allowed. * * Unescapes a segment of an escaped string. * * If any of the characters in @illegal_characters or the character zero appears * as an escaped character in @escaped_string then that is an error and %NULL * will be returned. This is useful it you want to avoid for instance having a * slash being expanded in an escaped path element, which might confuse pathname * handling. * * Returns: an unescaped version of @escaped_string or %NULL on error. * The returned string should be freed when no longer needed. * * Since: 2.16 **/ char * g_uri_unescape_segment (const char *escaped_string, const char *escaped_string_end, const char *illegal_characters) { const char *in; char *out, *result; gint character; if (escaped_string == NULL) return NULL; if (escaped_string_end == NULL) escaped_string_end = escaped_string + strlen (escaped_string); result = g_malloc (escaped_string_end - escaped_string + 1); out = result; for (in = escaped_string; in < escaped_string_end; in++) { character = *in; if (*in == '%') { in++; if (escaped_string_end - in < 2) { /* Invalid escaped char (to short) */ g_free (result); return NULL; } character = unescape_character (in); /* Check for an illegal character. We consider '\0' illegal here. */ if (character <= 0 || (illegal_characters != NULL && strchr (illegal_characters, (char)character) != NULL)) { g_free (result); return NULL; } in++; /* The other char will be eaten in the loop header */ } *out++ = (char)character; } *out = '\0'; return result; }