summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvagrant <[email protected]>2016-10-12 07:53:16 +0000
committerraveit65 <[email protected]>2019-01-09 20:05:00 +0100
commit5543711e5c6667e5da4b7c5e2f7504e12fc9ee6d (patch)
tree341d41aa4731f4a8520002e86fcac97ceefd29b6 /src
parent991a851ec15fc2bb31a37ccb7ca36e46f18828fb (diff)
downloadcaja-dropbox-5543711e5c6667e5da4b7c5e2f7504e12fc9ee6d.tar.bz2
caja-dropbox-5543711e5c6667e5da4b7c5e2f7504e12fc9ee6d.tar.xz
Avoid reading or writing invalid memory addresses
origin commit: https://github.com/dropbox/nautilus-dropbox/commit/122b941 https://github.com/dropbox/nautilus-dropbox/pull/25
Diffstat (limited to 'src')
-rw-r--r--src/caja-dropbox.c58
1 files changed, 46 insertions, 12 deletions
diff --git a/src/caja-dropbox.c b/src/caja-dropbox.c
index 3d512d5..c0ffad5 100644
--- a/src/caja-dropbox.c
+++ b/src/caja-dropbox.c
@@ -53,11 +53,21 @@ gboolean dropbox_use_operation_in_progress_workaround;
static GType dropbox_type = 0;
-/* probably my favorite function */
+/*
+ Simplifies a path by removing navigation elements such as '.' and '..'
+
+ Arguments:
+ - path: input path to be canonicalized
+
+ Returns:
+ Canonicalized path if input path is valid.
+ NULL otherwise.
+*/
static gchar *
canonicalize_path(gchar *path) {
int i, j = 0;
- gchar *toret, **cpy, **elts;
+ gchar *toret = NULL;
+ gchar **cpy, **elts;
g_assert(path != NULL);
g_assert(path[0] == '/');
@@ -67,7 +77,14 @@ canonicalize_path(gchar *path) {
cpy[j++] = "/";
for (i = 0; elts[i] != NULL; i++) {
if (strcmp(elts[i], "..") == 0) {
- j--;
+ if (j > 0) {
+ j--;
+ }
+ else {
+ // Input path has too many parent directory references and is invalid
+ toret = NULL;
+ goto exit;
+ }
}
else if (strcmp(elts[i], ".") != 0 && elts[i][0] != '\0') {
cpy[j++] = elts[i];
@@ -76,6 +93,8 @@ canonicalize_path(gchar *path) {
cpy[j] = NULL;
toret = g_build_filenamev(cpy);
+
+exit:
g_free(cpy);
g_strfreev(elts);
@@ -128,6 +147,10 @@ changed_cb(CajaFileInfo *file, CajaDropbox *cvs) {
uri = caja_file_info_get_uri(file);
pfilename = g_filename_from_uri(uri, NULL, NULL);
filename = pfilename ? canonicalize_path(pfilename) : NULL;
+
+ /* Canonicalization will only null-out a non-null filename if it is invalid */
+ g_assert((pfilename == NULL && filename == NULL) || (pfilename != NULL && filename != NULL));
+
filename2 = g_hash_table_lookup(cvs->obj2filename, file);
g_free(pfilename);
@@ -204,6 +227,10 @@ caja_dropbox_update_file_info(CajaInfoProvider *provider,
filename = canonicalize_path(pfilename);
g_free(pfilename);
+ if (filename == NULL) {
+ /* pfilename path was invalid if canonicalize operation nulled it out */
+ return CAJA_OPERATION_FAILED;
+ }
stored_filename = g_hash_table_lookup(cvs->obj2filename, file);
/* don't worry about the dup checks, gcc is smart enough to optimize this
@@ -286,16 +313,17 @@ handle_shell_touch(GHashTable *args, CajaDropbox *cvs) {
gchar *filename;
filename = canonicalize_path(path[0]);
+ if (filename != NULL) {
+ debug("shell touch for %s", filename);
- debug("shell touch for %s", filename);
-
- file = g_hash_table_lookup(cvs->filename2obj, filename);
+ file = g_hash_table_lookup(cvs->filename2obj, filename);
- if (file != NULL) {
- debug("gonna reset %s", filename);
- reset_file(file);
+ if (file != NULL) {
+ debug("gonna reset %s", filename);
+ reset_file(file);
+ }
+ g_free(filename);
}
- g_free(filename);
}
return;
@@ -481,8 +509,14 @@ int GhettoURLDecode(gchar* out, gchar* in, int n) {
for(out_initial = out; out-out_initial < n && *in != '\0'; out++) {
if (*in == '%') {
- *out = from_hex(in[1]) << 4 | from_hex(in[2]);
- in += 3;
+ if ((in[1] != '\0') && (in[2] != '\0')) {
+ *out = from_hex(in[1]) << 4 | from_hex(in[2]);
+ in += 3;
+ }
+ else {
+ // Input string isn't well-formed
+ return -1;
+ }
}
else {
*out = *in;