Commit 27a1fb87 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

fix feh_printf buffer overflows

parent 76e4af51
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
git HEAD

    * Patch by David Gowers: Add %L format code (temporary copy of filelist)
    * Fix buffer overflows in printf implementation (affects --action,
      --customlist, --index-info, --info, --thumb-title, --title)

Fri, 03 May 2013 21:16:59 +0200  Daniel Friesel <derf+feh@finalrewind.org>

* Release v2.9.2
+24 −24
Original line number Diff line number Diff line
@@ -478,116 +478,116 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid)
			switch (*c) {
			case 'f':
				if (file)
					strcat(ret, file->filename);
					strncat(ret, file->filename, sizeof(ret) - strlen(ret));
				break;
			case 'F':
				if (file)
					strcat(ret, shell_escape(file->filename));
					strncat(ret, shell_escape(file->filename), sizeof(ret) - strlen(ret));
				break;
			case 'h':
				if (file && (file->info || !feh_file_info_load(file, NULL))) {
					snprintf(buf, sizeof(buf), "%d", file->info->height);
					strcat(ret, buf);
					strncat(ret, buf, sizeof(ret) - strlen(ret));
				}
				break;
			case 'l':
				snprintf(buf, sizeof(buf), "%d", gib_list_length(filelist));
				strcat(ret, buf);
				strncat(ret, buf, sizeof(ret) - strlen(ret));
				break;
			case 'L':
				if (filelist_tmppath != NULL) {
					strcat(ret, filelist_tmppath);
					strncat(ret, filelist_tmppath, sizeof(ret) - strlen(ret));
				} else {
					filelist_tmppath = feh_unique_filename("/tmp/","filelist");
					feh_write_filelist(filelist, filelist_tmppath);
					strcat(ret, filelist_tmppath);
					strncat(ret, filelist_tmppath, sizeof(ret) - strlen(ret));
				}
				break;
			case 'm':
				strcat(ret, mode);
				strncat(ret, mode, sizeof(ret) - strlen(ret));
				break;
			case 'n':
				if (file)
					strcat(ret, file->name);
					strncat(ret, file->name, sizeof(ret) - strlen(ret));
				break;
			case 'N':
				if (file)
					strcat(ret, shell_escape(file->name));
					strncat(ret, shell_escape(file->name), sizeof(ret) - strlen(ret));
				break;
			case 'o':
				if (winwid) {
					snprintf(buf, sizeof(buf), "%d,%d", winwid->im_x,
						winwid->im_y);
					strcat(ret, buf);
					strncat(ret, buf, sizeof(ret) - strlen(ret));
				}
				break;
			case 'p':
				if (file && (file->info || !feh_file_info_load(file, NULL))) {
					snprintf(buf, sizeof(buf), "%d", file->info->pixels);
					strcat(ret, buf);
					strncat(ret, buf, sizeof(ret) - strlen(ret));
				}
				break;
			case 'P':
				if (file && (file->info || !feh_file_info_load(file, NULL))) {
					strcat(ret, format_size(file->info->pixels));
					strncat(ret, format_size(file->info->pixels), sizeof(ret) - strlen(ret));
				}
				break;
			case 'r':
				if (winwid) {
					snprintf(buf, sizeof(buf), "%.1f", winwid->im_angle);
					strcat(ret, buf);
					strncat(ret, buf, sizeof(ret) - strlen(ret));
				}
				break;
			case 's':
				if (file && (file->info || !feh_file_info_load(file, NULL))) {
					snprintf(buf, sizeof(buf), "%d", file->info->size);
					strcat(ret, buf);
					strncat(ret, buf, sizeof(ret) - strlen(ret));
				}
				break;
			case 'S':
				if (file && (file->info || !feh_file_info_load(file, NULL))) {
					strcat(ret, format_size(file->info->size));
					strncat(ret, format_size(file->info->size), sizeof(ret) - strlen(ret));
				}
				break;
			case 't':
				if (file && (file->info || !feh_file_info_load(file, NULL))) {
					strcat(ret, file->info->format);
					strncat(ret, file->info->format, sizeof(ret) - strlen(ret));
				}
				break;
			case 'u':
				snprintf(buf, sizeof(buf), "%d",
					 current_file != NULL ? gib_list_num(filelist, current_file)
					 + 1 : 0);
				strcat(ret, buf);
				strncat(ret, buf, sizeof(ret) - strlen(ret));
				break;
			case 'v':
				strcat(ret, VERSION);
				strncat(ret, VERSION, sizeof(ret) - strlen(ret));
				break;
			case 'V':
				snprintf(buf, sizeof(buf), "%d", getpid());
				strcat(ret, buf);
				strncat(ret, buf, sizeof(ret) - strlen(ret));
				break;
			case 'w':
				if (file && (file->info || !feh_file_info_load(file, NULL))) {
					snprintf(buf, sizeof(buf), "%d", file->info->width);
					strcat(ret, buf);
					strncat(ret, buf, sizeof(ret) - strlen(ret));
				}
				break;
			case 'z':
				if (winwid) {
					snprintf(buf, sizeof(buf), "%.2f", winwid->zoom);
					strcat(ret, buf);
					strncat(ret, buf, sizeof(ret) - strlen(ret));
				}
				break;
			case '%':
				strcat(ret, "%");
				strncat(ret, "%", sizeof(ret) - strlen(ret));
				break;
			default:
				weprintf("Unrecognized format specifier %%%c", *c);
				strncat(ret, c - 1, 2);
				break;
			}
		} else if ((*c == '\\') && (*(c+1) != '\0')) {
		} else if ((*c == '\\') && (*(c+1) != '\0') && ((strlen(ret) + 3) < sizeof(ret))) {
			c++;
			switch (*c) {
			case 'n':
@@ -597,7 +597,7 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid)
				strncat(ret, c - 1, 2);
				break;
			}
		} else
		} else if ((strlen(ret) + 2) < sizeof(ret))
			strncat(ret, c, 1);
	}
	if (filelist_tmppath != NULL)