1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-02 02:10:46 -08:00

Fix file name encodings in diagnostics

Also, close some minor races when opening image files, by opening
them once instead of multiple times.
* src/gtkutil.c (xg_get_image_for_pixmap):
* src/image.c (xpm_load, tiff_load, gif_load, imagemagick_load)
(svg_load):
* src/nsimage.m (allocInitFromFile:):
* src/xfns.c (xg_set_icon):
Encode file name, since x_find_image_file no longer does that.
* src/image.c (x_find_image_fd): New function.
(x_find_image_file): Use it.  Do not encode resulting file name,
since callers sometimes need it decoded.
(slurp_file): File arg is now a fd, not a file name.
All callers changed.  This saves us having to open the file twice.
(xbm_load, xpm_load, pbm_load, png_load_body, jpeg_load_body)
(svg_load):
Use x_find_image_fd and fdopen to save a file-open.
Report file name that failed.
* src/lread.c (openp): If PREDICATE is t, open the file in binary mode.
This commit is contained in:
Paul Eggert 2015-08-18 16:17:30 -07:00
parent 345284f5e9
commit 6367368616
5 changed files with 84 additions and 70 deletions

View file

@ -382,10 +382,11 @@ xg_get_image_for_pixmap (struct frame *f,
if (STRINGP (specified_file)
&& STRINGP (file = x_find_image_file (specified_file)))
{
char *encoded_file = SSDATA (ENCODE_FILE (file));
if (! old_widget)
old_widget = GTK_IMAGE (gtk_image_new_from_file (SSDATA (file)));
old_widget = GTK_IMAGE (gtk_image_new_from_file (encoded_file));
else
gtk_image_set_from_file (old_widget, SSDATA (file));
gtk_image_set_from_file (old_widget, encoded_file);
return GTK_WIDGET (old_widget);
}

View file

@ -2270,11 +2270,13 @@ image_unget_x_image (struct image *img, bool mask_p, XImagePtr ximg)
***********************************************************************/
/* Find image file FILE. Look in data-directory/images, then
x-bitmap-file-path. Value is the encoded full name of the file
found, or nil if not found. */
x-bitmap-file-path. Value is the full name of the file
found, or nil if not found. If PFD is nonnull store into *PFD a
readable file descriptor for the file, opened in binary mode. If
PFD is null, do not open the file. */
Lisp_Object
x_find_image_file (Lisp_Object file)
static Lisp_Object
x_find_image_fd (Lisp_Object file, int *pfd)
{
Lisp_Object file_found, search_path;
int fd;
@ -2286,29 +2288,35 @@ x_find_image_file (Lisp_Object file)
Vx_bitmap_file_path);
/* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
fd = openp (search_path, file, Qnil, &file_found, Qnil, false);
if (fd == -1)
file_found = Qnil;
else
{
file_found = ENCODE_FILE (file_found);
if (fd != -2)
emacs_close (fd);
}
fd = openp (search_path, file, Qnil, &file_found,
pfd ? Qt : make_number (R_OK), false);
if (fd < 0)
return Qnil;
if (pfd)
*pfd = fd;
return file_found;
}
/* Find image file FILE. Look in data-directory/images, then
x-bitmap-file-path. Value is the encoded full name of the file
found, or nil if not found. */
Lisp_Object
x_find_image_file (Lisp_Object file)
{
return x_find_image_fd (file, 0);
}
/* Read FILE into memory. Value is a pointer to a buffer allocated
with xmalloc holding FILE's contents. Value is null if an error
occurred. *SIZE is set to the size of the file. */
occurred. FD is a file descriptor open for reading FILE. Set
*SIZE to the size of the file. */
static unsigned char *
slurp_file (char *file, ptrdiff_t *size)
slurp_file (int fd, ptrdiff_t *size)
{
FILE *fp = emacs_fopen (file, "rb");
FILE *fp = fdopen (fd, "rb");
unsigned char *buf = NULL;
struct stat st;
@ -2980,21 +2988,19 @@ xbm_load (struct frame *f, struct image *img)
file_name = image_spec_value (img->spec, QCfile, NULL);
if (STRINGP (file_name))
{
Lisp_Object file;
unsigned char *contents;
ptrdiff_t size;
file = x_find_image_file (file_name);
int fd;
Lisp_Object file = x_find_image_fd (file_name, &fd);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
return 0;
}
contents = slurp_file (SSDATA (file), &size);
ptrdiff_t size;
unsigned char *contents = slurp_file (fd, &size);
if (contents == NULL)
{
image_error ("Error loading XBM image "uLSQM"%s"uRSQM, img->spec);
image_error ("Error loading XBM image "uLSQM"%s"uRSQM, file);
return 0;
}
@ -3640,6 +3646,7 @@ xpm_load (struct frame *f, struct image *img)
return 0;
}
file = ENCODE_FILE (file);
#ifdef HAVE_NTGUI
#ifdef WINDOWSNT
/* FILE is encoded in UTF-8, but image libraries on Windows
@ -4290,21 +4297,19 @@ xpm_load (struct frame *f,
file_name = image_spec_value (img->spec, QCfile, NULL);
if (STRINGP (file_name))
{
Lisp_Object file;
unsigned char *contents;
ptrdiff_t size;
file = x_find_image_file (file_name);
int fd;
Lisp_Object file = x_find_image_fd (file_name, &fd);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
return 0;
}
contents = slurp_file (SSDATA (file), &size);
ptrdiff_t size;
unsigned char *contents = slurp_file (fd, &size);
if (contents == NULL)
{
image_error ("Error loading XPM image "uLSQM"%s"uRSQM, img->spec);
image_error ("Error loading XPM image "uLSQM"%s"uRSQM, file);
return 0;
}
@ -5253,11 +5258,10 @@ pbm_load (struct frame *f, struct image *img)
bool raw_p;
int x, y;
int width, height, max_color_idx = 0;
Lisp_Object file, specified_file;
Lisp_Object specified_file;
enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
unsigned char *contents = NULL;
unsigned char *end, *p;
ptrdiff_t size;
#ifdef USE_CAIRO
unsigned char *data = 0;
uint32_t *dataptr;
@ -5269,7 +5273,8 @@ pbm_load (struct frame *f, struct image *img)
if (STRINGP (specified_file))
{
file = x_find_image_file (specified_file);
int fd;
Lisp_Object file = x_find_image_fd (specified_file, &fd);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@ -5277,7 +5282,8 @@ pbm_load (struct frame *f, struct image *img)
return 0;
}
contents = slurp_file (SSDATA (file), &size);
ptrdiff_t size;
contents = slurp_file (fd, &size);
if (contents == NULL)
{
image_error ("Error reading "uLSQM"%s"uRSQM, file);
@ -5878,7 +5884,7 @@ struct png_load_context
static bool
png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
{
Lisp_Object file, specified_file;
Lisp_Object specified_file;
Lisp_Object specified_data;
int x, y;
ptrdiff_t i;
@ -5909,7 +5915,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
if (NILP (specified_data))
{
file = x_find_image_file (specified_file);
int fd;
Lisp_Object file = x_find_image_fd (specified_file, &fd);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@ -5918,7 +5925,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
}
/* Open the image file. */
fp = emacs_fopen (SSDATA (file), "rb");
fp = fdopen (fd, "rb");
if (!fp)
{
image_error ("Cannot open image file "uLSQM"%s"uRSQM, file);
@ -6654,7 +6661,7 @@ static bool
jpeg_load_body (struct frame *f, struct image *img,
struct my_jpeg_error_mgr *mgr)
{
Lisp_Object file, specified_file;
Lisp_Object specified_file;
Lisp_Object specified_data;
/* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */
FILE * IF_LINT (volatile) fp = NULL;
@ -6674,7 +6681,8 @@ jpeg_load_body (struct frame *f, struct image *img,
if (NILP (specified_data))
{
file = x_find_image_file (specified_file);
int fd;
Lisp_Object file = x_find_image_fd (specified_file, &fd);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
@ -6682,7 +6690,7 @@ jpeg_load_body (struct frame *f, struct image *img,
return 0;
}
fp = emacs_fopen (SSDATA (file), "rb");
fp = fdopen (fd, "rb");
if (fp == NULL)
{
image_error ("Cannot open "uLSQM"%s"uRSQM, file);
@ -7172,7 +7180,7 @@ tiff_warning_handler (const char *title, const char *format, va_list ap)
static bool
tiff_load (struct frame *f, struct image *img)
{
Lisp_Object file, specified_file;
Lisp_Object specified_file;
Lisp_Object specified_data;
TIFF *tiff;
int width, height, x, y, count;
@ -7191,19 +7199,21 @@ tiff_load (struct frame *f, struct image *img)
if (NILP (specified_data))
{
/* Read from a file */
file = x_find_image_file (specified_file);
Lisp_Object file = x_find_image_file (specified_file);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
specified_file);
return 0;
}
Lisp_Object encoded_file = ENCODE_FILE (file);
# ifdef WINDOWSNT
file = ansi_encode_filename (file);
encoded_file = ansi_encode_filename (encoded_file);
# endif
/* Try to open the image file. */
tiff = TIFFOpen (SSDATA (file), "r");
tiff = TIFFOpen (SSDATA (encoded_file), "r");
if (tiff == NULL)
{
image_error ("Cannot open "uLSQM"%s"uRSQM, file);
@ -7605,7 +7615,6 @@ static const int interlace_increment[] = {8, 8, 4, 2};
static bool
gif_load (struct frame *f, struct image *img)
{
Lisp_Object file;
int rc, width, height, x, y, i, j;
ColorMapObject *gif_color_map;
unsigned long pixel_colors[256];
@ -7626,27 +7635,29 @@ gif_load (struct frame *f, struct image *img)
if (NILP (specified_data))
{
file = x_find_image_file (specified_file);
Lisp_Object file = x_find_image_file (specified_file);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM,
specified_file);
return 0;
}
Lisp_Object encoded_file = ENCODE_FILE (file);
#ifdef WINDOWSNT
file = ansi_encode_filename (file);
encoded_file = ansi_encode_filename (encoded_file);
#endif
/* Open the GIF file. */
#if GIFLIB_MAJOR < 5
gif = DGifOpenFileName (SSDATA (file));
gif = DGifOpenFileName (SSDATA (encoded_file));
if (gif == NULL)
{
image_error ("Cannot open "uLSQM"%s"uRSQM, file);
return 0;
}
#else
gif = DGifOpenFileName (SSDATA (file), &gif_err);
gif = DGifOpenFileName (SSDATA (encoded_file), &gif_err);
if (gif == NULL)
{
image_error ("Cannot open "uLSQM"%s"uRSQM": %s",
@ -8818,14 +8829,13 @@ imagemagick_load (struct frame *f, struct image *img)
file_name = image_spec_value (img->spec, QCfile, NULL);
if (STRINGP (file_name))
{
Lisp_Object file;
file = x_find_image_file (file_name);
Lisp_Object file = x_find_image_file (file_name);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
return 0;
}
file = ENCODE_FILE (file);
#ifdef WINDOWSNT
file = ansi_encode_filename (file);
#endif
@ -9097,11 +9107,8 @@ svg_load (struct frame *f, struct image *img)
file_name = image_spec_value (img->spec, QCfile, NULL);
if (STRINGP (file_name))
{
Lisp_Object file;
unsigned char *contents;
ptrdiff_t size;
file = x_find_image_file (file_name);
int fd;
Lisp_Object file = x_find_image_fd (file_name, &fd);
if (!STRINGP (file))
{
image_error ("Cannot find image file "uLSQM"%s"uRSQM, file_name);
@ -9109,14 +9116,16 @@ svg_load (struct frame *f, struct image *img)
}
/* Read the entire file into memory. */
contents = slurp_file (SSDATA (file), &size);
ptrdiff_t size;
unsigned char *contents = slurp_file (fd, &size);
if (contents == NULL)
{
image_error ("Error loading SVG image "uLSQM"%s"uRSQM, img->spec);
image_error ("Error loading SVG image "uLSQM"%s"uRSQM, file);
return 0;
}
/* If the file was slurped into memory properly, parse it. */
success_p = svg_load_image (f, img, contents, size, SSDATA (file));
success_p = svg_load_image (f, img, contents, size,
SSDATA (ENCODE_FILE (file)));
xfree (contents);
}
/* Else its not a file, its a lisp object. Load the image from a

View file

@ -1403,7 +1403,8 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
SUFFIXES is a list of strings containing possible suffixes.
The empty suffix is automatically added if the list is empty.
PREDICATE non-nil means don't open the files,
PREDICATE t means the files are binary.
PREDICATE non-nil and non-t means don't open the files,
just look for one that satisfies the predicate. In this case,
return 1 on success. The predicate can be a lisp function or
an integer to pass to `access' (in which case file-name-handlers
@ -1418,7 +1419,7 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
If NEWER is true, try all SUFFIXes and return the result for the
newest file that exists. Does not apply to remote files,
or if PREDICATE is specified. */
or if a non-nil and non-t PREDICATE is specified. */
int
openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
@ -1520,10 +1521,11 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
else
string = make_string (fn, fnlen);
handler = Ffind_file_name_handler (string, Qfile_exists_p);
if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
if ((!NILP (handler) || (!NILP (predicate) && !EQ (predicate, Qt)))
&& !NATNUMP (predicate))
{
bool exists;
if (NILP (predicate))
if (NILP (predicate) || EQ (predicate, Qt))
exists = !NILP (Ffile_readable_p (string));
else
{
@ -1577,7 +1579,8 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
}
else
{
fd = emacs_open (pfn, O_RDONLY, 0);
int oflags = O_RDONLY + (NILP (predicate) ? 0 : O_BINARY);
fd = emacs_open (pfn, oflags, 0);
if (fd < 0)
{
if (errno != ENOENT)

View file

@ -169,6 +169,7 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
found = x_find_image_file (file);
if (!STRINGP (found))
return nil;
found = ENCODE_FILE (found);
image = [[EmacsImage alloc] initByReferencingFile:
[NSString stringWithUTF8String: SSDATA (found)]];

View file

@ -548,7 +548,7 @@ xg_set_icon (struct frame *f, Lisp_Object file)
{
GdkPixbuf *pixbuf;
GError *err = NULL;
char *filename = SSDATA (found);
char *filename = SSDATA (ENCODE_FILE (found));
block_input ();
pixbuf = gdk_pixbuf_new_from_file (filename, &err);