diff options
| author | Paul Eggert | 2013-07-19 11:09:23 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-19 11:09:23 -0700 |
| commit | 3f5bef16fab0ba83cb2298f8137fec831af1aec4 (patch) | |
| tree | 8f825fe5834080db213452ee3bb1b291f1923a6d /src/image.c | |
| parent | 4195afc389bb0e5ed5aa749e7606a710e07a72d1 (diff) | |
| download | emacs-3f5bef16fab0ba83cb2298f8137fec831af1aec4.tar.gz emacs-3f5bef16fab0ba83cb2298f8137fec831af1aec4.zip | |
Fix some minor file descriptor leaks and related glitches.
* filelock.c (create_lock_file) [!O_CLOEXEC]: Use fcntl with FD_CLOEXEC.
(create_lock_file): Use write, not emacs_write.
* image.c (slurp_file, png_load_body):
* process.c (Fnetwork_interface_list, Fnetwork_interface_info)
(server_accept_connection):
Don't leak an fd on memory allocation failure.
* image.c (slurp_file): Add a cheap heuristic for growing files.
* xfaces.c (Fx_load_color_file): Block input around the fopen too,
as that's what the other routines do. Maybe input need not be
blocked at all, but it's better to be consistent.
Avoid undefined behavior when strlen is zero.
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/image.c b/src/image.c index 95d385dc9e2..1e3944ac1a1 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -2276,23 +2276,28 @@ slurp_file (char *file, ptrdiff_t *size) | |||
| 2276 | unsigned char *buf = NULL; | 2276 | unsigned char *buf = NULL; |
| 2277 | struct stat st; | 2277 | struct stat st; |
| 2278 | 2278 | ||
| 2279 | if (fp && fstat (fileno (fp), &st) == 0 | 2279 | if (fp) |
| 2280 | && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) | ||
| 2281 | && (buf = xmalloc (st.st_size), | ||
| 2282 | fread (buf, 1, st.st_size, fp) == st.st_size)) | ||
| 2283 | { | ||
| 2284 | *size = st.st_size; | ||
| 2285 | fclose (fp); | ||
| 2286 | } | ||
| 2287 | else | ||
| 2288 | { | 2280 | { |
| 2289 | if (fp) | 2281 | ptrdiff_t count = SPECPDL_INDEX (); |
| 2290 | fclose (fp); | 2282 | record_unwind_protect_ptr (fclose_unwind, fp); |
| 2291 | if (buf) | 2283 | |
| 2284 | if (fstat (fileno (fp), &st) == 0 | ||
| 2285 | && 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX)) | ||
| 2292 | { | 2286 | { |
| 2293 | xfree (buf); | 2287 | /* Report an error if we read past the purported EOF. |
| 2294 | buf = NULL; | 2288 | This can happen if the file grows as we read it. */ |
| 2289 | ptrdiff_t buflen = st.st_size; | ||
| 2290 | buf = xmalloc (buflen + 1); | ||
| 2291 | if (fread (buf, 1, buflen + 1, fp) == buflen) | ||
| 2292 | *size = buflen; | ||
| 2293 | else | ||
| 2294 | { | ||
| 2295 | xfree (buf); | ||
| 2296 | buf = NULL; | ||
| 2297 | } | ||
| 2295 | } | 2298 | } |
| 2299 | |||
| 2300 | unbind_to (count, Qnil); | ||
| 2296 | } | 2301 | } |
| 2297 | 2302 | ||
| 2298 | return buf; | 2303 | return buf; |
| @@ -5732,8 +5737,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 5732 | if (fread (sig, 1, sizeof sig, fp) != sizeof sig | 5737 | if (fread (sig, 1, sizeof sig, fp) != sizeof sig |
| 5733 | || fn_png_sig_cmp (sig, 0, sizeof sig)) | 5738 | || fn_png_sig_cmp (sig, 0, sizeof sig)) |
| 5734 | { | 5739 | { |
| 5735 | image_error ("Not a PNG file: `%s'", file, Qnil); | ||
| 5736 | fclose (fp); | 5740 | fclose (fp); |
| 5741 | image_error ("Not a PNG file: `%s'", file, Qnil); | ||
| 5737 | return 0; | 5742 | return 0; |
| 5738 | } | 5743 | } |
| 5739 | } | 5744 | } |