Compare commits
	
		
			2 Commits
		
	
	
		
			701846ab39
			...
			4e11970a7e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4e11970a7e | |||
| ae0b5506ab | 
| @ -729,17 +729,6 @@ thumbnailers_start(FivBrowser *self) | |||||||
| 	if (!self->model) | 	if (!self->model) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	// TODO(p): Leave out all paths containing .cache/thumbnails altogether.
 |  | ||||||
| 	gchar *thumbnails_dir = fiv_thumbnail_get_root(); |  | ||||||
| 	GFile *thumbnails = g_file_new_for_path(thumbnails_dir); |  | ||||||
| 	g_free(thumbnails_dir); |  | ||||||
| 
 |  | ||||||
| 	GFile *current = fiv_io_model_get_location(self->model); |  | ||||||
| 	gboolean is_a_thumbnail = current && g_file_has_prefix(current, thumbnails); |  | ||||||
| 	g_object_unref(thumbnails); |  | ||||||
| 	if (is_a_thumbnail) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	GList *missing = NULL, *lq = NULL; | 	GList *missing = NULL, *lq = NULL; | ||||||
| 	for (guint i = self->entries->len; i--; ) { | 	for (guint i = self->entries->len; i--; ) { | ||||||
| 		Entry *entry = &g_array_index(self->entries, Entry, i); | 		Entry *entry = &g_array_index(self->entries, Entry, i); | ||||||
| @ -988,7 +977,6 @@ fiv_browser_realize(GtkWidget *widget) | |||||||
| 		attributes.event_mask |= GDK_SMOOTH_SCROLL_MASK; | 		attributes.event_mask |= GDK_SMOOTH_SCROLL_MASK; | ||||||
| 
 | 
 | ||||||
| 	// We need this window to receive input events at all.
 | 	// We need this window to receive input events at all.
 | ||||||
| 	// TODO(p): See if input events bubble up to parents.
 |  | ||||||
| 	GdkWindow *window = gdk_window_new(gtk_widget_get_parent_window(widget), | 	GdkWindow *window = gdk_window_new(gtk_widget_get_parent_window(widget), | ||||||
| 		&attributes, GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL); | 		&attributes, GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL); | ||||||
| 	gtk_widget_register_window(widget, window); | 	gtk_widget_register_window(widget, window); | ||||||
|  | |||||||
| @ -25,6 +25,7 @@ | |||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <math.h> | #include <math.h> | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
|  | #include <string.h> | ||||||
| 
 | 
 | ||||||
| #include "fiv-io.h" | #include "fiv-io.h" | ||||||
| #include "fiv-thumbnail.h" | #include "fiv-thumbnail.h" | ||||||
| @ -93,7 +94,7 @@ mark_thumbnail_lq(cairo_surface_t *surface) | |||||||
| 		surface, &fiv_thumbnail_key_lq, (void *) (intptr_t) 1, NULL); | 		surface, &fiv_thumbnail_key_lq, (void *) (intptr_t) 1, NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| gchar * | static gchar * | ||||||
| fiv_thumbnail_get_root(void) | fiv_thumbnail_get_root(void) | ||||||
| { | { | ||||||
| 	gchar *cache_dir = get_xdg_home_dir("XDG_CACHE_HOME", ".cache"); | 	gchar *cache_dir = get_xdg_home_dir("XDG_CACHE_HOME", ".cache"); | ||||||
| @ -102,6 +103,23 @@ fiv_thumbnail_get_root(void) | |||||||
| 	return thumbnails_dir; | 	return thumbnails_dir; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static gboolean | ||||||
|  | might_be_a_thumbnail(const char *path_or_uri) | ||||||
|  | { | ||||||
|  | 	// It is generally difficult to discern case in/sensitivity of subpaths,
 | ||||||
|  | 	// so err on the side of false positives.
 | ||||||
|  | 	gchar *normalized = g_ascii_strdown(path_or_uri, -1); | ||||||
|  | 
 | ||||||
|  | 	// The Windows path separator must be percent-encoded in URIs,
 | ||||||
|  | 	// and the file scheme always uses forward slashes.
 | ||||||
|  | 	if (G_DIR_SEPARATOR != '/') | ||||||
|  | 		g_strdelimit(normalized, G_DIR_SEPARATOR_S, '/'); | ||||||
|  | 
 | ||||||
|  | 	gboolean matches = strstr(normalized, "/.cache/thumbnails/") != NULL; | ||||||
|  | 	g_free(normalized); | ||||||
|  | 	return matches; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | ||||||
| 
 | 
 | ||||||
| static cairo_surface_t * | static cairo_surface_t * | ||||||
| @ -440,8 +458,10 @@ fiv_thumbnail_produce(GFile *target, FivThumbnailSize max_size, GError **error) | |||||||
| 	g_return_val_if_fail(max_size >= FIV_THUMBNAIL_SIZE_MIN && | 	g_return_val_if_fail(max_size >= FIV_THUMBNAIL_SIZE_MIN && | ||||||
| 		max_size <= FIV_THUMBNAIL_SIZE_MAX, FALSE); | 		max_size <= FIV_THUMBNAIL_SIZE_MAX, FALSE); | ||||||
| 
 | 
 | ||||||
|  | 	// Don't save thumbnails for FUSE mounts, such as sftp://.
 | ||||||
|  | 	// Moreover, it doesn't make sense to save thumbnails of thumbnails.
 | ||||||
| 	const gchar *path = g_file_peek_path(target); | 	const gchar *path = g_file_peek_path(target); | ||||||
| 	if (!path || !g_file_is_native(target) /* Don't save sftp://. */) | 	if (!path || !g_file_is_native(target) || might_be_a_thumbnail(path)) | ||||||
| 		return produce_fallback(target, max_size, error); | 		return produce_fallback(target, max_size, error); | ||||||
| 
 | 
 | ||||||
| 	// Make the TOCTTOU issue favour unnecessary reloading.
 | 	// Make the TOCTTOU issue favour unnecessary reloading.
 | ||||||
| @ -620,6 +640,11 @@ fiv_thumbnail_lookup(const char *uri, gint64 mtime_msec, FivThumbnailSize size) | |||||||
| 	g_return_val_if_fail(size >= FIV_THUMBNAIL_SIZE_MIN && | 	g_return_val_if_fail(size >= FIV_THUMBNAIL_SIZE_MIN && | ||||||
| 		size <= FIV_THUMBNAIL_SIZE_MAX, NULL); | 		size <= FIV_THUMBNAIL_SIZE_MAX, NULL); | ||||||
| 
 | 
 | ||||||
|  | 	// Don't waste time looking up something that shouldn't exist--
 | ||||||
|  | 	// thumbnail directories tend to get huge, and syscalls are expensive.
 | ||||||
|  | 	if (might_be_a_thumbnail(uri)) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
| 	gchar *sum = g_compute_checksum_for_string(G_CHECKSUM_MD5, uri, -1); | 	gchar *sum = g_compute_checksum_for_string(G_CHECKSUM_MD5, uri, -1); | ||||||
| 	gchar *thumbnails_dir = fiv_thumbnail_get_root(); | 	gchar *thumbnails_dir = fiv_thumbnail_get_root(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -52,9 +52,6 @@ extern FivThumbnailSizeInfo fiv_thumbnail_sizes[FIV_THUMBNAIL_SIZE_COUNT]; | |||||||
| /// If non-NULL, indicates a thumbnail of insufficient quality.
 | /// If non-NULL, indicates a thumbnail of insufficient quality.
 | ||||||
| extern cairo_user_data_key_t fiv_thumbnail_key_lq; | extern cairo_user_data_key_t fiv_thumbnail_key_lq; | ||||||
| 
 | 
 | ||||||
| /// Returns this user's root thumbnail directory.
 |  | ||||||
| gchar *fiv_thumbnail_get_root(void); |  | ||||||
| 
 |  | ||||||
| /// Attempts to extract any low-quality thumbnail from fast targets.
 | /// Attempts to extract any low-quality thumbnail from fast targets.
 | ||||||
| /// If `max_size` is a valid value, the image will be downscaled as appropriate.
 | /// If `max_size` is a valid value, the image will be downscaled as appropriate.
 | ||||||
| cairo_surface_t *fiv_thumbnail_extract( | cairo_surface_t *fiv_thumbnail_extract( | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user