Last active
August 29, 2015 14:16
-
-
Save jsenin/0d7bf185a54f09c3c793 to your computer and use it in GitHub Desktop.
mate-desktop pluma uri decode problem poc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* compile gcc `pkg-config --cflags gtk+-3.0` -o pluma-uri-decode pluma-uri-decode.c `pkg-config --libs gtk+-3.0` | |
* execute: | |
* ./pluma-uri-decode file:///tmp/pluma/pluma-1.8.1+dfsg1/pluma/pluma-window.c | |
* | |
* running as user will enter at mount part and not show uri, only a mount_name | |
* running as root will not enter at mount | |
*/ | |
#include <gtk/gtk.h> | |
int | |
main (int argc, | |
char *argv[]) | |
{ | |
GFile *location; | |
GMount *mount; | |
gchar *mount_name; | |
gchar *uri; | |
gtk_init (&argc, &argv); | |
location = g_file_new_for_uri ( argv[1] ); | |
uri = g_file_get_parse_name (location); | |
mount = g_file_find_enclosing_mount (location, NULL, NULL); | |
if (mount != NULL) | |
{ | |
mount_name = g_mount_get_name (mount); | |
g_message("is mount %s %s", mount_name, uri ); | |
gchar *path; | |
/* obtain the "path" patrt of the uri */ | |
if (pluma_utils_decode_uri (uri, | |
NULL, NULL, | |
NULL, NULL, | |
&path)) | |
{ | |
g_message("decode ok %s %s", uri , path ); | |
} | |
} | |
g_message("end"); | |
return 0; | |
} | |
static void | |
null_ptr (gchar **ptr) | |
{ | |
if (ptr) | |
*ptr = NULL; | |
} | |
/** | |
* pluma_utils_decode_uri: | |
* @uri: the uri to decode | |
* @scheme: return value pointer for the uri's scheme (e.g. http, sftp, ...) | |
* @user: return value pointer for the uri user info | |
* @port: return value pointer for the uri port | |
* @host: return value pointer for the uri host | |
* @path: return value pointer for the uri path | |
* | |
* Parse and break an uri apart in its individual components like the uri | |
* scheme, user info, port, host and path. The return value pointer can be | |
* NULL to ignore certain parts of the uri. If the function returns TRUE, then | |
* all return value pointers should be freed using g_free | |
* | |
* Return value: TRUE if the uri could be properly decoded, FALSE otherwise. | |
*/ | |
gboolean | |
pluma_utils_decode_uri (const gchar *uri, | |
gchar **scheme, | |
gchar **user, | |
gchar **host, | |
gchar **port, | |
gchar **path | |
) | |
{ | |
/* Largely copied from glib/gio/gdummyfile.c:_g_decode_uri. This | |
* functionality should be in glib/gio, but for now we implement it | |
* ourselves (see bug #546182) */ | |
const char *p, *in, *hier_part_start, *hier_part_end; | |
char *out; | |
char c; | |
/* From RFC 3986 Decodes: | |
* URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] | |
*/ | |
p = uri; | |
null_ptr (scheme); | |
null_ptr (user); | |
null_ptr (port); | |
null_ptr (host); | |
null_ptr (path); | |
/* Decode scheme: | |
* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) | |
*/ | |
g_message("decoding1"); | |
if (!g_ascii_isalpha (*p)){ | |
g_message("byebye %s",p); | |
return FALSE; | |
} | |
while (1) | |
{ | |
c = *p++; | |
if (c == ':') | |
break; | |
if (!(g_ascii_isalnum(c) || | |
c == '+' || | |
c == '-' || | |
c == '.')) | |
return FALSE; | |
} | |
if (scheme) | |
{ | |
*scheme = g_malloc (p - uri); | |
out = *scheme; | |
for (in = uri; in < p - 1; in++) | |
*out++ = g_ascii_tolower (*in); | |
*out = '\0'; | |
} | |
hier_part_start = p; | |
hier_part_end = p + strlen (p); | |
if (hier_part_start[0] == '/' && hier_part_start[1] == '/') | |
{ | |
const char *authority_start, *authority_end; | |
const char *userinfo_start, *userinfo_end; | |
const char *host_start, *host_end; | |
const char *port_start; | |
authority_start = hier_part_start + 2; | |
/* authority is always followed by / or nothing */ | |
authority_end = memchr (authority_start, '/', hier_part_end - authority_start); | |
if (authority_end == NULL) | |
authority_end = hier_part_end; | |
/* 3.2: | |
* authority = [ userinfo "@" ] host [ ":" port ] | |
*/ | |
userinfo_end = memchr (authority_start, '@', authority_end - authority_start); | |
if (userinfo_end) | |
{ | |
userinfo_start = authority_start; | |
if (user) | |
*user = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL); | |
if (user && *user == NULL) | |
{ | |
if (scheme) | |
g_free (*scheme); | |
return FALSE; | |
} | |
host_start = userinfo_end + 1; | |
} | |
else | |
host_start = authority_start; | |
port_start = memchr (host_start, ':', authority_end - host_start); | |
if (port_start) | |
{ | |
host_end = port_start++; | |
if (port) | |
*port = g_strndup (port_start, authority_end - port_start); | |
} | |
else | |
host_end = authority_end; | |
if (host) | |
*host = g_strndup (host_start, host_end - host_start); | |
hier_part_start = authority_end; | |
} | |
if (path) | |
*path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/"); | |
return TRUE; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment