/* Given a pathname @path, split it into individual entries in @out_components, * validating that it does not have backreferences (`..`) etc. */ gboolean ot_util_path_split_validate (const char *path, GPtrArray **out_components, GError **error) { if (strlen (path) > PATH_MAX) return glnx_throw (error, "Path '%s' is too long", path); g_autoptr(GPtrArray) ret_components = ot_split_string_ptrarray (path, '/'); /* Canonicalize by removing '.' and '', throw an error on .. */ for (int i = ret_components->len-1; i >= 0; i--) { const char *name = ret_components->pdata[i]; if (strcmp (name, "..") == 0) return glnx_throw (error, "Invalid uplink '..' in path %s", path); if (strcmp (name, ".") == 0 || name[0] == '\0') g_ptr_array_remove_index (ret_components, i); } ot_transfer_out_value(out_components, &ret_components); return TRUE; }
gboolean ot_util_path_split_validate (const char *path, GPtrArray **out_components, GError **error) { gboolean ret = FALSE; int i; gs_unref_ptrarray GPtrArray *ret_components = NULL; if (strlen (path) > PATH_MAX) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Path '%s' is too long", path); goto out; } ret_components = ot_split_string_ptrarray (path, '/'); /* Canonicalize by removing '.' and '', throw an error on .. */ for (i = ret_components->len-1; i >= 0; i--) { const char *name = ret_components->pdata[i]; if (strcmp (name, "..") == 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid uplink '..' in path %s", path); goto out; } if (strcmp (name, ".") == 0 || name[0] == '\0') g_ptr_array_remove_index (ret_components, i); } ret = TRUE; ot_transfer_out_value(out_components, &ret_components); out: return ret; }