* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) @ 2011-07-29 6:44 Paul Eggert 2011-07-29 10:01 ` Jan Djärv [not found] ` <handler.9196.B.131192196724343.ack@debbugs.gnu.org> 0 siblings, 2 replies; 13+ messages in thread From: Paul Eggert @ 2011-07-29 6:44 UTC (permalink / raw) To: 9196 Package: emacs Version: 24.0.50 Tags: patch This is a followup to Bug#9079. The enclosed patch fixes several more integer and memory overflow issues in the Emacs trunk, mostly having to do with 64-bit machines. Like Bug#9079, the patch doesn't add any features to Emacs and it focuses on fixing bugs, so it should be suitable for installing into the trunk after a bit more testing. Here's an example bug fixed by the patch. Start Emacs on a 64-bit GNU/Linux host, and cut-and-paste a slightly-larger-than-2-GiB chunk of text from some other application into Emacs. Emacs will dump core due to heap corruption. This patch is large and tedious but mostly straightforward. For those inclined to wade through it, I suggest looking at two issues. * The patch to image.c uses vsnprintf in order to avoid a buffer overflow with sprintf. The code can't use doprnt because the API is established by the TIFF library, and the TIFF library code uses a printf-like interface, not a doprnt-like interface. The patch assumes only the intersection of the standard/GNU and the Microsoft behaviors for vsnprintf, so it should be portable. * The patch to xselect.c required the most work on my part, is the trickiest, and would be most helped by a review, if someone has the time for that. # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: eggert@cs.ucla.edu-20110729053112-essfu02l7ms3r8wy # target_branch: bzr+ssh://eggert@bzr.savannah.gnu.org/emacs/trunk # testament_sha1: 3f815ffa0cb03479afac0558dfab16532da52b40 # timestamp: 2011-07-28 22:46:36 -0700 # base_revision_id: schwab@linux-m68k.org-20110728202319-\ # yx12un58runa3zxk # # Begin patch === modified file 'src/ChangeLog' --- src/ChangeLog 2011-07-28 20:23:19 +0000 +++ src/ChangeLog 2011-07-29 05:31:12 +0000 @@ -1,3 +1,358 @@ +2011-07-29 Paul Eggert <eggert@cs.ucla.edu> + + Integer and memory overflow issues. + + * bidi.c (bidi_shelve_header_size): New constant. + (bidi_cache_ensure_space, bidi_shelve_cache): Use it. + (bidi_cache_ensure_space): Avoid integer overflow when allocating. + + * buffer.c (overlays_at, overlays_in, record_overlay_string) + (overlay_strings): + Don't update size of array until after memory allocation succeeds, + because xmalloc/xrealloc may not return. + + * callproc.c (child_setup): Don't assume strlen fits in int. + + * ccl.c (Fccl_execute_on_string): Check for memory overflow. + Use ptrdiff_t rather than EMACS_INT where ptrdiff_t will do. + Redo buffer-overflow calculations to avoid integer overflow. + + * character.c (Fstring): Check for size-calculation overflow. + + * coding.c (produce_chars): Redo buffer-overflow calculations to avoid + unnecessary integer overflow. Check for size overflow. + (encode_coding_object): Don't update size until xmalloc succeeds. + + * composite.c (get_composition_id): Check for overflow in glyph + length calculations. + + Integer and memory overflow fixes for display code. + * dispextern.h (struct glyph_pool.nglyphs): Now ptrdiff_t, not int. + * dispnew.c (adjust_glyph_matrix, realloc_glyph_pool) + (scrolling_window): Check for overflow in size calculations. + (line_draw_cost, realloc_glyph_pool, add_row_entry): + Don't assume glyph table len fits in int. + (struct row_entry.bucket, row_entry_pool_size, row_entry_idx) + (row_table_size): Now ptrdiff_t, not int. + (scrolling_window): Avoid overflow in size calculations. + Don't update size until allocation succeeds. + * fns.c (concat): Check for overflow in size calculations. + (next_almost_prime): Verify NEXT_ALMOST_PRIME_LIMIT. + * lisp.h (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): New macros. + (NEXT_ALMOST_PRIME_LIMIT): New constant. + + * doc.c (get_doc_string_buffer_size): Now ptrdiff_t, not int. + (get_doc_string): Check for size calculation overflow. + Don't update size until allocation succeeds. + (get_doc_string, Fsubstitute_command_keys): Use ptrdiff_t, not + EMACS_INT, where ptrdiff_t will do. + (Fsubstitute_command_keys): Check for string overflow. + + * editfns.c (set_time_zone_rule): Don't assume environment length + fits in int. + (message_length): Now ptrdiff_t, not int. + (Fmessage_box): Don't update size until allocation succeeds. + Don't assume message length fits in int. + (Fformat): Use ptrdiff_t, not EMACS_INT, where ptrdiff_t will do. + + * emacs.c (main, sort_args): Check for size-calculation overflow. + + * eval.c (init_eval_once, grow_specpdl): Don't update size until + alloc succeeds. + (call_debugger, grow_specpdl): Redo calculations to avoid overflow. + + * frame.c (set_menu_bar_lines, x_set_frame_parameters) + (x_set_scroll_bar_width, x_figure_window_size): + Check for integer overflow. + (x_set_alpha): Do not assume XINT fits in int. + + * frame.h (struct frame): Use int, not EMACS_INT, where int works. + This is for the members text_lines, text_cols, total_lines, total_cols, + where the system imposes an 'int' limit. + + * fringe.c (Fdefine_fringe_bitmap): + Don't update size until alloc works. + + * ftfont.c (ftfont_get_open_type_spec, setup_otf_gstring) + (ftfont_shape_by_flt): Check for integer overflow in size calculations. + + * gtkutil.c (get_utf8_string, xg_store_widget_in_map): + Check for size-calculation overflow. + (get_utf8_string): Use ptrdiff_t, not size_t, where either will + do, as we prefer signed integers. + (id_to_widget.max_size, id_to_widget.used) + (xg_store_widget_in_map, xg_remove_widget_from_map) + (xg_get_widget_from_map, xg_get_scroll_id_for_window) + (xg_remove_scroll_bar, xg_update_scrollbar_pos): + Use and return ptrdiff_t, not int. + (xg_gtk_scroll_destroy): Don't assume ptrdiff_t fits in int. + * gtkutil.h: Change prototypes to match the above. + + * image.c (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): Remove; these + are duplicate now that they've been promoted to lisp.h. + (x_allocate_bitmap_record, x_alloc_image_color) + (make_image_cache, cache_image, xpm_load): + Don't update size until alloc is done. + (xpm_load, lookup_rgb_color, lookup_pixel_color, x_to_xcolors) + (x_detect_edges): + Check for size calculation overflow. + (ct_colors_allocated_max): New constant. + (x_to_xcolors, x_detect_edges): Reorder multiplicands to avoid + overflow. + + * keyboard.c (read_char, menu_bar_items, tool_bar_items) + (read_char_x_menu_prompt, read_char_minibuf_menu_width) + (read_char_minibuf_menu_prompt, follow_key, read_key_sequence): + Use ptrdiff_t, not int, to count maps. + (read_char_minibuf_menu_prompt): Check for overflow in size + calculations. Don't update size until allocation succeeds. Redo + calculations to avoid overflow. + * keyboard.h: Change prototypes to match the above. + + * keymap.c (cmm_size, current_minor_maps): Use ptrdiff_t, not int, + to count maps. + (current_minor_maps): Check for size calculation overflow. + * keymap.h: Change prototypes to match the above. + + * lread.c (read1, init_obarray): Don't update size until alloc done. + + * macros.c (Fstart_kbd_macro): Don't update size until alloc done. + (store_kbd_macro_char): Reorder multiplicands to avoid overflow. + + * minibuf.c (read_minibuf_noninteractive): Don't leak memory + on memory overflow. + + * nsterm.h (struct ns_color_table.size, struct ns_color_table.avail): + Now ptrdiff_t, not int. + * nsterm.m (ns_index_color): Use ptrdiff_t, not int, for table indexes. + (ns_draw_fringe_bitmap): Rewrite to avoid overflow. + + * process.c (Fnetwork_interface_list): Check for overflow + in size calculation. + + * region-cache.c (move_cache_gap): Check for size calculation overflow. + + * scroll.c (do_line_insertion_deletion_costs): Check for size calc + overflow. Don't bother calling xmalloc when xrealloc will do. + + * search.c (Freplace_match): Check for size calculation overflow. + (Fset_match_data): Don't assume list lengths fit in 'int'. + + * sysdep.c (system_process_attributes): Use ptrdiff_t, not int, + for command line length. Do not attempt to address one before the + beginning of an array, as that's not portable. + + * term.c (max_frame_lines): Remove; unused. + (encode_terminal_src_size, encode_terminal_dst_size): Now ptrdiff_t, + not int. + (encode_terminal_code, calculate_costs): Check for size + calculation overflow. + (encode_terminal_code): Use ptrdiff_t, not int, to record glyph + table lengths and related sizes. Don't update size until alloc + done. Redo calculations to avoid overflow. + (calculate_costs): Don't bother calling xmalloc when xrealloc will do. + + * termcap.c (tgetent): Use ptrdiff_t, not int, to record results of + subtracting pointers. + (gobble_line): Check for overflow more carefully. Don't update size + until alloc done. + + * tparam.c (tparam1): Use ptrdiff_t, not int, for sizes. + Don't update size until alloc done. + Redo size calculations to avoid overflow. + Check for size calculation overflow. + + * xdisp.c (store_mode_line_noprop_char, x_consider_frame_title): + Use ptrdiff_t, not int, for sizes. + (store_mode_line_noprop_char): Don't update size until alloc done. + + * xfaces.c (Finternal_make_lisp_face): Use ptrdiff_t, not int, for + sizes. Check for size calculation overflow. + (cache_face): Do not overflow in size calculation. + + * xfns.c (x_encode_text, x_set_name_internal) + (Fx_change_window_property): Use ptrdiff_t, not int, to count + sizes, since they can exceed INT_MAX in size. Check for size + calculation overflow. + + * xgselect.c (xg_select): Check for size calculation overflow. + Don't update size until alloc done. + + * xrdb.c (magic_file_p): Plug memory leak on size overflow. + (get_environ_db): Don't assume path length fits in int, + as sprintf is limited to int lengths. + + * xselect.c (X_LONG_SIZE, X_USHRT_MAX, X_ULONG_MAX): New macros. + Use them to make the following changes clearer. + (MAX_SELECTION_QUANTUM): Make the other bounds on this value clearer. + This change doesn't affect the value now, but it may help remind + future maintainers not to raise the value too much later. + (SELECTION_QUANTUM): Remove, replacing with ... + (selection_quantum): ... new function, which avoids overflow. + All uses changed. + (struct selection_data.size): Now ptrdiff_t, not int, to avoid + assumption that selection length fits in 'int'. + (x_reply_selection_request, x_handle_selection_request) + (x_get_window_property, receive_incremental_selection) + (x_get_window_property_as_lisp_data, selection_data_to_lisp_data) + (lisp_data_to_selection_data, clean_local_selection_data): + Use ptrdiff_t, not int, to record length of selection. + (x_reply_selection_request, x_get_window_property) + (receive_incremental_selection, x_property_data_to_lisp): + Redo calculations to avoid overflow. + (x_reply_selection_request): When sending hint, ceiling it at + X_ULONG_MAX rather than relying on wraparound overflow to send + something. + (x_get_window_property, receive_incremental_selection) + (lisp_data_to_selection_data, x_property_data_to_lisp): + Check for size-calculation overflow. + (x_get_window_property, receive_incremental_selection) + (lisp_data_to_selection_data, Fx_register_dnd_atom): + Don't store size until memory allocation succeeds. + (x_get_window_property): Plug memory leak on memory exhaustion. + Don't double-block input; malloc is safe here. Don't assume 2**34 + - 4 fits in unsigned long. Add an xassert to check + XGetWindowProperty overflow. Be more careful about overflow + calculations, and distinguish size from memory overflow better. + (receive_incremental_selection): When tracing, don't assume + unsigned int is less than INT_MAX. + (x_selection_data_to_lisp_data): Remove unnecessary (and in theory + harmful) conversions of unsigned short to int. + (lisp_data_to_selection_data): Don't assume that integers + in the range -65535 through -1 fit in an X unsigned short. + Don't assume that ULONG_MAX == X_ULONG_MAX. Don't store into + result parameters unless successful. Rely on cons_to_unsigned + to report problems with elements; the old code wasn't right anyway. + (x_check_property_data): Check for int overflow; we cannot use + a wider type due to X limits. + (x_handle_dnd_message): Use unsigned int, to avoid int overflow. + + * xsmfns.c (smc_save_yourself_CB): Check for size calc overflow. + + * xterm.c (x_color_cells, handle_one_xevent, x_term_init): + Check for size calculation overflow. + (x_color_cells): Don't store size until memory allocation succeeds. + (handle_one_xevent): Use ptrdiff_t, not int, for byte counts. + (x_term_init): Don't assume length fits in int (sprintf is limited + to int size). + + Use ptrdiff_t for composition IDs. + * character.c (lisp_string_width): + * composite.c (composition_table_size, n_compositions) + (get_composition_id, composition_gstring_from_id): + * dispextern.h (struct glyph_string.cmp_id, struct composition_it.id): + * xdisp.c (BUILD_COMPOSITE_GLYPH_STRING): + * window.c (Frecenter): + Use ptrdiff_t, not int, for composition IDs. + * composite.c (get_composition_id): Check for integer overflow. + * composite.h: Adjust prototypes to match the above changes. + + Use ptrdiff_t for hash table indexes. + * category.c (hash_get_category_set): + * ccl.c (ccl_driver): + * charset.h (struct charset.hash_index, CHECK_CHARSET_GET_ID): + * coding.c (coding_system_charset_list, detect_coding_system): + * coding.h (struct coding_system.id): + * composite.c (get_composition_id, gstring_lookup_cache): + * fns.c (hash_lookup, hash_put, Fgethash, Fputhash): + * image.c (xpm_get_color_table_h): + * lisp.h (hash_lookup, hash_put): + * minibuf.c (Ftest_completion): + Use ptrdiff_t for hash table indexes, not int (which is too + narrow, on 64-bit hosts) or EMACS_INT (which is too wide, on + 32-bit --with-wide-int hosts). + + * charset.c (Fdefine_charset_internal): Check for integer overflow. + Add a FIXME comment about memory leaks. + (syms_of_charset): Don't assume xmalloc returns. + + Don't assume that stated character widths fit in int. + * character.c (Fchar_width, c_string_width, lisp_string_width): + * character.h (CHAR_WIDTH): + * indent.c (MULTIBYTE_BYTES_WIDTH): + Use sanitize_char_width to avoid undefined and/or bad behavior + with outlandish widths. + * character.h (sanitize_tab_width): Renamed from sanitize_width, + now that we have two such functions. All uses changed. + (sanitize_char_width): New inline function. + + Don't assume that tab-width fits in int. + * character.h (sanitize_width): New inline function. + (SANE_TAB_WIDTH): New macro. + (ASCII_CHAR_WIDTH): Use it. + * indent.c (sane_tab_width): Remove. All uses replaced by + SANE_TAB_WIDTH (current_buffer). + * xdisp.c (init_iterator): Use SANE_TAB_WIDTH. + + * fileio.c: Integer overflow issues with file modes. + (Fset_file_modes, auto_save_1): Don't assume EMACS_INT fits in int. + + * charset.c (read_hex): New arg OVERFLOW. All uses changed. + Remove unreachable code. + (read_hex, load_charset_map_from_file): Check for integer overflow. + + * xterm.c: don't go over XClientMessageEvent limit + (scroll_bar_windows_size): Now ptrdiff_t, as we prefer signed. + (x_send_scroll_bar_event): Likewise. Check that the size does not + exceed limits imposed by XClientMessageEvent, as well as the usual + ptrdiff_t and size_t limits. + + * keyboard.c: Overflow, signedness and related fixes. + (make_lispy_movement): Use same integer type in forward decl + that is used in the definition. + (read_key_sequence, keyremap_step): + Change bufsize argument back to int, undoing my 2011-03-30 change. + We prefer signed types, and int is wide enough here. + (parse_tool_bar_item): Don't assume tool_bar_max_label_size is less + than TYPE_MAXIMUM (EMACS_INT) / 2. Don't let the label size grow + larger than STRING_BYTES_BOUND. Use ptrdiff_t for Emacs string + length, not size_t. Use ptrdiff_t for index, not int. + (keyremap_step, read_key_sequence): Redo bufsize check to avoid + possibility of integer overflow. + + Overflow, signedness and related fixes for images. + + * dispextern.h (struct it.stack[0].u.image.image_id) + (struct_it.image_id, struct image.id, struct image_cache.size) + (struct image_cache.used, struct image_cache.ref_count): + * gtkutil.c (update_frame_tool_bar): + * image.c (x_reference_bitmap, Fimage_size, Fimage_mask_p) + (Fimage_metadata, free_image_cache, clear_image_cache, lookup_image) + (cache_image, mark_image_cache, x_kill_gs_process, Flookup_image): + * nsmenu.m (update_frame_tool_bar): + * xdisp.c (calc_pixel_width_or_height): + * xfns.c (image_cache_refcount): + Image IDs are now ptrdiff_t, not int, to avoid arbitrary limits + on typical 64-bit hosts. + + * image.c (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): New macros. + (x_bitmap_pixmap, x_create_x_image_and_pixmap): + Omit unnecessary casts to int. + (parse_image_spec): Check that integers fall into 'int' range + when the callers expect that. + (image_ascent): Redo ascent calculation to avoid int overflow. + (clear_image_cache): Avoid overflow when sqrt (INT_MAX) < nimages. + (lookup_image): Remove unnecessary tests. + (xbm_image_p): Locals are now of int, not EMACS_INT, + since parse_image_check makes sure they fit into int. + (png_load, gif_load, svg_load_image): + Prefer int to unsigned where either will do. + (tiff_handler): New function, combining the cores of the + old tiff_error_handler and tiff_warning_handler. This + function is rewritten to use vsnprintf and thereby avoid + stack buffer overflows. It uses only the features of vsnprintf + that are common to both POSIX and native Microsoft. + (tiff_error_handler, tiff_warning_handler): Use it. + (tiff_load, gif_load, imagemagick_load_image): + Don't assume :index value fits in 'int'. + (gif_load): Omit unnecessary cast to double, and avoid double-rounding. + (imagemagick_load_image): Check that crop parameters fit into + the integer types that MagickCropImage accepts. Don't assume + Vimagemagick_render_type has a nonnegative value. Don't assume + size_t fits in 'long'. + (gs_load): Use printmax_t to print the widest integers possible. + Check for integer overflow when computing image height and width. + 2011-07-28 Andreas Schwab <schwab@linux-m68k.org> * print.c (print_object): Print empty symbol as ##. === modified file 'src/bidi.c' --- src/bidi.c 2011-07-28 00:24:58 +0000 +++ src/bidi.c 2011-07-29 05:31:12 +0000 @@ -306,6 +306,21 @@ static ptrdiff_t bidi_cache_start = 0; /* start of cache for this "stack" level */ +/* 5-slot stack for saving the start of the previous level of the + cache. xdisp.c maintains a 5-slot stack for its iterator state, + and we need the same size of our stack. */ +static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; +static int bidi_cache_sp; + +/* Size of header used by bidi_shelve_cache. */ +enum + { + bidi_shelve_header_size = + (sizeof (bidi_cache_idx) + sizeof (bidi_cache_start_stack) + + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) + + sizeof (bidi_cache_last_idx)) + }; + /* Reset the cache state to the empty state. We only reset the part of the cache relevant to iteration of the current object. Previous objects, which are pushed on the display iterator's stack, are left @@ -471,7 +486,8 @@ max (BUF_BYTES_MAX, STRING_BYTES_BOUND); /* Also, it cannot be larger than what C can represent. */ - ptrdiff_t c_bound = min (PTRDIFF_MAX, SIZE_MAX) / elsz; + ptrdiff_t c_bound = + (min (PTRDIFF_MAX, SIZE_MAX) - bidi_shelve_header_size) / elsz; if (min (string_or_buffer_bound, c_bound) <= idx) memory_full (SIZE_MAX); @@ -568,11 +584,6 @@ /*********************************************************************** Pushing and popping the bidi iterator state ***********************************************************************/ -/* 5-slot stack for saving the start of the previous level of the - cache. xdisp.c maintains a 5-slot stack for its iterator state, - and we need the same size of our stack. */ -static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; -static int bidi_cache_sp; /* Push the bidi iterator state in preparation for reordering a different object, e.g. display string found at certain buffer @@ -629,11 +640,8 @@ if (bidi_cache_idx == 0) return NULL; - databuf = xmalloc (sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack) - + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) - + sizeof (bidi_cache_last_idx)); + databuf = xmalloc (bidi_shelve_header_size + + bidi_cache_idx * sizeof (struct bidi_it)); memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); memcpy (databuf + sizeof (bidi_cache_idx), bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); === modified file 'src/buffer.c' --- src/buffer.c 2011-07-28 17:46:21 +0000 +++ src/buffer.c 2011-07-29 05:31:12 +0000 @@ -2572,9 +2572,9 @@ memory_full (SIZE_MAX); /* Make it work with an initial len == 0. */ len = len * 2 + 4; - *len_ptr = len; vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); *vec_ptr = vec; + *len_ptr = len; } else inhibit_storing = 1; @@ -2615,9 +2615,9 @@ memory_full (SIZE_MAX); /* Make it work with an initial len == 0. */ len = len * 2 + 4; - *len_ptr = len; vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); *vec_ptr = vec; + *len_ptr = len; } else inhibit_storing = 1; @@ -2712,9 +2712,9 @@ memory_full (SIZE_MAX); /* Make it work with an initial len == 0. */ len = len * 2 + 4; - *len_ptr = len; vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); *vec_ptr = vec; + *len_ptr = len; } else inhibit_storing = 1; @@ -2760,9 +2760,9 @@ memory_full (SIZE_MAX); /* Make it work with an initial len == 0. */ len = len * 2 + 4; - *len_ptr = len; vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); *vec_ptr = vec; + *len_ptr = len; } else inhibit_storing = 1; @@ -2978,15 +2978,12 @@ if (ssl->used == ssl->size) { - if (min (PTRDIFF_MAX, SIZE_MAX) / (sizeof (struct sortstr) * 2) - < ssl->size) + ptrdiff_t ssl_size = 0 < ssl->size ? ssl->size * 2 : 5; + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct sortstr) < ssl_size) memory_full (SIZE_MAX); - else if (0 < ssl->size) - ssl->size *= 2; - else - ssl->size = 5; ssl->buf = ((struct sortstr *) - xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr))); + xrealloc (ssl->buf, ssl_size * sizeof (struct sortstr))); + ssl->size = ssl_size; } ssl->buf[ssl->used].string = str; ssl->buf[ssl->used].string2 = str2; @@ -3111,9 +3108,9 @@ if (total > overlay_str_len) { - overlay_str_len = total; overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf, total); + overlay_str_len = total; } p = overlay_str_buf; for (i = overlay_tails.used; --i >= 0;) === modified file 'src/callproc.c' --- src/callproc.c 2011-07-28 01:46:23 +0000 +++ src/callproc.c 2011-07-29 05:31:12 +0000 @@ -1147,9 +1147,11 @@ cleaned up in the usual way. */ { register char *temp; - register int i; + register ptrdiff_t i; i = SBYTES (current_dir); + if (min (PTRDIFF_MAX, SIZE_MAX) - 6 < i) + memory_full (SIZE_MAX); #ifdef MSDOS /* MSDOS must have all environment variables malloc'ed, because low-level libc functions that launch subsidiary processes rely === modified file 'src/category.c' --- src/category.c 2011-06-24 21:25:22 +0000 +++ src/category.c 2011-07-19 06:07:07 +0000 @@ -67,7 +67,7 @@ hash_get_category_set (Lisp_Object table, Lisp_Object category_set) { struct Lisp_Hash_Table *h; - EMACS_INT i; + ptrdiff_t i; EMACS_UINT hash; if (NILP (XCHAR_TABLE (table)->extras[1])) === modified file 'src/ccl.c' --- src/ccl.c 2011-06-24 21:25:22 +0000 +++ src/ccl.c 2011-07-28 20:29:44 +0000 @@ -1303,7 +1303,7 @@ case CCL_LookupIntConstTbl: { - EMACS_INT eop; + ptrdiff_t eop; struct Lisp_Hash_Table *h; GET_CCL_RANGE (eop, ccl_prog, ic++, 0, (VECTORP (Vtranslation_hash_table_vector) @@ -1329,7 +1329,7 @@ case CCL_LookupCharConstTbl: { - EMACS_INT eop; + ptrdiff_t eop; struct Lisp_Hash_Table *h; GET_CCL_RANGE (eop, ccl_prog, ic++, 0, (VECTORP (Vtranslation_hash_table_vector) @@ -2061,12 +2061,12 @@ Lisp_Object val; struct ccl_program ccl; int i; - EMACS_INT outbufsize; + ptrdiff_t outbufsize; unsigned char *outbuf, *outp; - EMACS_INT str_chars, str_bytes; + ptrdiff_t str_chars, str_bytes; #define CCL_EXECUTE_BUF_SIZE 1024 int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE]; - EMACS_INT consumed_chars, consumed_bytes, produced_chars; + ptrdiff_t consumed_chars, consumed_bytes, produced_chars; if (setup_ccl_program (&ccl, ccl_prog) < 0) error ("Invalid CCL program"); @@ -2093,6 +2093,10 @@ ccl.ic = i; } + if (((min (PTRDIFF_MAX, SIZE_MAX) - 256) + / (ccl.buf_magnification ? ccl.buf_magnification : 1)) + < str_bytes) + memory_full (SIZE_MAX); outbufsize = (ccl.buf_magnification ? str_bytes * ccl.buf_magnification + 256 : str_bytes + 256); @@ -2127,11 +2131,19 @@ produced_chars += ccl.produced; if (NILP (unibyte_p)) { - if (outp - outbuf + MAX_MULTIBYTE_LENGTH * ccl.produced - > outbufsize) + ptrdiff_t offset = outp - outbuf; + if ((outbufsize - offset) / MAX_MULTIBYTE_LENGTH < ccl.produced) { - EMACS_INT offset = outp - outbuf; - outbufsize += MAX_MULTIBYTE_LENGTH * ccl.produced; + ptrdiff_t produced; + if (((min (PTRDIFF_MAX, SIZE_MAX) - outbufsize) + / MAX_MULTIBYTE_LENGTH) + < ccl.produced) + { + xfree (outbuf); + memory_full (SIZE_MAX); + } + produced = ccl.produced; + outbufsize += MAX_MULTIBYTE_LENGTH * produced; outbuf = (unsigned char *) xrealloc (outbuf, outbufsize); outp = outbuf + offset; } @@ -2140,9 +2152,14 @@ } else { - if (outp - outbuf + ccl.produced > outbufsize) + ptrdiff_t offset = outp - outbuf; + if (outbufsize - offset < ccl.produced) { - EMACS_INT offset = outp - outbuf; + if (min (PTRDIFF_MAX, SIZE_MAX) - outbufsize < ccl.produced) + { + xfree (outbuf); + memory_full (SIZE_MAX); + } outbufsize += ccl.produced; outbuf = (unsigned char *) xrealloc (outbuf, outbufsize); outp = outbuf + offset; === modified file 'src/character.c' --- src/character.c 2011-07-12 21:17:39 +0000 +++ src/character.c 2011-07-28 20:30:20 +0000 @@ -326,7 +326,7 @@ disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil; if (VECTORP (disp)) - width = ASIZE (disp); + width = sanitize_char_width (ASIZE (disp)); else width = CHAR_WIDTH (c); @@ -358,7 +358,7 @@ { val = DISP_CHAR_VECTOR (dp, c); if (VECTORP (val)) - thiswidth = ASIZE (val); + thiswidth = sanitize_char_width (ASIZE (val)); else thiswidth = CHAR_WIDTH (c); } @@ -423,7 +423,7 @@ { EMACS_INT chars, bytes, thiswidth; Lisp_Object val; - int cmp_id; + ptrdiff_t cmp_id; EMACS_INT ignore, end; if (find_composition (i, -1, &ignore, &end, &val, string) @@ -451,7 +451,7 @@ { val = DISP_CHAR_VECTOR (dp, c); if (VECTORP (val)) - thiswidth = ASIZE (val); + thiswidth = sanitize_char_width (ASIZE (val)); else thiswidth = CHAR_WIDTH (c); } @@ -902,6 +902,8 @@ Lisp_Object str; USE_SAFE_ALLOCA; + if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < n) + memory_full (SIZE_MAX); SAFE_ALLOCA (buf, unsigned char *, MAX_MULTIBYTE_LENGTH * n); p = buf; === modified file 'src/character.h' --- src/character.h 2011-07-06 23:28:00 +0000 +++ src/character.h 2011-07-19 00:42:24 +0000 @@ -556,6 +556,16 @@ } while (0) +/* Return a non-outlandish value for the tab width. */ + +#define SANE_TAB_WIDTH(buf) \ + sanitize_tab_width (XFASTINT (BVAR (buf, tab_width))) +static inline int +sanitize_tab_width (EMACS_INT width) +{ + return 0 < width && width <= 1000 ? width : 8; +} + /* Return the width of ASCII character C. The width is measured by how many columns C will occupy on the screen when displayed in the current buffer. */ @@ -563,12 +573,20 @@ #define ASCII_CHAR_WIDTH(c) \ (c < 0x20 \ ? (c == '\t' \ - ? XFASTINT (BVAR (current_buffer, tab_width)) \ + ? SANE_TAB_WIDTH (current_buffer) \ : (c == '\n' ? 0 : (NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2))) \ : (c < 0x7f \ ? 1 \ : ((NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2)))) +/* Return a non-outlandish value for a character width. */ + +static inline int +sanitize_char_width (EMACS_INT width) +{ + return 0 <= width && width <= 1000 ? width : 1000; +} + /* Return the width of character C. The width is measured by how many columns C will occupy on the screen when displayed in the current buffer. */ @@ -576,7 +594,7 @@ #define CHAR_WIDTH(c) \ (ASCII_CHAR_P (c) \ ? ASCII_CHAR_WIDTH (c) \ - : XINT (CHAR_TABLE_REF (Vchar_width_table, c))) + : sanitize_char_width (XINT (CHAR_TABLE_REF (Vchar_width_table, c)))) /* If C is a variation selector, return the index numnber of the variation selector (1..256). Otherwise, return 0. */ === modified file 'src/charset.c' --- src/charset.c 2011-06-14 18:57:19 +0000 +++ src/charset.c 2011-07-19 03:34:13 +0000 @@ -419,7 +419,7 @@ paying attention to comment character '#'. */ static inline unsigned -read_hex (FILE *fp, int *eof) +read_hex (FILE *fp, int *eof, int *overflow) { int c; unsigned n; @@ -441,15 +441,16 @@ *eof = 1; return 0; } - *eof = 0; n = 0; - if (c == 'x') - while ((c = getc (fp)) != EOF && isxdigit (c)) + while (isxdigit (c = getc (fp))) + { + if (UINT_MAX >> 4 < n) + *overflow = 1; n = ((n << 4) - | (c <= '9' ? c - '0' : c <= 'F' ? c - 'A' + 10 : c - 'a' + 10)); - else - while ((c = getc (fp)) != EOF && isdigit (c)) - n = (n * 10) + c - '0'; + | (c - ('0' <= c && c <= '9' ? '0' + : 'A' <= c && c <= 'F' ? 'A' - 10 + : 'a' - 10))); + } if (c != EOF) ungetc (c, fp); return n; @@ -479,7 +480,6 @@ unsigned max_code = CHARSET_MAX_CODE (charset); int fd; FILE *fp; - int eof; Lisp_Object suffixes; struct charset_map_entries *head, *entries; int n_entries, count; @@ -504,22 +504,27 @@ memset (entries, 0, sizeof (struct charset_map_entries)); n_entries = 0; - eof = 0; while (1) { - unsigned from, to; - int c; + unsigned from, to, c; int idx; + int eof = 0, overflow = 0; - from = read_hex (fp, &eof); + from = read_hex (fp, &eof, &overflow); if (eof) break; if (getc (fp) == '-') - to = read_hex (fp, &eof); + to = read_hex (fp, &eof, &overflow); else to = from; - c = (int) read_hex (fp, &eof); + if (eof) + break; + c = read_hex (fp, &eof, &overflow); + if (eof) + break; + if (overflow) + continue; if (from < min_code || to > max_code || from > to || c > MAX_CHAR) continue; @@ -1145,13 +1150,28 @@ hash_code); if (charset_table_used == charset_table_size) { - struct charset *new_table + struct charset *new_table; + /* Ensure that charset IDs fit into 'int' as well as into the + restriction imposed by fixnums, ptrdiff_t, and size_t. + Although the 'int' restriction could be removed, too much other + code would need altering; for example, the IDs are stuffed into + struct coding_system.charbuf[i] entries, which are 'int'. */ + int charset_table_size_max = + min (min (INT_MAX, MOST_POSITIVE_FIXNUM), + min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct charset)); + if (charset_table_size_max - 16 < charset_table_size) + memory_full (SIZE_MAX); + new_table = (struct charset *) xmalloc (sizeof (struct charset) * (charset_table_size + 16)); memcpy (new_table, charset_table, sizeof (struct charset) * charset_table_size); charset_table_size += 16; charset_table = new_table; + /* FIXME: Doesn't this leak memory? The old charset_table + becomes unreachable. If the memory leak is intentional, + a comment should be added to explain this. If not, the + old charset_table should be freed, using xfree. */ } id = charset_table_used++; new_definition_p = 1; @@ -2342,9 +2362,8 @@ Vcharset_hash_table = Fmake_hash_table (2, args); } + charset_table = (struct charset *) xmalloc (sizeof (struct charset) * 128); charset_table_size = 128; - charset_table = ((struct charset *) - xmalloc (sizeof (struct charset) * charset_table_size)); charset_table_used = 0; defsubr (&Scharsetp); === modified file 'src/charset.h' --- src/charset.h 2011-06-15 18:57:45 +0000 +++ src/charset.h 2011-07-19 06:07:07 +0000 @@ -148,7 +148,7 @@ int id; /* Index to Vcharset_hash_table. */ - EMACS_INT hash_index; + ptrdiff_t hash_index; /* Dimension of the charset: 1, 2, 3, or 4. */ int dimension; @@ -341,7 +341,7 @@ number of the charset. Otherwise, signal an error. */ #define CHECK_CHARSET_GET_ID(x, id) \ do { \ - int idx; \ + ptrdiff_t idx; \ \ if (! SYMBOLP (x) || (idx = CHARSET_SYMBOL_HASH_INDEX (x)) < 0) \ wrong_type_argument (Qcharsetp, (x)); \ === modified file 'src/coding.c' --- src/coding.c 2011-07-01 11:03:55 +0000 +++ src/coding.c 2011-07-28 20:31:29 +0000 @@ -5838,7 +5838,7 @@ Lisp_Object coding_system_charset_list (Lisp_Object coding_system) { - int id; + ptrdiff_t id; Lisp_Object attrs, charset_list; CHECK_CODING_SYSTEM_GET_ID (coding_system, id); @@ -6683,8 +6683,12 @@ break; } - if (dst + MAX_MULTIBYTE_LENGTH * to_nchars > dst_end) + if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars) { + if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf)) + / MAX_MULTIBYTE_LENGTH) + < to_nchars) + memory_full (SIZE_MAX); dst = alloc_destination (coding, buf_end - buf + MAX_MULTIBYTE_LENGTH * to_nchars, @@ -7888,11 +7892,10 @@ } else if (EQ (dst_object, Qt)) { + ptrdiff_t dst_bytes = max (1, coding->src_chars); coding->dst_object = Qnil; - coding->dst_bytes = coding->src_chars; - if (coding->dst_bytes == 0) - coding->dst_bytes = 1; - coding->destination = (unsigned char *) xmalloc (coding->dst_bytes); + coding->destination = (unsigned char *) xmalloc (dst_bytes); + coding->dst_bytes = dst_bytes; coding->dst_multibyte = 0; } else @@ -8076,7 +8079,7 @@ Lisp_Object attrs, eol_type; Lisp_Object val = Qnil; struct coding_system coding; - int id; + ptrdiff_t id; struct coding_detection_info detect_info; enum coding_category base_category; int null_byte_found = 0, eight_bit_found = 0; === modified file 'src/coding.h' --- src/coding.h 2011-04-11 06:58:57 +0000 +++ src/coding.h 2011-07-19 06:07:07 +0000 @@ -415,7 +415,7 @@ setup_coding_system. At the early stage of building time, this value is -1 in the array coding_categories to indicate that no coding-system of that category is yet defined. */ - int id; + ptrdiff_t id; /* Flag bits of the coding system. The meaning of each bit is common to all types of coding systems. */ === modified file 'src/composite.c' --- src/composite.c 2011-07-09 06:28:40 +0000 +++ src/composite.c 2011-07-28 20:35:09 +0000 @@ -142,10 +142,10 @@ struct composition **composition_table; /* The current size of `composition_table'. */ -static int composition_table_size; +static ptrdiff_t composition_table_size; /* Number of compositions currently made. */ -int n_compositions; +ptrdiff_t n_compositions; /* Hash table for compositions. The key is COMPONENTS-VEC of `composition' property. The value is the corresponding @@ -172,19 +172,29 @@ If the composition is invalid, return -1. */ -int +ptrdiff_t get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, Lisp_Object prop, Lisp_Object string) { Lisp_Object id, length, components, key, *key_contents; - int glyph_len; + ptrdiff_t glyph_len; struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); - EMACS_INT hash_index; + ptrdiff_t hash_index; EMACS_UINT hash_code; + enum composition_method method; struct composition *cmp; EMACS_INT i; int ch; + /* Maximum length of a string of glyphs. XftGlyphExtents limits this + to INT_MAX, and Emacs may limit it further. */ + enum { + glyph_len_max = + min (INT_MAX, + (min (PTRDIFF_MAX, SIZE_MAX) + / max (MAX_MULTIBYTE_LENGTH, 2 * sizeof (short)))) + }; + /* PROP should be Form-A: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) or @@ -260,18 +270,22 @@ /* Check if we have sufficient memory to store this information. */ if (composition_table_size == 0) { + composition_table + = (struct composition **) xmalloc (sizeof (composition_table[0]) * 256); composition_table_size = 256; - composition_table - = (struct composition **) xmalloc (sizeof (composition_table[0]) - * composition_table_size); } else if (composition_table_size <= n_compositions) { - composition_table_size += 256; + if ((min (MOST_POSITIVE_FIXNUM, + min (PTRDIFF_MAX, SIZE_MAX) / sizeof composition_table[0]) + - 256) + < composition_table_size) + memory_full (SIZE_MAX); composition_table = (struct composition **) xrealloc (composition_table, sizeof (composition_table[0]) - * composition_table_size); + * (composition_table_size + 256)); + composition_table_size += 256; } key_contents = XVECTOR (key)->contents; @@ -316,18 +330,24 @@ /* Register the composition in composition_hash_table. */ hash_index = hash_put (hash_table, key, id, hash_code); + method = (NILP (components) + ? COMPOSITION_RELATIVE + : ((INTEGERP (components) || STRINGP (components)) + ? COMPOSITION_WITH_ALTCHARS + : COMPOSITION_WITH_RULE_ALTCHARS)); + + glyph_len = (method == COMPOSITION_WITH_RULE_ALTCHARS + ? (ASIZE (key) + 1) / 2 + : ASIZE (key)); + + if (glyph_len_max < glyph_len) + memory_full (SIZE_MAX); + /* Register the composition in composition_table. */ cmp = (struct composition *) xmalloc (sizeof (struct composition)); - cmp->method = (NILP (components) - ? COMPOSITION_RELATIVE - : ((INTEGERP (components) || STRINGP (components)) - ? COMPOSITION_WITH_ALTCHARS - : COMPOSITION_WITH_RULE_ALTCHARS)); + cmp->method = method; cmp->hash_index = hash_index; - glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS - ? (ASIZE (key) + 1) / 2 - : ASIZE (key)); cmp->glyph_len = glyph_len; cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2); cmp->font = NULL; @@ -656,7 +676,7 @@ gstring_lookup_cache (Lisp_Object header) { struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); - EMACS_INT i = hash_lookup (h, header, NULL); + ptrdiff_t i = hash_lookup (h, header, NULL); return (i >= 0 ? HASH_VALUE (h, i) : Qnil); } @@ -691,7 +711,7 @@ } Lisp_Object -composition_gstring_from_id (int id) +composition_gstring_from_id (ptrdiff_t id) { struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); === modified file 'src/composite.h' --- src/composite.h 2011-06-12 23:25:12 +0000 +++ src/composite.h 2011-07-28 20:35:41 +0000 @@ -193,7 +193,7 @@ void *font; /* Pointer to an array of x-offset and y-offset (by pixels) of - glyphs. This points to a sufficient memory space (sizeof (int) * + glyphs. This points to a sufficient memory space (sizeof (short) * glyph_len * 2) that is allocated when the composition is registered in composition_table. X-offset and Y-offset of Nth glyph are (2N)th and (2N+1)th elements respectively. */ @@ -204,7 +204,7 @@ COMPOSITION-ID. */ extern struct composition **composition_table; /* Number of the currently registered compositions. */ -extern int n_compositions; +extern ptrdiff_t n_compositions; /* Mask bits for CHECK_MASK arg to update_compositions. For a change in the region FROM and TO, check compositions ... */ @@ -216,8 +216,8 @@ extern Lisp_Object Qcomposition; extern Lisp_Object composition_hash_table; -extern int get_composition_id (EMACS_INT, EMACS_INT, EMACS_INT, - Lisp_Object, Lisp_Object); +extern ptrdiff_t get_composition_id (EMACS_INT, EMACS_INT, EMACS_INT, + Lisp_Object, Lisp_Object); extern int find_composition (EMACS_INT, EMACS_INT, EMACS_INT *, EMACS_INT *, Lisp_Object *, Lisp_Object); extern void update_compositions (EMACS_INT, EMACS_INT, int); @@ -299,7 +299,7 @@ struct font_metrics; extern Lisp_Object composition_gstring_put_cache (Lisp_Object, EMACS_INT); -extern Lisp_Object composition_gstring_from_id (int); +extern Lisp_Object composition_gstring_from_id (ptrdiff_t); extern int composition_gstring_p (Lisp_Object); extern int composition_gstring_width (Lisp_Object, EMACS_INT, EMACS_INT, struct font_metrics *); === modified file 'src/dispextern.h' --- src/dispextern.h 2011-07-14 17:28:42 +0000 +++ src/dispextern.h 2011-07-28 21:31:33 +0000 @@ -575,7 +575,7 @@ struct glyph *glyphs; /* Allocated size of `glyphs'. */ - int nglyphs; + ptrdiff_t nglyphs; /* Number of rows and columns in a matrix. */ int nrows, ncolumns; @@ -1240,7 +1240,7 @@ struct composition *cmp; /* If not negative, this string describes a compos. */ - int cmp_id; + ptrdiff_t cmp_id; /* Start and end glyph indices in a glyph-string. */ int cmp_from, cmp_to; @@ -2056,7 +2056,7 @@ EMACS_INT stop_pos; /* ID number of the composition or glyph-string. If negative, we are not iterating over a composition now. */ - int id; + ptrdiff_t id; /* If non-negative, character that triggers the automatic composition at `stop_pos', and this is an automatic composition. If negative, this is a static composition. This is set to -2 @@ -2246,7 +2246,7 @@ struct { Lisp_Object object; struct it_slice slice; - int image_id; + ptrdiff_t image_id; } image; /* method == GET_FROM_COMPOSITION */ struct { @@ -2376,7 +2376,7 @@ enum glyphless_display_method glyphless_method; /* If what == IT_IMAGE, the id of the image to display. */ - int image_id; + ptrdiff_t image_id; /* Values from `slice' property. */ struct it_slice slice; @@ -2826,7 +2826,7 @@ EMACS_UINT hash; /* Image id of this image. */ - int id; + ptrdiff_t id; /* Hash collision chain. */ struct image *next, *prev; @@ -2845,13 +2845,13 @@ struct image **images; /* Allocated size of `images'. */ - unsigned size; + ptrdiff_t size; /* Number of images in the cache. */ - unsigned used; + ptrdiff_t used; /* Reference count (number of frames sharing this cache). */ - int refcount; + ptrdiff_t refcount; }; @@ -3117,7 +3117,7 @@ extern int x_bitmap_height (struct frame *, ptrdiff_t); extern int x_bitmap_width (struct frame *, ptrdiff_t); extern int x_bitmap_pixmap (struct frame *, ptrdiff_t); -extern void x_reference_bitmap (struct frame *, int); +extern void x_reference_bitmap (struct frame *, ptrdiff_t); extern ptrdiff_t x_create_bitmap_from_data (struct frame *, char *, unsigned int, unsigned int); extern ptrdiff_t x_create_bitmap_from_file (struct frame *, Lisp_Object); @@ -3138,7 +3138,7 @@ void mark_image_cache (struct image_cache *); int valid_image_p (Lisp_Object); void prepare_image_for_display (struct frame *, struct image *); -int lookup_image (struct frame *, Lisp_Object); +ptrdiff_t lookup_image (struct frame *, Lisp_Object); unsigned long image_background (struct image *, struct frame *, XImagePtr_or_DC ximg); === modified file 'src/dispnew.c' --- src/dispnew.c 2011-07-14 20:40:35 +0000 +++ src/dispnew.c 2011-07-28 21:31:33 +0000 @@ -499,7 +499,10 @@ /* Enlarge MATRIX->rows if necessary. New rows are cleared. */ if (matrix->rows_allocated < dim.height) { - ptrdiff_t size = dim.height * sizeof (struct glyph_row); + ptrdiff_t size; + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph_row) < dim.height) + memory_full (SIZE_MAX); + size = dim.height * sizeof (struct glyph_row); new_rows = dim.height - matrix->rows_allocated; matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size); memset (matrix->rows + matrix->rows_allocated, 0, @@ -573,6 +576,9 @@ struct glyph_row *row = matrix->rows; struct glyph_row *end = row + matrix->rows_allocated; + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) < dim.width) + memory_full (SIZE_MAX); + while (row < end) { row->glyphs[LEFT_MARGIN_AREA] @@ -1217,7 +1223,7 @@ struct glyph *end = beg + row->used[TEXT_AREA]; int len; Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE; - int glyph_table_len = GLYPH_TABLE_LENGTH; + ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH; /* Ignore trailing and leading spaces if we can. */ if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */ @@ -1391,31 +1397,26 @@ static int realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim) { - int needed; + ptrdiff_t needed; int changed_p; changed_p = (pool->glyphs == 0 || matrix_dim.height != pool->nrows || matrix_dim.width != pool->ncolumns); + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) / matrix_dim.width + < matrix_dim.height) + memory_full (SIZE_MAX); + /* Enlarge the glyph pool. */ - needed = matrix_dim.width * matrix_dim.height; + needed = matrix_dim.width; + needed *= matrix_dim.height; if (needed > pool->nglyphs) { ptrdiff_t size = needed * sizeof (struct glyph); - - if (pool->glyphs) - { - pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size); - memset (pool->glyphs + pool->nglyphs, 0, - size - pool->nglyphs * sizeof (struct glyph)); - } - else - { - pool->glyphs = (struct glyph *) xmalloc (size); - memset (pool->glyphs, 0, size); - } - + pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size); + memset (pool->glyphs + pool->nglyphs, 0, + size - pool->nglyphs * sizeof (struct glyph)); pool->nglyphs = needed; } @@ -4166,7 +4167,7 @@ int new_line_number; /* Bucket index of this row_entry in the hash table row_table. */ - int bucket; + ptrdiff_t bucket; /* The row described by this entry. */ struct glyph_row *row; @@ -4180,18 +4181,18 @@ that we need a larger one. */ static struct row_entry *row_entry_pool; -static int row_entry_pool_size; +static ptrdiff_t row_entry_pool_size; /* Index of next free entry in row_entry_pool. */ -static int row_entry_idx; +static ptrdiff_t row_entry_idx; /* The hash table used during scrolling, and the table's size. This table is used to quickly identify equal rows in the desired and current matrix. */ static struct row_entry **row_table; -static int row_table_size; +static ptrdiff_t row_table_size; /* Vectors of pointers to row_entry structures belonging to the current and desired matrix, and the size of the vectors. */ @@ -4214,7 +4215,7 @@ add_row_entry (struct glyph_row *row) { struct row_entry *entry; - int i = row->hash % row_table_size; + ptrdiff_t i = row->hash % row_table_size; entry = row_table[i]; while (entry && !row_equal_p (entry->row, row, 1)) @@ -4267,9 +4268,10 @@ struct glyph_matrix *desired_matrix = w->desired_matrix; struct glyph_matrix *current_matrix = w->current_matrix; int yb = window_text_bottom_y (w); - int i, j, first_old, first_new, last_old, last_new; - int nruns, n, run_idx; - ptrdiff_t nbytes; + ptrdiff_t i; + int j, first_old, first_new, last_old, last_new; + int nruns, run_idx; + ptrdiff_t n, nbytes; struct row_entry *entry; struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); @@ -4354,45 +4356,77 @@ if (last_new == first_new) return 0; + /* Check for integer overflow in xrealloc size calculation. + + If next_almost_prime checks (N) for divisibility by 2..10, then + it can return at most N + 10, e.g., next_almost_prime (1) == 11. + So, set next_almost_prime_increment_max to 10. + + It's just a coincidence that next_almost_prime_increment_max == + NEXT_ALMOST_PRIME_LIMIT - 1. If NEXT_ALMOST_PRIME_LIMIT were + 13, then next_almost_prime_increment_max would be 14, e.g., + because next_almost_prime (113) would be 127. */ + { + verify (NEXT_ALMOST_PRIME_LIMIT == 11); + enum { next_almost_prime_increment_max = 10 }; + ptrdiff_t alloc_max = min (PTRDIFF_MAX, SIZE_MAX); + ptrdiff_t row_table_max = + ((alloc_max - next_almost_prime_increment_max) + / (3 * sizeof *row_table)); + ptrdiff_t row_entry_pool_max = alloc_max / sizeof *row_entry_pool; + int n_max = min (INT_MAX, min (row_table_max, row_entry_pool_max)); + ptrdiff_t old_lines_max = alloc_max / sizeof *old_lines; + int current_nrows_max = min (n_max - desired_matrix->nrows, old_lines_max); + int desired_nrows_max = + min (INT_MAX, + alloc_max / max (sizeof *new_lines, + max (sizeof *runs, sizeof *run_pool))); + if (current_nrows_max < current_matrix->nrows + || desired_nrows_max < desired_matrix->nrows) + memory_full (SIZE_MAX); + } + /* Reallocate vectors, tables etc. if necessary. */ if (current_matrix->nrows > old_lines_size) { + nbytes = current_matrix->nrows * sizeof *old_lines; + old_lines = (struct row_entry **) xrealloc (old_lines, nbytes); old_lines_size = current_matrix->nrows; - nbytes = old_lines_size * sizeof *old_lines; - old_lines = (struct row_entry **) xrealloc (old_lines, nbytes); } if (desired_matrix->nrows > new_lines_size) { + nbytes = desired_matrix->nrows * sizeof *new_lines; + new_lines = (struct row_entry **) xrealloc (new_lines, nbytes); new_lines_size = desired_matrix->nrows; - nbytes = new_lines_size * sizeof *new_lines; - new_lines = (struct row_entry **) xrealloc (new_lines, nbytes); } - n = desired_matrix->nrows + current_matrix->nrows; - if (3 * n > row_table_size) + n = desired_matrix->nrows; + n += current_matrix->nrows; + if (row_table_size / 3 < n) { - row_table_size = next_almost_prime (3 * n); - nbytes = row_table_size * sizeof *row_table; + ptrdiff_t size = next_almost_prime (3 * n); + nbytes = size * sizeof *row_table; row_table = (struct row_entry **) xrealloc (row_table, nbytes); + row_table_size = size; memset (row_table, 0, nbytes); } if (n > row_entry_pool_size) { + nbytes = n * sizeof *row_entry_pool; + row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes); row_entry_pool_size = n; - nbytes = row_entry_pool_size * sizeof *row_entry_pool; - row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes); } if (desired_matrix->nrows > runs_size) { - runs_size = desired_matrix->nrows; - nbytes = runs_size * sizeof *runs; + nbytes = desired_matrix->nrows * sizeof *runs; runs = (struct run **) xrealloc (runs, nbytes); - nbytes = runs_size * sizeof *run_pool; + nbytes = desired_matrix->nrows * sizeof *run_pool; run_pool = (struct run *) xrealloc (run_pool, nbytes); + runs_size = desired_matrix->nrows; } nruns = run_idx = 0; === modified file 'src/doc.c' --- src/doc.c 2011-07-15 15:31:36 +0000 +++ src/doc.c 2011-07-28 21:34:39 +0000 @@ -39,7 +39,7 @@ extern Lisp_Object Qclosure; /* Buffer used for reading from documentation file. */ static char *get_doc_string_buffer; -static int get_doc_string_buffer_size; +static ptrdiff_t get_doc_string_buffer_size; static unsigned char *read_bytecode_pointer; static Lisp_Object Fdocumentation_property (Lisp_Object, Lisp_Object, @@ -166,18 +166,23 @@ p = get_doc_string_buffer; while (1) { - EMACS_INT space_left = (get_doc_string_buffer_size + ptrdiff_t space_left = (get_doc_string_buffer_size - (p - get_doc_string_buffer)); int nread; /* Allocate or grow the buffer if we need to. */ if (space_left == 0) { - EMACS_INT in_buffer = p - get_doc_string_buffer; - get_doc_string_buffer_size += 16 * 1024; + ptrdiff_t in_buffer = p - get_doc_string_buffer; + enum { incr = 16 * 1024 }; + ptrdiff_t size; + if (min (PTRDIFF_MAX, SIZE_MAX) - 1 - incr + < get_doc_string_buffer_size) + memory_full (SIZE_MAX); + size = get_doc_string_buffer_size + incr; get_doc_string_buffer - = (char *) xrealloc (get_doc_string_buffer, - get_doc_string_buffer_size + 1); + = (char *) xrealloc (get_doc_string_buffer, size + 1); + get_doc_string_buffer_size = size; p = get_doc_string_buffer + in_buffer; space_left = (get_doc_string_buffer_size - (p - get_doc_string_buffer)); @@ -713,16 +718,16 @@ int changed = 0; register unsigned char *strp; register char *bufp; - EMACS_INT idx; - EMACS_INT bsize; + ptrdiff_t idx; + ptrdiff_t bsize; Lisp_Object tem; Lisp_Object keymap; unsigned char *start; - EMACS_INT length, length_byte; + ptrdiff_t length, length_byte; Lisp_Object name; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; int multibyte; - EMACS_INT nchars; + ptrdiff_t nchars; if (NILP (string)) return Qnil; @@ -774,7 +779,7 @@ } else if (strp[0] == '\\' && strp[1] == '[') { - EMACS_INT start_idx; + ptrdiff_t start_idx; int follow_remap = 1; changed = 1; @@ -813,7 +818,9 @@ if (NILP (tem)) /* but not on any keys */ { - EMACS_INT offset = bufp - buf; + ptrdiff_t offset = bufp - buf; + if (STRING_BYTES_BOUND - 4 < bsize) + string_overflow (); buf = (char *) xrealloc (buf, bsize += 4); bufp = buf + offset; memcpy (bufp, "M-x ", 4); @@ -836,7 +843,7 @@ else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<')) { struct buffer *oldbuf; - EMACS_INT start_idx; + ptrdiff_t start_idx; /* This is for computing the SHADOWS arg for describe_map_tree. */ Lisp_Object active_maps = Fcurrent_active_maps (Qnil, Qnil); Lisp_Object earlier_maps; @@ -907,7 +914,9 @@ length_byte = SBYTES (tem); subst: { - EMACS_INT offset = bufp - buf; + ptrdiff_t offset = bufp - buf; + if (STRING_BYTES_BOUND - length_byte < bsize) + string_overflow (); buf = (char *) xrealloc (buf, bsize += length_byte); bufp = buf + offset; memcpy (bufp, start, length_byte); === modified file 'src/editfns.c' --- src/editfns.c 2011-07-28 00:15:43 +0000 +++ src/editfns.c 2011-07-29 05:31:12 +0000 @@ -2100,7 +2100,7 @@ void set_time_zone_rule (const char *tzstring) { - int envptrs; + ptrdiff_t envptrs; char **from, **to, **newenv; /* Make the ENVIRON vector longer with room for TZSTRING. */ @@ -3350,7 +3350,7 @@ static char *message_text; /* Allocated length of that buffer. */ -static int message_length; +static ptrdiff_t message_length; DEFUN ("message", Fmessage, Smessage, 1, MANY, 0, doc: /* Display a message at the bottom of the screen. @@ -3432,8 +3432,8 @@ } if (SBYTES (val) > message_length) { + message_text = (char *) xrealloc (message_text, SBYTES (val)); message_length = SBYTES (val); - message_text = (char *)xrealloc (message_text, message_length); } memcpy (message_text, SDATA (val), SBYTES (val)); message2 (message_text, SBYTES (val), @@ -4158,7 +4158,7 @@ character. CONVBYTES says how much room is needed. Allocate enough room (and then some) and do it again. */ { - EMACS_INT used = p - buf; + ptrdiff_t used = p - buf; if (max_bufsize - used < convbytes) string_overflow (); === modified file 'src/emacs.c' --- src/emacs.c 2011-07-11 06:05:57 +0000 +++ src/emacs.c 2011-07-28 21:38:23 +0000 @@ -1360,9 +1360,12 @@ This requires inserting a new element into argv. */ if (displayname != 0 && skip_args - count_before == 1) { - char **new = (char **) xmalloc (sizeof (char *) * (argc + 2)); + char **new; int j; + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (char *) - 2 < argc) + memory_full (SIZE_MAX); + new = (char **) xmalloc (sizeof *new * argc + sizeof *new * 2); for (j = 0; j < count_before + 1; j++) new[j] = argv[j]; new[count_before + 1] = (char *) "-d"; @@ -1838,13 +1841,19 @@ 0 for an option that takes no arguments, 1 for an option that takes one argument, etc. -1 for an ordinary non-option argument. */ - int *options = (int *) xmalloc (sizeof (int) * argc); - int *priority = (int *) xmalloc (sizeof (int) * argc); + int *options; + int *priority; int to = 1; int incoming_used = 1; int from; int i; + if (sizeof (char *) < sizeof (int) + && min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < argc) + memory_full (SIZE_MAX); + options = (int *) xmalloc (sizeof (int) * argc); + priority = (int *) xmalloc (sizeof (int) * argc); + /* Categorize all the options, and figure out which argv elts are option arguments. */ for (from = 1; from < argc; from++) === modified file 'src/eval.c' --- src/eval.c 2011-07-07 02:14:52 +0000 +++ src/eval.c 2011-07-28 21:42:59 +0000 @@ -133,8 +133,9 @@ void init_eval_once (void) { - specpdl_size = 50; - specpdl = (struct specbinding *) xmalloc (specpdl_size * sizeof (struct specbinding)); + enum { size = 50 }; + specpdl = (struct specbinding *) xmalloc (size * sizeof (struct specbinding)); + specpdl_size = size; specpdl_ptr = specpdl; /* Don't forget to update docs (lispref node "Local Variables"). */ max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */ @@ -192,7 +193,7 @@ if (lisp_eval_depth + 40 > max_lisp_eval_depth) max_lisp_eval_depth = lisp_eval_depth + 40; - if (SPECPDL_INDEX () + 100 > max_specpdl_size) + if (max_specpdl_size - 100 < SPECPDL_INDEX ()) max_specpdl_size = SPECPDL_INDEX () + 100; #ifdef HAVE_WINDOW_SYSTEM @@ -3274,17 +3275,22 @@ grow_specpdl (void) { register int count = SPECPDL_INDEX (); - if (specpdl_size >= max_specpdl_size) + int max_size = + min (max_specpdl_size, + min (max (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct specbinding), + INT_MAX)); + int size; + if (max_size <= specpdl_size) { if (max_specpdl_size < 400) - max_specpdl_size = 400; - if (specpdl_size >= max_specpdl_size) + max_size = max_specpdl_size = 400; + if (max_size <= specpdl_size) signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil); } - specpdl_size *= 2; - if (specpdl_size > max_specpdl_size) - specpdl_size = max_specpdl_size; - specpdl = (struct specbinding *) xrealloc (specpdl, specpdl_size * sizeof (struct specbinding)); + size = specpdl_size < max_size / 2 ? 2 * specpdl_size : max_size; + specpdl = ((struct specbinding *) + xrealloc (specpdl, size * sizeof (struct specbinding))); + specpdl_size = size; specpdl_ptr = specpdl + count; } === modified file 'src/fileio.c' --- src/fileio.c 2011-07-19 20:33:28 +0000 +++ src/fileio.c 2011-07-19 20:37:27 +0000 @@ -2912,7 +2912,7 @@ encoded_absname = ENCODE_FILE (absname); - if (chmod (SSDATA (encoded_absname), XINT (mode)) < 0) + if (chmod (SSDATA (encoded_absname), XINT (mode) & 07777) < 0) report_file_error ("Doing chmod", Fcons (absname, Qnil)); return Qnil; @@ -5114,11 +5114,11 @@ { if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0) /* But make sure we can overwrite it later! */ - auto_save_mode_bits = st.st_mode | 0600; + auto_save_mode_bits = (st.st_mode | 0600) & 0777; else if ((modes = Ffile_modes (BVAR (current_buffer, filename)), INTEGERP (modes))) /* Remote files don't cooperate with stat. */ - auto_save_mode_bits = XINT (modes) | 0600; + auto_save_mode_bits = (XINT (modes) | 0600) & 0777; } return === modified file 'src/fns.c' --- src/fns.c 2011-07-08 00:51:25 +0000 +++ src/fns.c 2011-07-28 21:31:33 +0000 @@ -602,7 +602,12 @@ prev = Qnil; if (STRINGP (val)) - SAFE_ALLOCA (textprops, struct textprop_rec *, sizeof (struct textprop_rec) * nargs); + { + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *textprops < nargs) + memory_full (SIZE_MAX); + SAFE_ALLOCA (textprops, struct textprop_rec *, + sizeof *textprops * nargs); + } for (argnum = 0; argnum < nargs; argnum++) { @@ -3395,11 +3400,13 @@ /* Value is the next integer I >= N, N >= 0 which is "almost" a prime - number. */ + number. A number is "almost" a prime number if it is not divisible + by any integer in the range 2 .. (NEXT_ALMOST_PRIME_LIMIT - 1). */ EMACS_INT next_almost_prime (EMACS_INT n) { + verify (NEXT_ALMOST_PRIME_LIMIT == 11); for (n |= 1; ; n += 2) if (n % 3 != 0 && n % 5 != 0 && n % 7 != 0) return n; @@ -3787,11 +3794,11 @@ the hash code of KEY. Value is the index of the entry in H matching KEY, or -1 if not found. */ -EMACS_INT +ptrdiff_t hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash) { EMACS_UINT hash_code; - EMACS_INT start_of_bucket; + ptrdiff_t start_of_bucket; Lisp_Object idx; hash_code = h->hashfn (h, key); @@ -3821,11 +3828,11 @@ HASH is a previously computed hash code of KEY. Value is the index of the entry in H matching KEY. */ -EMACS_INT +ptrdiff_t hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value, EMACS_UINT hash) { - EMACS_INT start_of_bucket, i; + ptrdiff_t start_of_bucket, i; xassert ((hash & ~INTMASK) == 0); @@ -4482,7 +4489,7 @@ (Lisp_Object key, Lisp_Object table, Lisp_Object dflt) { struct Lisp_Hash_Table *h = check_hash_table (table); - EMACS_INT i = hash_lookup (h, key, NULL); + ptrdiff_t i = hash_lookup (h, key, NULL); return i >= 0 ? HASH_VALUE (h, i) : dflt; } @@ -4494,7 +4501,7 @@ (Lisp_Object key, Lisp_Object value, Lisp_Object table) { struct Lisp_Hash_Table *h = check_hash_table (table); - EMACS_INT i; + ptrdiff_t i; EMACS_UINT hash; i = hash_lookup (h, key, &hash); === modified file 'src/frame.c' --- src/frame.c 2011-07-22 05:02:24 +0000 +++ src/frame.c 2011-07-29 05:31:12 +0000 @@ -160,7 +160,7 @@ if (FRAME_MINIBUF_ONLY_P (f)) return; - if (INTEGERP (value)) + if (TYPE_RANGED_INTEGERP (int, value)) nlines = XINT (value); else nlines = 0; @@ -2992,7 +2992,7 @@ f->size_hint_flags &= ~ (XNegative | YNegative); if (EQ (left, Qminus)) f->size_hint_flags |= XNegative; - else if (INTEGERP (left)) + else if (TYPE_RANGED_INTEGERP (int, left)) { leftpos = XINT (left); if (leftpos < 0) @@ -3000,21 +3000,21 @@ } else if (CONSP (left) && EQ (XCAR (left), Qminus) && CONSP (XCDR (left)) - && INTEGERP (XCAR (XCDR (left)))) + && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX)) { leftpos = - XINT (XCAR (XCDR (left))); f->size_hint_flags |= XNegative; } else if (CONSP (left) && EQ (XCAR (left), Qplus) && CONSP (XCDR (left)) - && INTEGERP (XCAR (XCDR (left)))) + && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left)))) { leftpos = XINT (XCAR (XCDR (left))); } if (EQ (top, Qminus)) f->size_hint_flags |= YNegative; - else if (INTEGERP (top)) + else if (TYPE_RANGED_INTEGERP (int, top)) { toppos = XINT (top); if (toppos < 0) @@ -3022,14 +3022,14 @@ } else if (CONSP (top) && EQ (XCAR (top), Qminus) && CONSP (XCDR (top)) - && INTEGERP (XCAR (XCDR (top)))) + && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX)) { toppos = - XINT (XCAR (XCDR (top))); f->size_hint_flags |= YNegative; } else if (CONSP (top) && EQ (XCAR (top), Qplus) && CONSP (XCDR (top)) - && INTEGERP (XCAR (XCDR (top)))) + && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top)))) { toppos = XINT (XCAR (XCDR (top))); } @@ -3481,7 +3481,7 @@ x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); do_pending_window_change (0); } - else if (INTEGERP (arg) && XINT (arg) > 0 + else if (RANGED_INTEGERP (1, arg, INT_MAX) && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) { if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM) @@ -3520,7 +3520,7 @@ { double alpha = 1.0; double newval[2]; - int i, ialpha; + int i; Lisp_Object item; for (i = 0; i < 2; i++) @@ -3544,7 +3544,7 @@ } else if (INTEGERP (item)) { - ialpha = XINT (item); + EMACS_INT ialpha = XINT (item); if (ialpha < 0 || 100 < ialpha) args_out_of_range (make_number (0), make_number (100)); else @@ -4031,11 +4031,15 @@ if (!EQ (tem0, Qunbound)) { CHECK_NUMBER (tem0); + if (! (0 <= XINT (tem0) && XINT (tem0) <= INT_MAX)) + xsignal1 (Qargs_out_of_range, tem0); FRAME_LINES (f) = XINT (tem0); } if (!EQ (tem1, Qunbound)) { CHECK_NUMBER (tem1); + if (! (0 <= XINT (tem1) && XINT (tem1) <= INT_MAX)) + xsignal1 (Qargs_out_of_range, tem1); SET_FRAME_COLS (f, XINT (tem1)); } if (!NILP (tem2) && !EQ (tem2, Qunbound)) @@ -4066,12 +4070,10 @@ ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF); - if (INTEGERP (Vtool_bar_button_margin) - && XINT (Vtool_bar_button_margin) > 0) + if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX)) margin = XFASTINT (Vtool_bar_button_margin); else if (CONSP (Vtool_bar_button_margin) - && INTEGERP (XCDR (Vtool_bar_button_margin)) - && XINT (XCDR (Vtool_bar_button_margin)) > 0) + && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin), INT_MAX)) margin = XFASTINT (XCDR (Vtool_bar_button_margin)); else margin = 0; @@ -4097,14 +4099,14 @@ } else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus) && CONSP (XCDR (tem0)) - && INTEGERP (XCAR (XCDR (tem0)))) + && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem0)), INT_MAX)) { f->top_pos = - XINT (XCAR (XCDR (tem0))); window_prompting |= YNegative; } else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus) && CONSP (XCDR (tem0)) - && INTEGERP (XCAR (XCDR (tem0)))) + && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem0)))) { f->top_pos = XINT (XCAR (XCDR (tem0))); } @@ -4125,14 +4127,14 @@ } else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus) && CONSP (XCDR (tem1)) - && INTEGERP (XCAR (XCDR (tem1)))) + && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem1)), INT_MAX)) { f->left_pos = - XINT (XCAR (XCDR (tem1))); window_prompting |= XNegative; } else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus) && CONSP (XCDR (tem1)) - && INTEGERP (XCAR (XCDR (tem1)))) + && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem1)))) { f->left_pos = XINT (XCAR (XCDR (tem1))); } === modified file 'src/frame.h' --- src/frame.h 2011-06-11 21:31:32 +0000 +++ src/frame.h 2011-07-28 21:51:29 +0000 @@ -258,11 +258,11 @@ /* Size of this frame, excluding fringes, scroll bars etc., in units of canonical characters. */ - EMACS_INT text_lines, text_cols; + int text_lines, text_cols; /* Total size of this frame (i.e. its native window), in units of canonical characters. */ - EMACS_INT total_lines, total_cols; + int total_lines, total_cols; /* New text height and width for pending size change. 0 if no change pending. */ === modified file 'src/fringe.c' --- src/fringe.c 2011-06-24 21:25:22 +0000 +++ src/fringe.c 2011-07-28 23:47:01 +0000 @@ -1610,22 +1610,25 @@ if (n == max_fringe_bitmaps) { - if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS) + int bitmaps = max_fringe_bitmaps + 20; + if (MAX_FRINGE_BITMAPS < bitmaps) error ("No free fringe bitmap slots"); i = max_fringe_bitmaps; - max_fringe_bitmaps += 20; fringe_bitmaps = ((struct fringe_bitmap **) - xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *))); + xrealloc (fringe_bitmaps, bitmaps * sizeof *fringe_bitmaps)); fringe_faces - = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object)); + = (Lisp_Object *) xrealloc (fringe_faces, + bitmaps * sizeof *fringe_faces); - for (; i < max_fringe_bitmaps; i++) + for (i = max_fringe_bitmaps; i < bitmaps; i++) { fringe_bitmaps[i] = NULL; fringe_faces[i] = Qnil; } + + max_fringe_bitmaps = bitmaps; } } === modified file 'src/ftfont.c' --- src/ftfont.c 2011-06-18 18:09:17 +0000 +++ src/ftfont.c 2011-07-28 23:51:50 +0000 @@ -682,7 +682,10 @@ if (NILP (val)) continue; len = Flength (val); - spec->features[i] = malloc (sizeof (int) * XINT (len)); + spec->features[i] = + (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len) + ? 0 + : malloc (sizeof (int) * XINT (len))); if (! spec->features[i]) { if (i > 0 && spec->features[0]) @@ -1761,6 +1764,9 @@ static void setup_otf_gstring (int size) { + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (OTF_Glyph) < size) + memory_full (SIZE_MAX); + if (otf_gstring.size == 0) { otf_gstring.glyphs = (OTF_Glyph *) xmalloc (sizeof (OTF_Glyph) * size); @@ -2390,6 +2396,8 @@ struct MFLTFontFT flt_font_ft; MFLT *flt = NULL; int with_variation_selector = 0; + int allocated_max = min (INT_MAX, + min (PTRDIFF_MAX, SIZE_MAX) / sizeof (MFLTGlyph)); if (! m17n_flt_initialized) { @@ -2445,6 +2453,9 @@ } } + if (allocated_max / 2 < len) + memory_full (SIZE_MAX); + if (gstring.allocated == 0) { gstring.allocated = len * 2; @@ -2504,6 +2515,8 @@ int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt); if (result != -2) break; + if (allocated_max / 2 < gstring.allocated) + memory_full (SIZE_MAX); gstring.allocated += gstring.allocated; gstring.glyphs = xrealloc (gstring.glyphs, sizeof (MFLTGlyph) * gstring.allocated); === modified file 'src/gtkutil.c' --- src/gtkutil.c 2011-07-13 15:42:12 +0000 +++ src/gtkutil.c 2011-07-28 23:58:05 +0000 @@ -487,7 +487,8 @@ if (!utf8_str) { /* Probably some control characters in str. Escape them. */ - size_t nr_bad = 0; + ptrdiff_t len; + ptrdiff_t nr_bad = 0; gsize bytes_read; gsize bytes_written; unsigned char *p = (unsigned char *)str; @@ -511,7 +512,10 @@ } if (cp) g_free (cp); - up = utf8_str = xmalloc (strlen (str) + nr_bad * 4 + 1); + len = strlen (str); + if ((min (PTRDIFF_MAX, SIZE_MAX) - len - 1) / 4 < nr_bad) + memory_full (SIZE_MAX); + up = utf8_str = xmalloc (len + nr_bad * 4 + 1); p = (unsigned char *)str; while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read, @@ -3296,8 +3300,8 @@ static struct { GtkWidget **widgets; - int max_size; - int used; + ptrdiff_t max_size; + ptrdiff_t used; } id_to_widget; /* Grow this much every time we need to allocate more */ @@ -3306,15 +3310,20 @@ /* Store the widget pointer W in id_to_widget and return the integer index. */ -static int +static ptrdiff_t xg_store_widget_in_map (GtkWidget *w) { - int i; + ptrdiff_t i; if (id_to_widget.max_size == id_to_widget.used) { - int new_size = id_to_widget.max_size + ID_TO_WIDGET_INCR; + ptrdiff_t new_size; + ptrdiff_t lim = min (TYPE_MAXIMUM (Window), + min (PTRDIFF_MAX, SIZE_MAX) / sizeof (GtkWidget *)); + if (lim - ID_TO_WIDGET_INCR < id_to_widget.max_size) + memory_full (SIZE_MAX); + new_size = id_to_widget.max_size + ID_TO_WIDGET_INCR; id_to_widget.widgets = xrealloc (id_to_widget.widgets, sizeof (GtkWidget *)*new_size); @@ -3345,7 +3354,7 @@ Called when scroll bar is destroyed. */ static void -xg_remove_widget_from_map (int idx) +xg_remove_widget_from_map (ptrdiff_t idx) { if (idx < id_to_widget.max_size && id_to_widget.widgets[idx] != 0) { @@ -3357,7 +3366,7 @@ /* Get the widget pointer at IDX from id_to_widget. */ static GtkWidget * -xg_get_widget_from_map (int idx) +xg_get_widget_from_map (ptrdiff_t idx) { if (idx < id_to_widget.max_size && id_to_widget.widgets[idx] != 0) return id_to_widget.widgets[idx]; @@ -3396,10 +3405,10 @@ /* Return the scrollbar id for X Window WID on display DPY. Return -1 if WID not in id_to_widget. */ -int +ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid) { - int idx; + ptrdiff_t idx; GtkWidget *w; w = xg_win_to_widget (dpy, wid); @@ -3421,7 +3430,7 @@ static void xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data) { - int id = (intptr_t) data; + intptr_t id = (intptr_t) data; xg_remove_widget_from_map (id); } @@ -3496,7 +3505,7 @@ /* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */ void -xg_remove_scroll_bar (FRAME_PTR f, int scrollbar_id) +xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id) { GtkWidget *w = xg_get_widget_from_map (scrollbar_id); if (w) @@ -3515,7 +3524,7 @@ void xg_update_scrollbar_pos (FRAME_PTR f, - int scrollbar_id, + ptrdiff_t scrollbar_id, int top, int left, int width, @@ -4429,7 +4438,7 @@ int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)); int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)); int idx; - int img_id; + ptrdiff_t img_id; int icon_size = 0; struct image *img = NULL; Lisp_Object image; === modified file 'src/gtkutil.h' --- src/gtkutil.h 2011-06-14 21:08:20 +0000 +++ src/gtkutil.h 2011-07-28 23:58:05 +0000 @@ -114,17 +114,17 @@ extern int xg_have_tear_offs (void); -extern int xg_get_scroll_id_for_window (Display *dpy, Window wid); +extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid); extern void xg_create_scroll_bar (FRAME_PTR f, struct scroll_bar *bar, GCallback scroll_callback, GCallback end_callback, const char *scroll_bar_name); -extern void xg_remove_scroll_bar (FRAME_PTR f, int scrollbar_id); +extern void xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id); extern void xg_update_scrollbar_pos (FRAME_PTR f, - int scrollbar_id, + ptrdiff_t scrollbar_id, int top, int left, int width, @@ -185,4 +185,3 @@ #endif /* USE_GTK */ #endif /* GTKUTIL_H */ - === modified file 'src/image.c' --- src/image.c 2011-07-28 09:40:05 +0000 +++ src/image.c 2011-07-29 05:31:12 +0000 @@ -196,7 +196,7 @@ int x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) { - return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; + return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; } #endif @@ -218,9 +218,9 @@ if (dpyinfo->bitmaps == NULL) { + dpyinfo->bitmaps + = (Bitmap_Record *) xmalloc (10 * sizeof (Bitmap_Record)); dpyinfo->bitmaps_size = 10; - dpyinfo->bitmaps - = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record)); dpyinfo->bitmaps_last = 1; return 1; } @@ -235,17 +235,18 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2 < dpyinfo->bitmaps_size) memory_full (SIZE_MAX); - dpyinfo->bitmaps_size *= 2; dpyinfo->bitmaps = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps, - dpyinfo->bitmaps_size * sizeof (Bitmap_Record)); + (dpyinfo->bitmaps_size + * (2 * sizeof (Bitmap_Record)))); + dpyinfo->bitmaps_size *= 2; return ++dpyinfo->bitmaps_last; } /* Add one reference to the reference count of the bitmap with id ID. */ void -x_reference_bitmap (FRAME_PTR f, int id) +x_reference_bitmap (FRAME_PTR f, ptrdiff_t id) { ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; } @@ -807,29 +808,30 @@ break; case IMAGE_POSITIVE_INTEGER_VALUE: - if (!INTEGERP (value) || XINT (value) <= 0) + if (! RANGED_INTEGERP (1, value, INT_MAX)) return 0; break; case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR: - if (INTEGERP (value) && XINT (value) >= 0) + if (RANGED_INTEGERP (1, value, INT_MAX)) break; if (CONSP (value) - && INTEGERP (XCAR (value)) && INTEGERP (XCDR (value)) - && XINT (XCAR (value)) >= 0 && XINT (XCDR (value)) >= 0) + && RANGED_INTEGERP (1, XCAR (value), INT_MAX) + && RANGED_INTEGERP (1, XCDR (value), INT_MAX)) break; return 0; case IMAGE_ASCENT_VALUE: if (SYMBOLP (value) && EQ (value, Qcenter)) break; - else if (INTEGERP (value) - && XINT (value) >= 0 - && XINT (value) <= 100) + else if (RANGED_INTEGERP (0, value, 100)) break; return 0; case IMAGE_NON_NEGATIVE_INTEGER_VALUE: + /* Unlike the other integer-related cases, this one does not + verify that VALUE fits in 'int'. This is because callers + want EMACS_INT. */ if (!INTEGERP (value) || XINT (value) < 0) return 0; break; @@ -849,7 +851,7 @@ break; case IMAGE_INTEGER_VALUE: - if (!INTEGERP (value)) + if (! TYPE_RANGED_INTEGERP (int, value)) return 0; break; @@ -919,7 +921,7 @@ if (valid_image_p (spec)) { struct frame *f = check_x_frame (frame); - int id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec); struct image *img = IMAGE_FROM_ID (f, id); int width = img->width + 2 * img->hmargin; int height = img->height + 2 * img->vmargin; @@ -949,7 +951,7 @@ if (valid_image_p (spec)) { struct frame *f = check_x_frame (frame); - int id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec); struct image *img = IMAGE_FROM_ID (f, id); if (img->mask) mask = Qt; @@ -972,7 +974,7 @@ if (valid_image_p (spec)) { struct frame *f = check_x_frame (frame); - int id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec); struct image *img = IMAGE_FROM_ID (f, id); ext = img->lisp_data; } @@ -1121,7 +1123,7 @@ ascent = height / 2; } else - ascent = (int) (height * img->ascent / 100.0); + ascent = height * (img->ascent / 100.0); return ascent; } @@ -1367,11 +1369,12 @@ { /* This isn't called frequently so we get away with simply reallocating the color vector to the needed size, here. */ - ++img->ncolors; + ptrdiff_t ncolors = img->ncolors + 1; img->colors = (unsigned long *) xrealloc (img->colors, - img->ncolors * sizeof *img->colors); - img->colors[img->ncolors - 1] = color.pixel; + ncolors * sizeof *img->colors); + img->colors[ncolors - 1] = color.pixel; + img->ncolors = ncolors; result = color.pixel; } else @@ -1399,8 +1402,9 @@ int size; memset (c, 0, sizeof *c); - c->size = 50; - c->images = (struct image **) xmalloc (c->size * sizeof *c->images); + size = 50; + c->images = (struct image **) xmalloc (size * sizeof *c->images); + c->size = size; size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; c->buckets = (struct image **) xmalloc (size); memset (c->buckets, 0, size); @@ -1466,7 +1470,7 @@ struct image_cache *c = FRAME_IMAGE_CACHE (f); if (c) { - int i; + ptrdiff_t i; /* Cache should not be referenced by any frame when freed. */ xassert (c->refcount == 0); @@ -1496,7 +1500,7 @@ if (c) { - int i, nfreed = 0; + ptrdiff_t i, nfreed = 0; /* Block input so that we won't be interrupted by a SIGIO while being in an inconsistent state. */ @@ -1520,8 +1524,8 @@ { /* Free cache based on timestamp. */ EMACS_TIME t; - time_t old; - int delay, nimages = 0; + double old, delay; + ptrdiff_t nimages = 0; for (i = 0; i < c->used; ++i) if (c->images[i]) @@ -1529,9 +1533,10 @@ /* If the number of cached images has grown unusually large, decrease the cache eviction delay (Bug#6230). */ - delay = XFASTINT (Vimage_cache_eviction_delay); + delay = XINT (Vimage_cache_eviction_delay); if (nimages > 40) - delay = max (1, 1600 * delay / (nimages*nimages)); + delay = 1600 * delay / nimages / nimages; + delay = max (delay, 1); EMACS_GET_TIME (t); old = EMACS_SECS (t) - delay; @@ -1707,7 +1712,7 @@ /* Return the id of image with Lisp specification SPEC on frame F. SPEC must be a valid Lisp image specification (see valid_image_p). */ -int +ptrdiff_t lookup_image (struct frame *f, Lisp_Object spec) { struct image *img; @@ -1766,15 +1771,12 @@ img->ascent = CENTERED_IMAGE_ASCENT; margin = image_spec_value (spec, QCmargin, NULL); - if (INTEGERP (margin) && XINT (margin) >= 0) + if (INTEGERP (margin)) img->vmargin = img->hmargin = XFASTINT (margin); - else if (CONSP (margin) && INTEGERP (XCAR (margin)) - && INTEGERP (XCDR (margin))) + else if (CONSP (margin)) { - if (XINT (XCAR (margin)) > 0) - img->hmargin = XFASTINT (XCAR (margin)); - if (XINT (XCDR (margin)) > 0) - img->vmargin = XFASTINT (XCDR (margin)); + img->hmargin = XFASTINT (XCAR (margin)); + img->vmargin = XFASTINT (XCDR (margin)); } relief = image_spec_value (spec, QCrelief, NULL); @@ -1821,7 +1823,7 @@ cache_image (struct frame *f, struct image *img) { struct image_cache *c = FRAME_IMAGE_CACHE (f); - int i; + ptrdiff_t i; /* Find a free slot in c->images. */ for (i = 0; i < c->used; ++i) @@ -1833,9 +1835,10 @@ { if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size) memory_full (SIZE_MAX); + c->images = + (struct image **) xrealloc (c->images, + c->size * (2 * sizeof *c->images)); c->size *= 2; - c->images = (struct image **) xrealloc (c->images, - c->size * sizeof *c->images); } /* Add IMG to c->images, and assign IMG an id. */ @@ -1875,7 +1878,7 @@ { if (c) { - int i; + ptrdiff_t i; for (i = 0; i < c->used; ++i) if (c->images[i]) mark_image (c->images[i]); @@ -2072,7 +2075,7 @@ DWORD err = GetLastError (); Lisp_Object errcode; /* All system errors are < 10000, so the following is safe. */ - XSETINT (errcode, (int) err); + XSETINT (errcode, err); image_error ("Unable to create bitmap, error code %d", errcode, Qnil); x_destroy_x_image (*ximg); return 0; @@ -2351,7 +2354,7 @@ else { Lisp_Object data; - EMACS_INT width, height; + int width, height; /* Entries for `:width', `:height' and `:data' must be present. */ if (!kw[XBM_WIDTH].count @@ -3583,9 +3586,12 @@ #endif /* HAVE_NTGUI */ /* Remember allocated colors. */ - img->ncolors = attrs.nalloc_pixels; + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors + < attrs.nalloc_pixels) + memory_full (SIZE_MAX); img->colors = (unsigned long *) xmalloc (img->ncolors * sizeof *img->colors); + img->ncolors = attrs.nalloc_pixels; for (i = 0; i < attrs.nalloc_pixels; ++i) { img->colors[i] = attrs.alloc_pixels[i]; @@ -3809,8 +3815,8 @@ int chars_len) { struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); - int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len), - NULL); + ptrdiff_t i = + hash_lookup (table, make_unibyte_string (chars_start, chars_len), NULL); return i >= 0 ? HASH_VALUE (table, i) : Qnil; } @@ -4159,6 +4165,12 @@ /* Number of entries in the color table. */ static int ct_colors_allocated; +enum +{ + ct_colors_allocated_max = + min (INT_MAX, + min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long)) +}; /* Initialize the color table. */ @@ -4245,7 +4257,14 @@ XColor color; Colormap cmap; int rc; - +#else + COLORREF color; +#endif + + if (ct_colors_allocated_max <= ct_colors_allocated) + return FRAME_FOREGROUND_PIXEL (f); + +#ifdef HAVE_X_WINDOWS color.red = r; color.green = g; color.blue = b; @@ -4267,7 +4286,6 @@ return FRAME_FOREGROUND_PIXEL (f); #else - COLORREF color; #ifdef HAVE_NTGUI color = PALETTERGB (r, g, b); #else @@ -4308,6 +4326,9 @@ Colormap cmap; int rc; + if (ct_colors_allocated_max <= ct_colors_allocated) + return FRAME_FOREGROUND_PIXEL (f); + #ifdef HAVE_X_WINDOWS cmap = FRAME_X_COLORMAP (f); color.pixel = pixel; @@ -4446,7 +4467,9 @@ HGDIOBJ prev; #endif /* HAVE_NTGUI */ - colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors); + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height) + memory_full (SIZE_MAX); + colors = (XColor *) xmalloc (sizeof *colors * img->width * img->height); #ifndef HAVE_NTGUI /* Get the X image IMG->pixmap. */ @@ -4598,7 +4621,9 @@ #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) - new = (XColor *) xmalloc (img->width * img->height * sizeof *new); + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height) + memory_full (SIZE_MAX); + new = (XColor *) xmalloc (sizeof *new * img->width * img->height); for (y = 0; y < img->height; ++y) { @@ -5876,7 +5901,7 @@ for (x = 0; x < width; ++x) { - unsigned r, g, b; + int r, g, b; r = *p++ << 8; g = *p++ << 8; @@ -6741,17 +6766,29 @@ } +static void tiff_handler (const char *, const char *, const char *, va_list) + ATTRIBUTE_FORMAT_PRINTF (3, 0); +static void +tiff_handler (const char *log_format, const char *title, + const char *format, va_list ap) +{ + /* doprnt is not suitable here, as TIFF handlers are called from + libtiff and are passed arbitrary printf directives. Instead, use + vsnprintf, taking care to be portable to nonstandard environments + where vsnprintf returns -1 on buffer overflow. Since it's just a + log entry, it's OK to truncate it. */ + char buf[4000]; + int len = vsnprintf (buf, sizeof buf, format, ap); + add_to_log (log_format, build_string (title), + make_string (buf, max (0, min (len, sizeof buf - 1)))); +} + static void tiff_error_handler (const char *, const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (2, 0); static void tiff_error_handler (const char *title, const char *format, va_list ap) { - char buf[512]; - int len; - - len = sprintf (buf, "TIFF error: %s ", title); - vsprintf (buf + len, format, ap); - add_to_log (buf, Qnil, Qnil); + tiff_handler ("TIFF error: %s %s", title, format, ap); } @@ -6760,12 +6797,7 @@ static void tiff_warning_handler (const char *title, const char *format, va_list ap) { - char buf[512]; - int len; - - len = sprintf (buf, "TIFF warning: %s ", title); - vsprintf (buf + len, format, ap); - add_to_log (buf, Qnil, Qnil); + tiff_handler ("TIFF warning: %s %s", title, format, ap); } @@ -6841,8 +6873,9 @@ image = image_spec_value (img->spec, QCindex, NULL); if (INTEGERP (image)) { - int ino = XFASTINT (image); - if (!fn_TIFFSetDirectory (tiff, ino)) + EMACS_INT ino = XFASTINT (image); + if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t) + && fn_TIFFSetDirectory (tiff, ino))) { image_error ("Invalid image number `%s' in image `%s'", image, img->spec); @@ -7141,7 +7174,7 @@ Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL); Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL); unsigned long bgcolor = 0; - int idx; + EMACS_INT idx; if (NILP (specified_data)) { @@ -7371,7 +7404,7 @@ img->lisp_data = Qnil; if (gif->SavedImages[idx].ExtensionBlockCount > 0) { - unsigned int delay = 0; + int delay = 0; ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks; for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++) /* Append (... FUNCTION "BYTES") */ @@ -7392,7 +7425,7 @@ if (delay) img->lisp_data = Fcons (Qdelay, - Fcons (make_float (((double) delay) * 0.01), + Fcons (make_float (delay / 100.0), img->lisp_data)); } @@ -7568,10 +7601,10 @@ Lisp_Object image; Lisp_Object value; Lisp_Object crop; - long ino; + EMACS_INT ino; int desired_width, desired_height; double rotation; - int imagemagick_rendermethod; + EMACS_INT imagemagick_rendermethod; int pixelwidth; ImageInfo *image_info; ExceptionInfo *exception; @@ -7598,7 +7631,7 @@ status = MagickPingImageBlob (ping_wand, contents, size); } - if (ino >= MagickGetNumberImages (ping_wand)) + if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand))) { image_error ("Invalid image number `%s' in image `%s'", image, img->spec); @@ -7673,28 +7706,28 @@ efficient. */ crop = image_spec_value (img->spec, QCcrop, NULL); - if (CONSP (crop) && INTEGERP (XCAR (crop))) + if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop))) { /* After some testing, it seems MagickCropImage is the fastest crop function in ImageMagick. This crop function seems to do less copying than the alternatives, but it still reads the entire image into memory - before croping, which is aparently difficult to avoid when using + before cropping, which is apparently difficult to avoid when using imagemagick. */ - int w, h; - w = XFASTINT (XCAR (crop)); + size_t crop_width = XINT (XCAR (crop)); crop = XCDR (crop); - if (CONSP (crop) && INTEGERP (XCAR (crop))) + if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop))) { - h = XFASTINT (XCAR (crop)); + size_t crop_height = XINT (XCAR (crop)); crop = XCDR (crop); - if (CONSP (crop) && INTEGERP (XCAR (crop))) + if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop))) { - x = XFASTINT (XCAR (crop)); + ssize_t crop_x = XINT (XCAR (crop)); crop = XCDR (crop); - if (CONSP (crop) && INTEGERP (XCAR (crop))) + if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop))) { - y = XFASTINT (XCAR (crop)); - MagickCropImage (image_wand, w, h, x, y); + ssize_t crop_y = XINT (XCAR (crop)); + MagickCropImage (image_wand, crop_width, crop_height, + crop_x, crop_y); } } } @@ -7740,9 +7773,11 @@ init_color_table (); imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type) - ? XFASTINT (Vimagemagick_render_type) : 0); + ? XINT (Vimagemagick_render_type) : 0); if (imagemagick_rendermethod == 0) { + size_t image_height; + /* Try to create a x pixmap to hold the imagemagick pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) @@ -7771,7 +7806,8 @@ goto imagemagick_error; } - for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++) + image_height = MagickGetImageHeight (image_wand); + for (y = 0; y < image_height; y++) { pixels = PixelGetNextIteratorRow (iterator, &width); if (pixels == (PixelWand **) NULL) @@ -8277,10 +8313,10 @@ { for (x = 0; x < width; ++x) { - unsigned red; - unsigned green; - unsigned blue; - unsigned opacity; + int red; + int green; + int blue; + int opacity; red = *pixels++; green = *pixels++; @@ -8461,7 +8497,8 @@ static int gs_load (struct frame *f, struct image *img) { - char buffer[100]; + uprintmax_t printnum1, printnum2; + char buffer[sizeof " " + INT_STRLEN_BOUND (printmax_t)]; Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; Lisp_Object frame; double in_width, in_height; @@ -8473,16 +8510,19 @@ info. */ pt_width = image_spec_value (img->spec, QCpt_width, NULL); in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0; - img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx; + in_width *= FRAME_X_DISPLAY_INFO (f)->resx; pt_height = image_spec_value (img->spec, QCpt_height, NULL); in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0; - img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; + in_height *= FRAME_X_DISPLAY_INFO (f)->resy; - if (!check_image_size (f, img->width, img->height)) + if (! (in_width <= INT_MAX && in_height <= INT_MAX + && check_image_size (f, in_width, in_height))) { image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); return 0; } + img->width = in_width; + img->height = in_height; /* Create the pixmap. */ xassert (img->pixmap == NO_PIXMAP); @@ -8507,14 +8547,14 @@ if successful. We do not record_unwind_protect here because other places in redisplay like calling window scroll functions don't either. Let the Lisp loader use `unwind-protect' instead. */ - sprintf (buffer, "%lu %lu", - (unsigned long) FRAME_X_WINDOW (f), - (unsigned long) img->pixmap); + printnum1 = FRAME_X_WINDOW (f); + printnum2 = img->pixmap; + sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2); window_and_pixmap_id = build_string (buffer); - sprintf (buffer, "%lu %lu", - FRAME_FOREGROUND_PIXEL (f), - FRAME_BACKGROUND_PIXEL (f)); + printnum1 = FRAME_FOREGROUND_PIXEL (f); + printnum2 = FRAME_BACKGROUND_PIXEL (f); + sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2); pixel_colors = build_string (buffer); XSETFRAME (frame, f); @@ -8539,7 +8579,8 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f) { struct image_cache *c = FRAME_IMAGE_CACHE (f); - int class, i; + int class; + ptrdiff_t i; struct image *img; /* Find the image containing PIXMAP. */ @@ -8643,7 +8684,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") (Lisp_Object spec) { - int id = -1; + ptrdiff_t id = -1; if (valid_image_p (spec)) id = lookup_image (SELECTED_FRAME (), spec); === modified file 'src/indent.c' --- src/indent.c 2011-07-14 21:35:23 +0000 +++ src/indent.c 2011-07-19 00:42:24 +0000 @@ -284,7 +284,7 @@ else \ { \ if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \ - width = ASIZE (DISP_CHAR_VECTOR (dp, ch)); \ + width = sanitize_char_width (ASIZE (DISP_CHAR_VECTOR (dp, ch))); \ else \ width = CHAR_WIDTH (ch); \ } \ @@ -318,15 +318,6 @@ last_known_column_point = 0; } -/* Return a non-outlandish value for the tab width. */ - -static int -sane_tab_width (void) -{ - EMACS_INT n = XFASTINT (BVAR (current_buffer, tab_width)); - return 0 < n && n <= 1000 ? n : 8; -} - EMACS_INT current_column (void) { @@ -335,7 +326,7 @@ register int tab_seen; EMACS_INT post_tab; register int c; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); register struct Lisp_Char_Table *dp = buffer_display_table (); @@ -515,7 +506,7 @@ static void scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) { - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); register struct Lisp_Char_Table *dp = buffer_display_table (); int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); @@ -732,7 +723,7 @@ register int tab_seen; int post_tab; register int c; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); int ctl_arrow = !NILP (current_buffer->ctl_arrow); register struct Lisp_Char_Table *dp = buffer_display_table (); int b, e; @@ -808,7 +799,7 @@ { EMACS_INT mincol; register EMACS_INT fromcol; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); CHECK_NUMBER (column); if (NILP (minimum)) @@ -867,7 +858,7 @@ position_indentation (register int pos_byte) { register EMACS_INT column = 0; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); register unsigned char *p; register unsigned char *stop; unsigned char *start; @@ -1116,7 +1107,7 @@ register EMACS_INT pos; EMACS_INT pos_byte; register int c = 0; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); register struct Lisp_Char_Table *dp = window_display_table (win); EMACS_INT selective === modified file 'src/keyboard.c' --- src/keyboard.c 2011-07-14 20:40:35 +0000 +++ src/keyboard.c 2011-07-29 00:30:00 +0000 @@ -435,16 +435,16 @@ static int read_avail_input (int); static void get_input_pending (int *, int); static int readable_events (int); -static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *, +static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *, Lisp_Object, int *); -static Lisp_Object read_char_minibuf_menu_prompt (int, int, +static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t, Lisp_Object *); static Lisp_Object make_lispy_event (struct input_event *); #if defined (HAVE_MOUSE) || defined (HAVE_GPM) static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object, enum scroll_bar_part, Lisp_Object, Lisp_Object, - unsigned long); + Time); #endif static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object, Lisp_Object, const char *const *, @@ -1300,7 +1300,7 @@ /* This is the actual command reading loop, sans error-handling encapsulation. */ -static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object, +static int read_key_sequence (Lisp_Object *, int, Lisp_Object, int, int, int); void safe_run_hooks (Lisp_Object); static void adjust_point_for_property (EMACS_INT, int); @@ -2267,7 +2267,8 @@ Value is t if we showed a menu and the user rejected it. */ Lisp_Object -read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event, +read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, + Lisp_Object prev_event, int *used_mouse_menu, struct timeval *end_time) { volatile Lisp_Object c; @@ -7405,7 +7406,7 @@ { /* The number of keymaps we're scanning right now, and the number of keymaps we have allocated space for. */ - int nmaps; + ptrdiff_t nmaps; /* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1] in the current keymaps, or nil where it is not a prefix. */ @@ -7413,7 +7414,7 @@ Lisp_Object def, tail; - int mapno; + ptrdiff_t mapno; Lisp_Object oquit; /* In order to build the menus, we need to call the keymap @@ -7458,7 +7459,7 @@ recognized when the menu-bar (or mode-line) is updated, which does not normally happen after every command. */ Lisp_Object tem; - int nminor; + ptrdiff_t nminor; nminor = current_minor_maps (NULL, &tmaps); maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); nmaps = 0; @@ -7962,7 +7963,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems) { Lisp_Object *maps; - int nmaps, i; + ptrdiff_t nmaps, i; Lisp_Object oquit; Lisp_Object *tmaps; @@ -8002,7 +8003,7 @@ recognized when the tool-bar (or mode-line) is updated, which does not normally happen after every command. */ Lisp_Object tem; - int nminor; + ptrdiff_t nminor; nminor = current_minor_maps (NULL, &tmaps); maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); nmaps = 0; @@ -8274,10 +8275,11 @@ Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION); const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : ""; const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : ""; - EMACS_INT max_lbl = 2 * tool_bar_max_label_size; + ptrdiff_t max_lbl = + 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)); char *buf = (char *) xmalloc (max_lbl + 1); Lisp_Object new_lbl; - size_t caption_len = strlen (capt); + ptrdiff_t caption_len = strlen (capt); if (caption_len <= max_lbl && capt[0] != '\0') { @@ -8290,7 +8292,7 @@ if (strlen (label) <= max_lbl && label[0] != '\0') { - int j; + ptrdiff_t j; if (label != buf) strcpy (buf, label); @@ -8399,10 +8401,10 @@ and do auto-saving in the inner call of read_char. */ static Lisp_Object -read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event, - int *used_mouse_menu) +read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps, + Lisp_Object prev_event, int *used_mouse_menu) { - int mapno; + ptrdiff_t mapno; if (used_mouse_menu) *used_mouse_menu = 0; @@ -8430,7 +8432,7 @@ Lisp_Object *realmaps = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); Lisp_Object value; - int nmaps1 = 0; + ptrdiff_t nmaps1 = 0; /* Use the maps that are not nil. */ for (mapno = 0; mapno < nmaps; mapno++) @@ -8481,17 +8483,18 @@ We make this bigger when necessary, and never free it. */ static char *read_char_minibuf_menu_text; /* Size of that buffer. */ -static int read_char_minibuf_menu_width; +static ptrdiff_t read_char_minibuf_menu_width; static Lisp_Object -read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) +read_char_minibuf_menu_prompt (int commandflag, + ptrdiff_t nmaps, Lisp_Object *maps) { - int mapno; + ptrdiff_t mapno; register Lisp_Object name; - int nlength; + ptrdiff_t nlength; /* FIXME: Use the minibuffer's frame width. */ - int width = FRAME_COLS (SELECTED_FRAME ()) - 4; - int idx = -1; + ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4; + ptrdiff_t idx = -1; int nobindings = 1; Lisp_Object rest, vector; char *menu; @@ -8516,16 +8519,13 @@ /* Make sure we have a big enough buffer for the menu text. */ width = max (width, SBYTES (name)); - if (read_char_minibuf_menu_text == 0) - { - read_char_minibuf_menu_width = width + 4; - read_char_minibuf_menu_text = (char *) xmalloc (width + 4); - } - else if (width + 4 > read_char_minibuf_menu_width) - { - read_char_minibuf_menu_width = width + 4; + if (STRING_BYTES_BOUND - 4 < width) + memory_full (SIZE_MAX); + if (width + 4 > read_char_minibuf_menu_width) + { read_char_minibuf_menu_text = (char *) xrealloc (read_char_minibuf_menu_text, width + 4); + read_char_minibuf_menu_width = width + 4; } menu = read_char_minibuf_menu_text; @@ -8544,7 +8544,7 @@ while (1) { int notfirst = 0; - int i = nlength; + ptrdiff_t i = nlength; Lisp_Object obj; Lisp_Object orig_defn_macro; @@ -8643,7 +8643,7 @@ < width || !notfirst) { - int thiswidth; + ptrdiff_t thiswidth; /* Punctuate between strings. */ if (notfirst) @@ -8659,9 +8659,7 @@ if (! char_matches) { /* Add as much of string as fits. */ - thiswidth = SCHARS (desc); - if (thiswidth + i > width) - thiswidth = width - i; + thiswidth = min (SCHARS (desc), width - i); memcpy (menu + i, SDATA (desc), thiswidth); i += thiswidth; strcpy (menu + i, " = "); @@ -8669,9 +8667,7 @@ } /* Add as much of string as fits. */ - thiswidth = SCHARS (s); - if (thiswidth + i > width) - thiswidth = width - i; + thiswidth = min (SCHARS (s), width - i); memcpy (menu + i, SDATA (s), thiswidth); i += thiswidth; menu[i] = 0; @@ -8746,10 +8742,10 @@ NEXT may be the same array as CURRENT. */ static int -follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs, - Lisp_Object *next) +follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current, + Lisp_Object *defs, Lisp_Object *next) { - int i, first_binding; + ptrdiff_t i, first_binding; first_binding = nmaps; for (i = nmaps - 1; i >= 0; i--) @@ -8849,7 +8845,7 @@ The return value is non-zero if the remapping actually took place. */ static int -keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey, +keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey, int input, int doit, int *diff, Lisp_Object prompt) { Lisp_Object next, key; @@ -8871,7 +8867,7 @@ *diff = len - (fkey->end - fkey->start); - if (input + *diff >= bufsize) + if (bufsize - input <= *diff) error ("Key sequence too long"); /* Shift the keys that follow fkey->end. */ @@ -8942,7 +8938,7 @@ from the selected window's buffer. */ static int -read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, +read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, int dont_downcase_last, int can_return_switch_frame, int fix_current_buffer) { @@ -8959,8 +8955,8 @@ /* The number of keymaps we're scanning right now, and the number of keymaps we have allocated space for. */ - int nmaps; - int nmaps_allocated = 0; + ptrdiff_t nmaps; + ptrdiff_t nmaps_allocated = 0; /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in the current keymaps. */ @@ -8984,7 +8980,7 @@ /* The index in submaps[] of the first keymap that has a binding for this key sequence. In other words, the lowest i such that submaps[i] is non-nil. */ - int first_binding; + ptrdiff_t first_binding; /* Index of the first key that has no binding. It is useless to try fkey.start larger than that. */ int first_unbound; @@ -9145,8 +9141,8 @@ } else { - int nminor; - int total; + ptrdiff_t nminor; + ptrdiff_t total; Lisp_Object *maps; nminor = current_minor_maps (0, &maps); @@ -9212,7 +9208,8 @@ echo_local_start and keys_local_start allow us to throw away just one key. */ int echo_local_start IF_LINT (= 0); - int keys_local_start, local_first_binding; + int keys_local_start; + ptrdiff_t local_first_binding; eassert (indec.end == t || (indec.end > t && indec.end <= mock_input)); eassert (indec.start <= indec.end); @@ -9549,7 +9546,7 @@ && (NILP (fake_prefixed_keys) || NILP (Fmemq (key, fake_prefixed_keys)))) { - if (t + 1 >= bufsize) + if (bufsize - t <= 1) error ("Key sequence too long"); keybuf[t] = posn; @@ -9630,7 +9627,7 @@ insert the dummy prefix event `menu-bar'. */ if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) { - if (t + 1 >= bufsize) + if (bufsize - t <= 1) error ("Key sequence too long"); keybuf[t] = posn; keybuf[t+1] = key; === modified file 'src/keyboard.h' --- src/keyboard.h 2011-07-07 17:55:38 +0000 +++ src/keyboard.h 2011-07-29 00:30:00 +0000 @@ -440,7 +440,7 @@ extern Lisp_Object parse_modifiers (Lisp_Object); extern Lisp_Object reorder_modifiers (Lisp_Object); -extern Lisp_Object read_char (int, int, Lisp_Object *, Lisp_Object, +extern Lisp_Object read_char (int, ptrdiff_t, Lisp_Object *, Lisp_Object, int *, EMACS_TIME *); extern int parse_solitary_modifier (Lisp_Object symbol); === modified file 'src/keymap.c' --- src/keymap.c 2011-07-12 21:12:36 +0000 +++ src/keymap.c 2011-07-29 00:32:09 +0000 @@ -1403,7 +1403,7 @@ some systems, static gets macro-defined to be the empty string. Ickypoo. */ static Lisp_Object *cmm_modes = NULL, *cmm_maps = NULL; -static int cmm_size = 0; +static ptrdiff_t cmm_size = 0; /* Store a pointer to an array of the currently active minor modes in *modeptr, a pointer to an array of the keymaps of the currently @@ -1423,10 +1423,10 @@ loop. Instead, we'll use realloc/malloc and silently truncate the list, let the key sequence be read, and hope some other piece of code signals the error. */ -int +ptrdiff_t current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr) { - int i = 0; + ptrdiff_t i = 0; int list_number = 0; Lisp_Object alist, assoc, var, val; Lisp_Object emulation_alists; @@ -1469,9 +1469,16 @@ if (i >= cmm_size) { - int newsize, allocsize; + ptrdiff_t newsize, allocsize; Lisp_Object *newmodes, *newmaps; + /* Check for size calculation overflow. Other code + (e.g., read_key_sequence) adds 3 to the count + later, so subtract 3 from the limit here. */ + if (min (PTRDIFF_MAX, SIZE_MAX) / (2 * sizeof *newmodes) - 3 + < cmm_size) + break; + newsize = cmm_size == 0 ? 30 : cmm_size * 2; allocsize = newsize * sizeof *newmodes; === modified file 'src/keymap.h' --- src/keymap.h 2011-07-07 17:19:10 +0000 +++ src/keymap.h 2011-07-29 00:32:09 +0000 @@ -38,7 +38,7 @@ EXFUN (Fset_keymap_parent, 2); extern int describe_map_tree (Lisp_Object, int, Lisp_Object, Lisp_Object, const char *, int, int, int, int); -extern int current_minor_maps (Lisp_Object **, Lisp_Object **); +extern ptrdiff_t current_minor_maps (Lisp_Object **, Lisp_Object **); extern void initial_define_key (Lisp_Object, int, const char *); extern void initial_define_lispy_key (Lisp_Object, const char *, const char *); extern void syms_of_keymap (void); === modified file 'src/lisp.h' --- src/lisp.h 2011-07-08 00:51:25 +0000 +++ src/lisp.h 2011-07-28 21:31:33 +0000 @@ -1704,6 +1704,11 @@ #define NUMBERP(x) (INTEGERP (x) || FLOATP (x)) #define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0) +#define RANGED_INTEGERP(lo, x, hi) \ + (INTEGERP (x) && (lo) <= XINT (x) && XINT (x) <= (hi)) +#define TYPE_RANGED_INTEGERP(type, x) \ + RANGED_INTEGERP (TYPE_MINIMUM (type), x, TYPE_MAXIMUM (type)) + #define INTEGERP(x) (LISP_INT_TAG_P (XTYPE ((x)))) #define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol) #define MISCP(x) (XTYPE ((x)) == Lisp_Misc) @@ -2551,6 +2556,7 @@ /* Defined in fns.c */ extern Lisp_Object QCrehash_size, QCrehash_threshold; +enum { NEXT_ALMOST_PRIME_LIMIT = 11 }; extern EMACS_INT next_almost_prime (EMACS_INT); extern Lisp_Object larger_vector (Lisp_Object, EMACS_INT, Lisp_Object); extern void sweep_weak_hash_tables (void); @@ -2562,8 +2568,8 @@ Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -EMACS_INT hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); -EMACS_INT hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, +ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); +ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, EMACS_UINT); void init_weak_hash_tables (void); extern void init_fns (void); === modified file 'src/lread.c' --- src/lread.c 2011-07-28 20:23:19 +0000 +++ src/lread.c 2011-07-29 05:31:12 +0000 @@ -2613,14 +2613,14 @@ if (saved_doc_string_size == 0) { + saved_doc_string = (char *) xmalloc (nskip + extra); saved_doc_string_size = nskip + extra; - saved_doc_string = (char *) xmalloc (saved_doc_string_size); } if (nskip > saved_doc_string_size) { - saved_doc_string_size = nskip + extra; saved_doc_string = (char *) xrealloc (saved_doc_string, - saved_doc_string_size); + nskip + extra); + saved_doc_string_size = nskip + extra; } saved_doc_string_position = file_tell (instream); @@ -2883,7 +2883,8 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size) memory_full (SIZE_MAX); read_buffer = (char *) xrealloc (read_buffer, - read_buffer_size *= 2); + read_buffer_size * 2); + read_buffer_size *= 2; p = read_buffer + offset; end = read_buffer + read_buffer_size; } @@ -3026,7 +3027,8 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size) memory_full (SIZE_MAX); read_buffer = (char *) xrealloc (read_buffer, - read_buffer_size *= 2); + read_buffer_size * 2); + read_buffer_size *= 2; p = read_buffer + offset; end = read_buffer + read_buffer_size; } @@ -3056,7 +3058,8 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size) memory_full (SIZE_MAX); read_buffer = (char *) xrealloc (read_buffer, - read_buffer_size *= 2); + read_buffer_size * 2); + read_buffer_size *= 2; p = read_buffer + offset; end = read_buffer + read_buffer_size; } @@ -3938,6 +3941,7 @@ init_obarray (void) { Lisp_Object oblength; + ptrdiff_t size = 100 + MAX_MULTIBYTE_LENGTH; XSETFASTINT (oblength, OBARRAY_SIZE); @@ -3970,8 +3974,8 @@ DEFSYM (Qvariable_documentation, "variable-documentation"); - read_buffer_size = 100 + MAX_MULTIBYTE_LENGTH; - read_buffer = (char *) xmalloc (read_buffer_size); + read_buffer = (char *) xmalloc (size); + read_buffer_size = size; } \f void === modified file 'src/macros.c' --- src/macros.c 2011-06-24 21:25:22 +0000 +++ src/macros.c 2011-07-29 01:00:29 +0000 @@ -62,9 +62,9 @@ if (!current_kboard->kbd_macro_buffer) { - current_kboard->kbd_macro_bufsize = 30; current_kboard->kbd_macro_buffer = (Lisp_Object *)xmalloc (30 * sizeof (Lisp_Object)); + current_kboard->kbd_macro_bufsize = 30; } update_mode_lines++; if (NILP (append)) @@ -202,7 +202,7 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *kb->kbd_macro_buffer / 2 < kb->kbd_macro_bufsize) memory_full (SIZE_MAX); - nbytes = kb->kbd_macro_bufsize * 2 * sizeof *kb->kbd_macro_buffer; + nbytes = kb->kbd_macro_bufsize * (2 * sizeof *kb->kbd_macro_buffer); kb->kbd_macro_buffer = (Lisp_Object *) xrealloc (kb->kbd_macro_buffer, nbytes); kb->kbd_macro_bufsize *= 2; === modified file 'src/minibuf.c' --- src/minibuf.c 2011-07-19 17:33:06 +0000 +++ src/minibuf.c 2011-07-29 01:01:17 +0000 @@ -261,7 +261,10 @@ if (len == size) { if (STRING_BYTES_BOUND / 2 < size) - memory_full (SIZE_MAX); + { + xfree (line); + memory_full (SIZE_MAX); + } size *= 2; line = (char *) xrealloc (line, size); } @@ -1723,7 +1726,7 @@ (Lisp_Object string, Lisp_Object collection, Lisp_Object predicate) { Lisp_Object regexps, tail, tem = Qnil; - EMACS_INT i = 0; + ptrdiff_t i = 0; CHECK_STRING (string); === modified file 'src/nsmenu.m' --- src/nsmenu.m 2011-07-28 18:30:59 +0000 +++ src/nsmenu.m 2011-07-29 05:31:12 +0000 @@ -1014,7 +1014,7 @@ BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P)); BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P)); int idx; - int img_id; + ptrdiff_t img_id; struct image *img; Lisp_Object image; Lisp_Object helpObj; === modified file 'src/nsterm.h' --- src/nsterm.h 2011-07-28 18:50:05 +0000 +++ src/nsterm.h 2011-07-29 05:31:12 +0000 @@ -416,8 +416,8 @@ /* this to map between emacs color indices and NSColor objects */ struct ns_color_table { - unsigned int size; - unsigned int avail; + ptrdiff_t size; + ptrdiff_t avail; #ifdef __OBJC__ NSColor **colors; NSMutableSet *empty_indices; === modified file 'src/nsterm.m' --- src/nsterm.m 2011-07-28 18:41:21 +0000 +++ src/nsterm.m 2011-07-29 05:31:12 +0000 @@ -1341,7 +1341,7 @@ ns_index_color (NSColor *color, struct frame *f) { struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table; - int idx; + ptrdiff_t idx; NSNumber *index; if (!color_table->colors) @@ -1356,7 +1356,7 @@ /* do we already have this color ? */ { - int i; + ptrdiff_t i; for (i = 1; i < color_table->avail; i++) { if (color_table->colors[i] && [color_table->colors[i] isEqual: color]) @@ -1371,16 +1371,23 @@ { index = [color_table->empty_indices anyObject]; [color_table->empty_indices removeObject: index]; - idx = [index unsignedIntValue]; + idx = [index unsignedLongValue]; } else { if (color_table->avail == color_table->size) { - color_table->size += NS_COLOR_CAPACITY; + ptrdiff_t size; + ptrdiff_t size_max = + min (ULONG_MAX, + min (PTRDIFF_MAX, SIZE_MAX) / sizeof (NSColor *)); + if (size_max - NS_COLOR_CAPACITY < color_table->size) + memory_full (SIZE_MAX); + size = color_table->size + NS_COLOR_CAPACITY; color_table->colors = (NSColor **)xrealloc (color_table->colors, - color_table->size * sizeof (NSColor *)); + size * sizeof (NSColor *)); + color_table->size = size; } idx = color_table->avail++; } @@ -2321,7 +2328,7 @@ if (!img) { unsigned short *bits = p->bits + p->dh; - int len = 8 * p->h/8; + int len = p->h; int i; unsigned char *cbits = xmalloc (len); @@ -4857,7 +4864,7 @@ } } - + #if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 /* if we get here we should send the key for input manager processing */ if (firstTime && [[NSInputManager currentInputManager] === modified file 'src/process.c' --- src/process.c 2011-07-16 18:27:08 +0000 +++ src/process.c 2011-07-29 01:05:39 +0000 @@ -3567,6 +3567,12 @@ return Qnil; again: + if (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / sizeof *ifreqs - 25 + < ifaces) + { + xfree (ifreqs); + memory_full (SIZE_MAX); + } ifaces += 25; buf_size = ifaces * sizeof (ifreqs[0]); ifreqs = (struct ifreq *)xrealloc(ifreqs, buf_size); === modified file 'src/region-cache.c' --- src/region-cache.c 2011-04-19 00:34:42 +0000 +++ src/region-cache.c 2011-07-29 01:10:08 +0000 @@ -247,11 +247,16 @@ if (gap_len < min_size) { EMACS_INT i; - - /* Always make at least NEW_CACHE_GAP elements, as long as we're - expanding anyway. */ - if (min_size < NEW_CACHE_GAP) - min_size = NEW_CACHE_GAP; + ptrdiff_t cache_len_max = + min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->boundaries; + ptrdiff_t min_size_max = cache_len_max - c->cache_len; + + if (min_size_max < min_size) + memory_full (SIZE_MAX); + + /* Unless running out of space, make at least NEW_CACHE_GAP + elements, as long as we're expanding anyway. */ + min_size = max (min_size, min (min_size_max, NEW_CACHE_GAP)); c->boundaries = (struct boundary *) xrealloc (c->boundaries, === modified file 'src/scroll.c' --- src/scroll.c 2011-06-22 18:15:23 +0000 +++ src/scroll.c 2011-07-29 01:11:37 +0000 @@ -969,32 +969,21 @@ const char *cleanup_string, int coefficient) { - if (FRAME_INSERT_COST (frame) != 0) - { - FRAME_INSERT_COST (frame) = - (int *) xrealloc (FRAME_INSERT_COST (frame), - FRAME_LINES (frame) * sizeof (int)); - FRAME_DELETEN_COST (frame) = - (int *) xrealloc (FRAME_DELETEN_COST (frame), - FRAME_LINES (frame) * sizeof (int)); - FRAME_INSERTN_COST (frame) = - (int *) xrealloc (FRAME_INSERTN_COST (frame), - FRAME_LINES (frame) * sizeof (int)); - FRAME_DELETE_COST (frame) = - (int *) xrealloc (FRAME_DELETE_COST (frame), - FRAME_LINES (frame) * sizeof (int)); - } - else - { - FRAME_INSERT_COST (frame) = - (int *) xmalloc (FRAME_LINES (frame) * sizeof (int)); - FRAME_DELETEN_COST (frame) = - (int *) xmalloc (FRAME_LINES (frame) * sizeof (int)); - FRAME_INSERTN_COST (frame) = - (int *) xmalloc (FRAME_LINES (frame) * sizeof (int)); - FRAME_DELETE_COST (frame) = - (int *) xmalloc (FRAME_LINES (frame) * sizeof (int)); - } + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < FRAME_LINES (frame)) + memory_full (SIZE_MAX); + + FRAME_INSERT_COST (frame) = + (int *) xrealloc (FRAME_INSERT_COST (frame), + FRAME_LINES (frame) * sizeof (int)); + FRAME_DELETEN_COST (frame) = + (int *) xrealloc (FRAME_DELETEN_COST (frame), + FRAME_LINES (frame) * sizeof (int)); + FRAME_INSERTN_COST (frame) = + (int *) xrealloc (FRAME_INSERTN_COST (frame), + FRAME_LINES (frame) * sizeof (int)); + FRAME_DELETE_COST (frame) = + (int *) xrealloc (FRAME_DELETE_COST (frame), + FRAME_LINES (frame) * sizeof (int)); ins_del_costs (frame, ins_line_string, multi_ins_string, === modified file 'src/search.c' --- src/search.c 2011-07-14 18:45:36 +0000 +++ src/search.c 2011-07-29 01:13:10 +0000 @@ -2648,6 +2648,8 @@ int really_changed = 0; substed_alloc_size = length * 2 + 100; + if (min (PTRDIFF_MAX, SIZE_MAX) - 1 < substed_alloc_size) + memory_full (SIZE_MAX); substed = (unsigned char *) xmalloc (substed_alloc_size + 1); substed_len = 0; @@ -2736,6 +2738,13 @@ /* Make sure SUBSTED is big enough. */ if (substed_len + add_len >= substed_alloc_size) { + ptrdiff_t add_len_max = + min (PTRDIFF_MAX, SIZE_MAX) - 1 - 500 - substed_len; + if (add_len_max < add_len) + { + xfree (substed); + memory_full (SIZE_MAX); + } substed_alloc_size = substed_len + add_len + 500; substed = (unsigned char *) xrealloc (substed, substed_alloc_size + 1); @@ -2973,7 +2982,7 @@ If optional arg RESEAT is non-nil, make markers on LIST point nowhere. */) (register Lisp_Object list, Lisp_Object reseat) { - register int i; + ptrdiff_t i; register Lisp_Object marker; if (running_asynch_code) @@ -2987,10 +2996,13 @@ /* Allocate registers if they don't already exist. */ { - int length = XFASTINT (Flength (list)) / 2; + ptrdiff_t length = XFASTINT (Flength (list)) / 2; if (length > search_regs.num_regs) { + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (regoff_t) < length) + memory_full (SIZE_MAX); + if (search_regs.num_regs == 0) { search_regs.start === modified file 'src/sysdep.c' --- src/sysdep.c 2011-07-11 06:05:57 +0000 +++ src/sysdep.c 2011-07-29 01:16:54 +0000 @@ -2640,7 +2640,7 @@ ssize_t nread; const char *cmd = NULL; char *cmdline = NULL; - size_t cmdsize = 0, cmdline_size; + ptrdiff_t cmdsize = 0, cmdline_size; unsigned char c; int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount; unsigned long long u_time, s_time, cutime, cstime, start; @@ -2822,8 +2822,10 @@ if (fd >= 0) { char ch; - for (cmdline_size = 0; emacs_read (fd, &ch, 1) == 1; cmdline_size++) + for (cmdline_size = 0; cmdline_size < STRING_BYTES_BOUND; cmdline_size++) { + if (emacs_read (fd, &ch, 1) != 1) + break; c = ch; if (isspace (c) || c == '\\') cmdline_size++; /* for later quoting, see below */ @@ -2844,7 +2846,7 @@ nread = 0; } /* We don't want trailing null characters. */ - for (p = cmdline + nread - 1; p > cmdline && !*p; p--) + for (p = cmdline + nread; p > cmdline + 1 && !p[-1]; p--) nread--; for (p = cmdline; p < cmdline + nread; p++) { === modified file 'src/term.c' --- src/term.c 2011-07-14 17:28:42 +0000 +++ src/term.c 2011-07-29 01:22:19 +0000 @@ -136,10 +136,6 @@ static int max_frame_cols; -/* The largest frame height in any call to calculate_costs. */ - -static int max_frame_lines; - /* Non-zero if we have dropped our controlling tty and therefore should not open a frame on stdout. */ static int no_controlling_tty; @@ -497,8 +493,8 @@ static unsigned char *encode_terminal_src; static unsigned char *encode_terminal_dst; /* Allocated sizes of the above buffers. */ -static int encode_terminal_src_size; -static int encode_terminal_dst_size; +static ptrdiff_t encode_terminal_src_size; +static ptrdiff_t encode_terminal_dst_size; /* Encode SRC_LEN glyphs starting at SRC to terminal output codes. Set CODING->produced to the byte-length of the resulting byte @@ -509,8 +505,8 @@ { struct glyph *src_end = src + src_len; unsigned char *buf; - int nchars, nbytes, required; - register int tlen = GLYPH_TABLE_LENGTH; + ptrdiff_t nchars, nbytes, required; + ptrdiff_t tlen = GLYPH_TABLE_LENGTH; register Lisp_Object *tbase = GLYPH_TABLE_BASE; Lisp_Object charset_list; @@ -518,13 +514,13 @@ multibyte-form. But, it may be enlarged on demand if Vglyph_table contains a string or a composite glyph is encountered. */ - required = MAX_MULTIBYTE_LENGTH * src_len; + if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len) + memory_full (SIZE_MAX); + required = src_len; + required *= MAX_MULTIBYTE_LENGTH; if (encode_terminal_src_size < required) { - if (encode_terminal_src) - encode_terminal_src = xrealloc (encode_terminal_src, required); - else - encode_terminal_src = xmalloc (required); + encode_terminal_src = xrealloc (encode_terminal_src, required); encode_terminal_src_size = required; } @@ -544,19 +540,23 @@ if (src->u.cmp.automatic) { gstring = composition_gstring_from_id (src->u.cmp.id); - required = src->slice.cmp.to + 1 - src->slice.cmp.from; + required = src->slice.cmp.to - src->slice.cmp.from + 1; } else { cmp = composition_table[src->u.cmp.id]; - required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len; + required = cmp->glyph_len; + required *= MAX_MULTIBYTE_LENGTH; } - if (encode_terminal_src_size < nbytes + required) + if (encode_terminal_src_size - nbytes < required) { - encode_terminal_src_size = nbytes + required; - encode_terminal_src = xrealloc (encode_terminal_src, - encode_terminal_src_size); + ptrdiff_t size; + if (min (PTRDIFF_MAX, SIZE_MAX) - nbytes < required) + memory_full (SIZE_MAX); + size = nbytes + required; + encode_terminal_src = xrealloc (encode_terminal_src, size); + encode_terminal_src_size = size; buf = encode_terminal_src + nbytes; } @@ -627,11 +627,15 @@ if (NILP (string)) { nbytes = buf - encode_terminal_src; - if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH) + if (encode_terminal_src_size - nbytes < MAX_MULTIBYTE_LENGTH) { - encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH; - encode_terminal_src = xrealloc (encode_terminal_src, - encode_terminal_src_size); + ptrdiff_t size; + if (min (PTRDIFF_MAX, SIZE_MAX) - MAX_MULTIBYTE_LENGTH + < nbytes) + memory_full (SIZE_MAX); + size = nbytes + MAX_MULTIBYTE_LENGTH; + encode_terminal_src = xrealloc (encode_terminal_src, size); + encode_terminal_src_size = size; buf = encode_terminal_src + nbytes; } if (CHAR_BYTE8_P (c) @@ -659,11 +663,14 @@ if (! STRING_MULTIBYTE (string)) string = string_to_multibyte (string); nbytes = buf - encode_terminal_src; - if (encode_terminal_src_size < nbytes + SBYTES (string)) + if (encode_terminal_src_size - nbytes < SBYTES (string)) { - encode_terminal_src_size = nbytes + SBYTES (string); - encode_terminal_src = xrealloc (encode_terminal_src, - encode_terminal_src_size); + ptrdiff_t size; + if (min (PTRDIFF_MAX, SIZE_MAX) - SBYTES (string) < nbytes) + memory_full (SIZE_MAX); + size = nbytes + SBYTES (string); + encode_terminal_src = xrealloc (encode_terminal_src, size); + encode_terminal_src_size = size; buf = encode_terminal_src + nbytes; } memcpy (buf, SDATA (string), SBYTES (string)); @@ -684,12 +691,9 @@ coding->source = encode_terminal_src; if (encode_terminal_dst_size == 0) { + encode_terminal_dst = xrealloc (encode_terminal_dst, + encode_terminal_src_size); encode_terminal_dst_size = encode_terminal_src_size; - if (encode_terminal_dst) - encode_terminal_dst = xrealloc (encode_terminal_dst, - encode_terminal_dst_size); - else - encode_terminal_dst = xmalloc (encode_terminal_dst_size); } coding->destination = encode_terminal_dst; coding->dst_bytes = encode_terminal_dst_size; @@ -1156,18 +1160,14 @@ char_ins_del_vector (i.e., char_ins_del_cost) isn't used because X turns off char_ins_del_ok. */ - max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); + if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2 < max_frame_cols) + memory_full (SIZE_MAX); - if (char_ins_del_vector != 0) - char_ins_del_vector - = (int *) xrealloc (char_ins_del_vector, - (sizeof (int) - + 2 * max_frame_cols * sizeof (int))); - else - char_ins_del_vector - = (int *) xmalloc (sizeof (int) - + 2 * max_frame_cols * sizeof (int)); + char_ins_del_vector + = (int *) xrealloc (char_ins_del_vector, + (sizeof (int) + + 2 * max_frame_cols * sizeof (int))); memset (char_ins_del_vector, 0, (sizeof (int) + 2 * max_frame_cols * sizeof (int))); === modified file 'src/termcap.c' --- src/termcap.c 2011-07-10 08:20:10 +0000 +++ src/termcap.c 2011-07-29 01:24:19 +0000 @@ -480,7 +480,7 @@ /* If BP is malloc'd by us, make sure it is big enough. */ if (malloc_size) { - int offset1 = bp1 - bp, offset2 = tc_search_point - bp; + ptrdiff_t offset1 = bp1 - bp, offset2 = tc_search_point - bp; malloc_size = offset1 + buf.size; bp = termcap_name = (char *) xrealloc (bp, malloc_size); bp1 = termcap_name + offset1; @@ -619,7 +619,6 @@ register char *end; register int nread; register char *buf = bufp->beg; - register char *tem; if (!append_end) append_end = bufp->ptr; @@ -636,14 +635,17 @@ { if (bufp->full == bufp->size) { - if ((PTRDIFF_MAX - 1) / 2 < bufp->size) + ptrdiff_t ptr_offset = bufp->ptr - buf; + ptrdiff_t append_end_offset = append_end - buf; + ptrdiff_t size; + if ((min (PTRDIFF_MAX, SIZE_MAX) - 1) / 2 < bufp->size) memory_full (SIZE_MAX); - bufp->size *= 2; + size = 2 * bufp->size; /* Add 1 to size to ensure room for terminating null. */ - tem = (char *) xrealloc (buf, bufp->size + 1); - bufp->ptr = (bufp->ptr - buf) + tem; - append_end = (append_end - buf) + tem; - bufp->beg = buf = tem; + bufp->beg = buf = (char *) xrealloc (buf, size + 1); + bufp->size = size; + bufp->ptr = buf + ptr_offset; + append_end = buf + append_end_offset; } } else === modified file 'src/termhooks.h' --- src/termhooks.h 2011-06-06 19:43:39 +0000 +++ src/termhooks.h 2011-07-20 00:09:31 +0000 @@ -288,12 +288,12 @@ /* The next four modifier bits are used also in keyboard events at the Lisp level. - It's probably not the greatest idea to use the 2^23 bit for any + It's probably not the greatest idea to use the 2^28 bit for any modifier. It may or may not be the sign bit, depending on - VALBITS, so using it to represent a modifier key means that + FIXNUM_BITS, so using it to represent a modifier key means that characters thus modified have different integer equivalents depending on the architecture they're running on. Oh, and - applying XINT to a character whose 2^23 bit is set sign-extends + applying XINT to a character whose 2^28 bit is set might sign-extend it, so you get a bunch of bits in the mask you didn't want. The CHAR_ macros are defined in lisp.h. */ === modified file 'src/tparam.c' --- src/tparam.c 2011-07-10 08:20:10 +0000 +++ src/tparam.c 2011-07-29 01:49:31 +0000 @@ -79,33 +79,38 @@ register const char *p = string; register char *op = outstring; char *outend; - int outlen = 0; + char *new = 0; + ptrdiff_t outlen = 0; register int tem; int *old_argp = argp; /* can move */ int *fixed_argp = argp; /* never moves */ int explicit_param_p = 0; /* set by %p */ - int doleft = 0; - int doup = 0; + ptrdiff_t doleft = 0; + ptrdiff_t doup = 0; + ptrdiff_t append_len = 0; outend = outstring + len; while (1) { /* If the buffer might be too short, make it bigger. */ - if (op + 5 >= outend) + while (outend - op - append_len <= 5) { - register char *new; - int offset = op - outstring; + ptrdiff_t offset = op - outstring; if (outlen == 0) { + if (min (PTRDIFF_MAX, SIZE_MAX) - 40 < len) + goto out_of_memory; outlen = len + 40; new = (char *) xmalloc (outlen); memcpy (new, outstring, offset); } else { + if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < outlen) + goto out_of_memory; outlen *= 2; new = (char *) xrealloc (outstring, outlen); } @@ -167,11 +172,19 @@ and this is one of them, increment it. */ while (tem == 0 || tem == '\n' || tem == '\t') { + ptrdiff_t append_len_incr; tem++; if (argp == old_argp) - doup++, outend -= strlen (up); + doup++, append_len_incr = strlen (up); else - doleft++, outend -= strlen (left); + doleft++, append_len_incr = strlen (left); + if (PTRDIFF_MAX - append_len < append_len_incr) + { + out_of_memory: + xfree (new); + memory_full (SIZE_MAX); + } + append_len += append_len_incr; } } *op++ = tem ? tem : 0200; === modified file 'src/window.c' --- src/window.c 2011-07-14 17:28:42 +0000 +++ src/window.c 2011-07-19 21:39:36 +0000 @@ -5069,7 +5069,7 @@ && (!EQ (Vrecenter_redisplay, Qtty) || !NILP (Ftty_type (selected_frame)))) { - int i; + ptrdiff_t i; /* Invalidate pixel data calculated for all compositions. */ for (i = 0; i < n_compositions; i++) === modified file 'src/xdisp.c' --- src/xdisp.c 2011-07-28 06:44:45 +0000 +++ src/xdisp.c 2011-07-29 05:31:12 +0000 @@ -2478,10 +2478,7 @@ else if (INTEGERP (w->redisplay_end_trigger)) it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger); - /* Correct bogus values of tab_width. */ - it->tab_width = XINT (BVAR (current_buffer, tab_width)); - if (it->tab_width <= 0 || it->tab_width > 1000) - it->tab_width = 8; + it->tab_width = SANE_TAB_WIDTH (current_buffer); /* Are lines in the display truncated? */ if (base_face_id != DEFAULT_FACE_ID @@ -10390,8 +10387,12 @@ double the buffer's size. */ if (mode_line_noprop_ptr == mode_line_noprop_buf_end) { - int len = MODE_LINE_NOPROP_LEN (0); - int new_size = 2 * len * sizeof *mode_line_noprop_buf; + ptrdiff_t len = MODE_LINE_NOPROP_LEN (0); + ptrdiff_t new_size; + + if (STRING_BYTES_BOUND / 2 < len) + memory_full (SIZE_MAX); + new_size = 2 * len; mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size); mode_line_noprop_buf_end = mode_line_noprop_buf + new_size; mode_line_noprop_ptr = mode_line_noprop_buf + len; @@ -10455,9 +10456,9 @@ /* Do we have more than one visible frame on this X display? */ Lisp_Object tail; Lisp_Object fmt; - int title_start; + ptrdiff_t title_start; char *title; - int len; + ptrdiff_t len; struct it it; int count = SPECPDL_INDEX (); @@ -21268,7 +21269,7 @@ if (FRAME_WINDOW_P (it->f) && valid_image_p (prop)) { - int id = lookup_image (it->f, prop); + ptrdiff_t id = lookup_image (it->f, prop); struct image *img = IMAGE_FROM_ID (it->f, id); return OK_PIXELS (width_p ? img->width : img->height); @@ -22140,7 +22141,7 @@ do { \ int face_id = (row)->glyphs[area][START].face_id; \ struct face *base_face = FACE_FROM_ID (f, face_id); \ - int cmp_id = (row)->glyphs[area][START].u.cmp.id; \ + ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \ struct composition *cmp = composition_table[cmp_id]; \ XChar2b *char2b; \ struct glyph_string *first_s IF_LINT (= NULL); \ === modified file 'src/xfaces.c' --- src/xfaces.c 2011-07-28 00:15:43 +0000 +++ src/xfaces.c 2011-07-29 05:31:12 +0000 @@ -2668,8 +2668,13 @@ property `face' of the Lisp face name. */ if (next_lface_id == lface_id_to_name_size) { - int new_size = max (50, 2 * lface_id_to_name_size); - int sz = new_size * sizeof *lface_id_to_name; + ptrdiff_t new_size, sz; + if (min (min (PTRDIFF_MAX, SIZE_MAX) / 2 / sizeof *lface_id_to_name, + MOST_POSITIVE_FIXNUM) + < lface_id_to_name_size) + memory_full (SIZE_MAX); + new_size = max (50, 2 * lface_id_to_name_size); + sz = new_size * sizeof *lface_id_to_name; lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz); lface_id_to_name_size = new_size; } @@ -4412,7 +4417,10 @@ if (c->used == c->size) { int new_size, sz; - new_size = min (2 * c->size, MAX_FACE_ID); + new_size = + min (2 * c->size, + min (MAX_FACE_ID, + min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->faces_by_id)); if (new_size == c->size) abort (); /* Alternatives? ++kfs */ sz = new_size * sizeof *c->faces_by_id; === modified file 'src/xfns.c' --- src/xfns.c 2011-07-23 12:15:53 +0000 +++ src/xfns.c 2011-07-29 05:31:12 +0000 @@ -145,7 +145,8 @@ Lisp_Object Qfont_param; #if GLYPH_DEBUG -static int image_cache_refcount, dpyinfo_refcount; +static ptrdiff_t image_cache_refcount; +static int dpyinfo_refcount; #endif #if defined (USE_GTK) && defined (HAVE_FREETYPE) @@ -1470,7 +1471,8 @@ the result should be `COMPOUND_TEXT'. */ static unsigned char * -x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, int *text_bytes, int *stringp, int *freep) +x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, + ptrdiff_t *text_bytes, int *stringp, int *freep) { int result = string_xstring_p (string); struct coding_system coding; @@ -1488,6 +1490,8 @@ coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK); /* We suppress producing escape sequences for composition. */ coding.common_flags &= ~CODING_ANNOTATION_MASK; + if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < SCHARS (string)) + memory_full (SIZE_MAX); coding.dst_bytes = SCHARS (string) * 2; coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); encode_coding_object (&coding, string, 0, 0, @@ -1511,7 +1515,8 @@ BLOCK_INPUT; { XTextProperty text, icon; - int bytes, stringp; + ptrdiff_t bytes; + int stringp; int do_free_icon_value = 0, do_free_text_value = 0; Lisp_Object coding_system; Lisp_Object encoded_name; @@ -1550,6 +1555,8 @@ : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); text.format = 8; text.nitems = bytes; + if (text.nitems != bytes) + error ("Window name too large"); if (!STRINGP (f->icon_name)) { @@ -1565,6 +1572,8 @@ : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); icon.format = 8; icon.nitems = bytes; + if (icon.nitems != bytes) + error ("Icon name too large"); encoded_icon_name = ENCODE_UTF_8 (f->icon_name); } @@ -4193,21 +4202,21 @@ if (CONSP (value)) { + ptrdiff_t elsize; + nelements = x_check_property_data (value); if (nelements == -1) error ("Bad data in VALUE, must be number, string or cons"); - if (element_format == 8) - data = (unsigned char *) xmalloc (nelements); - else if (element_format == 16) - data = (unsigned char *) xmalloc (nelements*2); - else /* format == 32 */ - /* The man page for XChangeProperty: - "If the specified format is 32, the property data must be a - long array." - This applies even if long is more than 64 bits. The X library - converts to 32 bits before sending to the X server. */ - data = (unsigned char *) xmalloc (nelements * sizeof(long)); + /* The man page for XChangeProperty: + "If the specified format is 32, the property data must be a + long array." + This applies even if long is more than 32 bits. The X library + converts to 32 bits before sending to the X server. */ + elsize = element_format == 32 ? sizeof (long) : element_format >> 3; + if (min (PTRDIFF_MAX, SIZE_MAX) / elsize < nelements) + memory_full (SIZE_MAX); + data = (unsigned char *) xmalloc (nelements * elsize); x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format); } @@ -4215,7 +4224,9 @@ { CHECK_STRING (value); data = SDATA (value); - nelements = SCHARS (value); + if (INT_MAX < SBYTES (value)) + error ("VALUE too long"); + nelements = SBYTES (value); } BLOCK_INPUT; === modified file 'src/xgselect.c' --- src/xgselect.c 2011-07-01 09:18:46 +0000 +++ src/xgselect.c 2011-07-29 01:56:54 +0000 @@ -54,10 +54,16 @@ do { if (n_gfds > gfds_size) { - while (n_gfds > gfds_size) - gfds_size *= 2; + int gfds_size_max = + min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *gfds); + int size; + if (gfds_size_max / 2 < n_gfds) + memory_full (SIZE_MAX); + size = 2 * n_gfds; + gfds_size = 0; xfree (gfds); - gfds = xmalloc (sizeof (*gfds) * gfds_size); + gfds = xmalloc (sizeof *gfds * size); + gfds_size = size; } n_gfds = g_main_context_query (context, === modified file 'src/xrdb.c' --- src/xrdb.c 2011-07-10 08:20:10 +0000 +++ src/xrdb.c 2011-07-29 01:59:57 +0000 @@ -204,7 +204,10 @@ if (path_size - path_len <= next_len) { if (min (PTRDIFF_MAX, SIZE_MAX) / 2 - 1 - path_len < next_len) - memory_full (SIZE_MAX); + { + xfree (path); + memory_full (SIZE_MAX); + } path_size = (path_len + next_len + 1) * 2; path = (char *) xrealloc (path, path_size); } @@ -426,24 +429,22 @@ { XrmDatabase db; char *p; - char *path = 0, *home = 0; - const char *host; + char *path = 0; if ((p = getenv ("XENVIRONMENT")) == NULL) { - home = gethomedir (); - host = get_system_name (); - path = (char *) xmalloc (strlen (home) - + sizeof (".Xdefaults-") - + strlen (host)); - sprintf (path, "%s%s%s", home, ".Xdefaults-", host); + static char const xdefaults[] = ".Xdefaults-"; + char *home = gethomedir (); + char const *host = get_system_name (); + ptrdiff_t pathsize = strlen (home) + sizeof xdefaults + strlen (host); + path = (char *) xrealloc (home, pathsize); + strcat (strcat (path, xdefaults), host); p = path; } db = XrmGetFileDatabase (p); xfree (path); - xfree (home); return db; } === modified file 'src/xselect.c' --- src/xselect.c 2011-07-13 03:45:56 +0000 +++ src/xselect.c 2011-07-29 05:08:30 +0000 @@ -66,22 +66,15 @@ static void wait_for_property_change (struct prop_location *); static Lisp_Object x_get_foreign_selection (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -static void x_get_window_property (Display *, Window, Atom, - unsigned char **, int *, - Atom *, int *, unsigned long *, int); -static void receive_incremental_selection (Display *, Window, Atom, - Lisp_Object, unsigned, - unsigned char **, int *, - Atom *, int *, unsigned long *); static Lisp_Object x_get_window_property_as_lisp_data (Display *, Window, Atom, Lisp_Object, Atom); static Lisp_Object selection_data_to_lisp_data (Display *, const unsigned char *, - int, Atom, int); + ptrdiff_t, Atom, int); static void lisp_data_to_selection_data (Display *, Lisp_Object, unsigned char **, Atom *, - unsigned *, int *, int *); + ptrdiff_t *, int *, int *); static Lisp_Object clean_local_selection_data (Lisp_Object); /* Printing traces to stderr. */ @@ -114,15 +107,37 @@ static Lisp_Object Qforeign_selection; static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions; +/* Bytes needed to represent 'long' data. This is as per libX11; it + is not necessarily sizeof (long). */ +#define X_LONG_SIZE 4 + +/* Maximum unsigned 'short' and 'long' values suitable for libX11. */ +#define X_USHRT_MAX 0xffff +#define X_ULONG_MAX 0xffffffff + /* If this is a smaller number than the max-request-size of the display, emacs will use INCR selection transfer when the selection is larger than this. The max-request-size is usually around 64k, so if you want emacs to use incremental selection transfers when the selection is smaller than that, set this. I added this mostly for debugging the - incremental transfer stuff, but it might improve server performance. */ -#define MAX_SELECTION_QUANTUM 0xFFFFFF - -#define SELECTION_QUANTUM(dpy) ((XMaxRequestSize(dpy) << 2) - 100) + incremental transfer stuff, but it might improve server performance. + + This value cannot exceed INT_MAX / max (X_LONG_SIZE, sizeof (long)) + because it is multiplied by X_LONG_SIZE and by sizeof (long) in + subscript calculations. Similarly for PTRDIFF_MAX - 1 or SIZE_MAX + - 1 in place of INT_MAX. */ +#define MAX_SELECTION_QUANTUM \ + ((int) min (0xFFFFFF, (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) - 1) \ + / max (X_LONG_SIZE, sizeof (long))))) + +static int +selection_quantum (Display *display) +{ + long mrs = XMaxRequestSize (display); + return (mrs < MAX_SELECTION_QUANTUM / X_LONG_SIZE + 25 + ? (mrs - 25) * X_LONG_SIZE + : MAX_SELECTION_QUANTUM); +} #define LOCAL_SELECTION(selection_symbol,dpyinfo) \ assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist) @@ -477,7 +492,7 @@ struct selection_data { unsigned char *data; - unsigned int size; + ptrdiff_t size; int format; Atom type; int nofree; @@ -581,14 +596,11 @@ XSelectionEvent *reply = &(reply_base.xselection); Display *display = SELECTION_EVENT_DISPLAY (event); Window window = SELECTION_EVENT_REQUESTOR (event); - int bytes_remaining; - int max_bytes = SELECTION_QUANTUM (display); + ptrdiff_t bytes_remaining; + int max_bytes = selection_quantum (display); int count = SPECPDL_INDEX (); struct selection_data *cs; - if (max_bytes > MAX_SELECTION_QUANTUM) - max_bytes = MAX_SELECTION_QUANTUM; - reply->type = SelectionNotify; reply->display = display; reply->requestor = window; @@ -616,11 +628,12 @@ if (cs->property == None) continue; - bytes_remaining = cs->size * (cs->format / 8); + bytes_remaining = cs->size; + bytes_remaining *= cs->format >> 3; if (bytes_remaining <= max_bytes) { /* Send all the data at once, with minimal handshaking. */ - TRACE1 ("Sending all %d bytes", bytes_remaining); + TRACE1 ("Sending all %"pD"d bytes", bytes_remaining); XChangeProperty (display, window, cs->property, cs->type, cs->format, PropModeReplace, cs->data, cs->size); @@ -628,9 +641,9 @@ else { /* Send an INCR tag to initiate incremental transfer. */ - long value[1]; + unsigned long value[1]; - TRACE2 ("Start sending %d bytes incrementally (%s)", + TRACE2 ("Start sending %"pD"d bytes incrementally (%s)", bytes_remaining, XGetAtomName (display, cs->property)); cs->wait_object = expect_property_change (display, window, cs->property, @@ -638,7 +651,7 @@ /* XChangeProperty expects an array of long even if long is more than 32 bits. */ - value[0] = bytes_remaining; + value[0] = min (bytes_remaining, X_ULONG_MAX); XChangeProperty (display, window, cs->property, dpyinfo->Xatom_INCR, 32, PropModeReplace, (unsigned char *) value, 1); @@ -672,7 +685,8 @@ int had_errors = x_had_errors_p (display); UNBLOCK_INPUT; - bytes_remaining = cs->size * format_bytes; + bytes_remaining = cs->size; + bytes_remaining *= format_bytes; /* Wait for the requester to ack by deleting the property. This can run Lisp code (process handlers) or signal. */ @@ -810,7 +824,7 @@ non-None property. */ Window requestor = SELECTION_EVENT_REQUESTOR (event); Lisp_Object multprop; - int j, nselections; + ptrdiff_t j, nselections; if (property == None) goto DONE; multprop @@ -1269,19 +1283,28 @@ static void x_get_window_property (Display *display, Window window, Atom property, - unsigned char **data_ret, int *bytes_ret, + unsigned char **data_ret, ptrdiff_t *bytes_ret, Atom *actual_type_ret, int *actual_format_ret, unsigned long *actual_size_ret, int delete_p) { - int total_size; + ptrdiff_t total_size; unsigned long bytes_remaining; - int offset = 0; + ptrdiff_t offset = 0; + unsigned char *data = 0; unsigned char *tmp_data = 0; int result; - int buffer_size = SELECTION_QUANTUM (display); - - if (buffer_size > MAX_SELECTION_QUANTUM) - buffer_size = MAX_SELECTION_QUANTUM; + int buffer_size = selection_quantum (display); + + /* Wide enough to avoid overflow in expressions using it. */ + ptrdiff_t x_long_size = X_LONG_SIZE; + + /* Maximum value for TOTAL_SIZE. It cannot exceed PTRDIFF_MAX - 1 + and SIZE_MAX - 1, for an extra byte at the end. And it cannot + exceed LONG_MAX * X_LONG_SIZE, for XGetWindowProperty. */ + ptrdiff_t total_size_max = + ((min (PTRDIFF_MAX, SIZE_MAX) - 1) / x_long_size < LONG_MAX + ? min (PTRDIFF_MAX, SIZE_MAX) - 1 + : LONG_MAX * x_long_size); BLOCK_INPUT; @@ -1292,49 +1315,44 @@ actual_size_ret, &bytes_remaining, &tmp_data); if (result != Success) - { - UNBLOCK_INPUT; - *data_ret = 0; - *bytes_ret = 0; - return; - } + goto done; /* This was allocated by Xlib, so use XFree. */ XFree ((char *) tmp_data); if (*actual_type_ret == None || *actual_format_ret == 0) - { - UNBLOCK_INPUT; - return; - } + goto done; - total_size = bytes_remaining + 1; - *data_ret = (unsigned char *) xmalloc (total_size); + if (total_size_max < bytes_remaining) + goto size_overflow; + total_size = bytes_remaining; + data = malloc (total_size + 1); + if (! data) + goto memory_exhausted; /* Now read, until we've gotten it all. */ while (bytes_remaining) { -#ifdef TRACE_SELECTION - unsigned long last = bytes_remaining; -#endif + ptrdiff_t bytes_gotten; + int bytes_per_item; result = XGetWindowProperty (display, window, property, - (long)offset/4, (long)buffer_size/4, + offset / X_LONG_SIZE, + buffer_size / X_LONG_SIZE, False, AnyPropertyType, actual_type_ret, actual_format_ret, actual_size_ret, &bytes_remaining, &tmp_data); - TRACE2 ("Read %lu bytes from property %s", - last - bytes_remaining, - XGetAtomName (display, property)); - /* If this doesn't return Success at this point, it means that some clod deleted the selection while we were in the midst of reading it. Deal with that, I guess.... */ if (result != Success) break; + bytes_per_item = *actual_format_ret >> 3; + xassert (*actual_size_ret <= buffer_size / bytes_per_item); + /* The man page for XGetWindowProperty says: "If the returned format is 32, the returned data is represented as a long array and should be cast to that type to obtain the @@ -1348,32 +1366,61 @@ The bytes and offsets passed to XGetWindowProperty refers to the property and those are indeed in 32 bit quantities if format is 32. */ + bytes_gotten = *actual_size_ret; + bytes_gotten *= bytes_per_item; + + TRACE2 ("Read %"pD"d bytes from property %s", + bytes_gotten, XGetAtomName (display, property)); + + if (total_size - offset < bytes_gotten) + { + unsigned char *data1; + ptrdiff_t remaining_lim = total_size_max - offset - bytes_gotten; + if (remaining_lim < 0 || remaining_lim < bytes_remaining) + goto size_overflow; + total_size = offset + bytes_gotten + bytes_remaining; + data1 = realloc (data, total_size + 1); + if (! data1) + goto memory_exhausted; + data = data1; + } + if (32 < BITS_PER_LONG && *actual_format_ret == 32) { unsigned long i; - int *idata = (int *) ((*data_ret) + offset); + int *idata = (int *) (data + offset); long *ldata = (long *) tmp_data; for (i = 0; i < *actual_size_ret; ++i) - { - idata[i]= (int) ldata[i]; - offset += 4; - } + idata[i] = ldata[i]; } else - { - *actual_size_ret *= *actual_format_ret / 8; - memcpy ((*data_ret) + offset, tmp_data, *actual_size_ret); - offset += *actual_size_ret; - } + memcpy (data + offset, tmp_data, bytes_gotten); + + offset += bytes_gotten; /* This was allocated by Xlib, so use XFree. */ XFree ((char *) tmp_data); } XFlush (display); + data[offset] = '\0'; + + done: UNBLOCK_INPUT; + *data_ret = data; *bytes_ret = offset; + return; + + size_overflow: + free (data); + UNBLOCK_INPUT; + memory_full (SIZE_MAX); + + memory_exhausted: + free (data); + UNBLOCK_INPUT; + memory_full (total_size + 1); } \f /* Use xfree, not XFree, to free the data obtained with this function. */ @@ -1382,16 +1429,19 @@ receive_incremental_selection (Display *display, Window window, Atom property, Lisp_Object target_type, unsigned int min_size_bytes, - unsigned char **data_ret, int *size_bytes_ret, + unsigned char **data_ret, + ptrdiff_t *size_bytes_ret, Atom *type_ret, int *format_ret, unsigned long *size_ret) { - int offset = 0; + ptrdiff_t offset = 0; struct prop_location *wait_object; + if (min (PTRDIFF_MAX, SIZE_MAX) < min_size_bytes) + memory_full (SIZE_MAX); + *data_ret = (unsigned char *) xmalloc (min_size_bytes); *size_bytes_ret = min_size_bytes; - *data_ret = (unsigned char *) xmalloc (*size_bytes_ret); - TRACE1 ("Read %d bytes incrementally", min_size_bytes); + TRACE1 ("Read %u bytes incrementally", min_size_bytes); /* At this point, we have read an INCR property. Delete the property to ack it. @@ -1416,7 +1466,7 @@ while (1) { unsigned char *tmp_data; - int tmp_size_bytes; + ptrdiff_t tmp_size_bytes; TRACE0 (" Wait for property change"); wait_for_property_change (wait_object); @@ -1429,7 +1479,7 @@ &tmp_data, &tmp_size_bytes, type_ret, format_ret, size_ret, 1); - TRACE1 (" Read increment of %d bytes", tmp_size_bytes); + TRACE1 (" Read increment of %"pD"d bytes", tmp_size_bytes); if (tmp_size_bytes == 0) /* we're done */ { @@ -1452,10 +1502,17 @@ XFlush (display); UNBLOCK_INPUT; - if (*size_bytes_ret < offset + tmp_size_bytes) + if (*size_bytes_ret - offset < tmp_size_bytes) { - *size_bytes_ret = offset + tmp_size_bytes; - *data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret); + ptrdiff_t size; + if (min (PTRDIFF_MAX, SIZE_MAX) - offset < tmp_size_bytes) + { + xfree (tmp_data); + memory_full (SIZE_MAX); + } + size = offset + tmp_size_bytes; + *data_ret = (unsigned char *) xrealloc (*data_ret, size); + *size_bytes_ret = size; } memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes); @@ -1482,7 +1539,7 @@ int actual_format; unsigned long actual_size; unsigned char *data = 0; - int bytes = 0; + ptrdiff_t bytes = 0; Lisp_Object val; struct x_display_info *dpyinfo = x_display_info_for_display (display); @@ -1574,7 +1631,7 @@ static Lisp_Object selection_data_to_lisp_data (Display *display, const unsigned char *data, - int size, Atom type, int format) + ptrdiff_t size, Atom type, int format) { struct x_display_info *dpyinfo = x_display_info_for_display (display); @@ -1607,7 +1664,7 @@ /* Treat ATOM_PAIR type similar to list of atoms. */ || type == dpyinfo->Xatom_ATOM_PAIR) { - int i; + ptrdiff_t i; /* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8. But the callers of these function has made sure the data for format == 32 is an array of int. Thus, use int instead @@ -1634,28 +1691,29 @@ else if (format == 32 && size == sizeof (int)) return INTEGER_TO_CONS (((unsigned int *) data) [0]); else if (format == 16 && size == sizeof (short)) - return make_number ((int) (((unsigned short *) data) [0])); + return make_number (((unsigned short *) data) [0]); /* Convert any other kind of data to a vector of numbers, represented as above (as an integer, or a cons of two 16 bit integers.) */ else if (format == 16) { - int i; + ptrdiff_t i; Lisp_Object v; v = Fmake_vector (make_number (size / 2), make_number (0)); for (i = 0; i < size / 2; i++) { - int j = (int) ((unsigned short *) data) [i]; + EMACS_INT j = ((unsigned short *) data) [i]; Faset (v, make_number (i), make_number (j)); } return v; } else { - int i; - Lisp_Object v = Fmake_vector (make_number (size / 4), make_number (0)); - for (i = 0; i < size / 4; i++) + ptrdiff_t i; + Lisp_Object v = Fmake_vector (make_number (size / X_LONG_SIZE), + make_number (0)); + for (i = 0; i < size / X_LONG_SIZE; i++) { unsigned int j = ((unsigned int *) data) [i]; Faset (v, make_number (i), INTEGER_TO_CONS (j)); @@ -1670,7 +1728,7 @@ static void lisp_data_to_selection_data (Display *display, Lisp_Object obj, unsigned char **data_ret, Atom *type_ret, - unsigned int *size_ret, + ptrdiff_t *size_ret, int *format_ret, int *nofree_ret) { Lisp_Object type = Qnil; @@ -1707,22 +1765,20 @@ } else if (SYMBOLP (obj)) { - *format_ret = 32; - *size_ret = 1; *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1); + *format_ret = 32; + *size_ret = 1; (*data_ret) [sizeof (Atom)] = 0; (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj); if (NILP (type)) type = QATOM; } - else if (INTEGERP (obj) - && XINT (obj) < 0xFFFF - && XINT (obj) > -0xFFFF) + else if (RANGED_INTEGERP (0, obj, X_USHRT_MAX)) { + *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1); *format_ret = 16; *size_ret = 1; - *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1); (*data_ret) [sizeof (short)] = 0; - (*(short **) data_ret) [0] = (short) XINT (obj); + (*(unsigned short **) data_ret) [0] = XINT (obj); if (NILP (type)) type = QINTEGER; } else if (INTEGERP (obj) @@ -1731,11 +1787,11 @@ || (CONSP (XCDR (obj)) && INTEGERP (XCAR (XCDR (obj))))))) { - *format_ret = 32; - *size_ret = 1; *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); + *format_ret = 32; + *size_ret = 1; (*data_ret) [sizeof (long)] = 0; - (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); + (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, X_ULONG_MAX); if (NILP (type)) type = QINTEGER; } else if (VECTORP (obj)) @@ -1744,50 +1800,54 @@ a set of 16 or 32 bit INTEGERs; or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...] */ - int i; + ptrdiff_t i; + ptrdiff_t size = ASIZE (obj); if (SYMBOLP (XVECTOR (obj)->contents [0])) /* This vector is an ATOM set */ { + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Atom) < size) + memory_full (SIZE_MAX); if (NILP (type)) type = QATOM; - *size_ret = ASIZE (obj); - *format_ret = 32; - for (i = 0; i < *size_ret; i++) + for (i = 0; i < size; i++) if (!SYMBOLP (XVECTOR (obj)->contents [i])) signal_error ("All elements of selection vector must have same type", obj); - *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom)); - for (i = 0; i < *size_ret; i++) + *data_ret = (unsigned char *) xmalloc (size * sizeof (Atom)); + *format_ret = 32; + *size_ret = size; + for (i = 0; i < size; i++) (*(Atom **) data_ret) [i] = symbol_to_x_atom (dpyinfo, XVECTOR (obj)->contents [i]); } else /* This vector is an INTEGER set, or something like it */ { + int format = 16; int data_size = 2; - *size_ret = ASIZE (obj); if (NILP (type)) type = QINTEGER; - *format_ret = 16; - for (i = 0; i < *size_ret; i++) - if (CONSP (XVECTOR (obj)->contents [i])) - *format_ret = 32; - else if (!INTEGERP (XVECTOR (obj)->contents [i])) - signal_error (/* Qselection_error */ - "Elements of selection vector must be integers or conses of integers", - obj); - - /* Use sizeof(long) even if it is more than 32 bits. See comment - in x_get_window_property and x_fill_property_data. */ - - if (*format_ret == 32) data_size = sizeof(long); - *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); - for (i = 0; i < *size_ret; i++) - if (*format_ret == 32) + for (i = 0; i < size; i++) + if (X_USHRT_MAX + < cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX)) + { + /* Use sizeof (long) even if it is more than 32 bits. + See comment in x_get_window_property and + x_fill_property_data. */ + data_size = sizeof (long); + format = 32; + } + if (min (PTRDIFF_MAX, SIZE_MAX) / data_size < size) + memory_full (SIZE_MAX); + *data_ret = (unsigned char *) xmalloc (size * data_size); + *format_ret = format; + *size_ret = size; + for (i = 0; i < size; i++) + if (format == 32) (*((unsigned long **) data_ret)) [i] = - cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); + cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX); else (*((unsigned short **) data_ret)) [i] = - cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); + cons_to_unsigned (XVECTOR (obj)->contents[i], X_USHRT_MAX); } } else @@ -1817,8 +1877,8 @@ } if (VECTORP (obj)) { - int i; - int size = ASIZE (obj); + ptrdiff_t i; + ptrdiff_t size = ASIZE (obj); Lisp_Object copy; if (size == 1) return clean_local_selection_data (XVECTOR (obj)->contents [0]); @@ -2213,6 +2273,8 @@ else if (CONSP (o) && (! NUMBERP (XCAR (o)) || ! NUMBERP (XCDR (o)))) return -1; + if (size == INT_MAX) + return -1; size++; } @@ -2294,8 +2356,11 @@ x_property_data_to_lisp (struct frame *f, const unsigned char *data, Atom type, int format, long unsigned int size) { + ptrdiff_t format_bytes = format >> 3; + if (PTRDIFF_MAX / format_bytes < size) + memory_full (SIZE_MAX); return selection_data_to_lisp_data (FRAME_X_DISPLAY (f), - data, size*format/8, type, format); + data, size * format_bytes, type, format); } /* Get the mouse position in frame relative coordinates. */ @@ -2405,10 +2470,10 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *dpyinfo->x_dnd_atoms / 2 < dpyinfo->x_dnd_atoms_size) memory_full (SIZE_MAX); + dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms, + (2 * sizeof *dpyinfo->x_dnd_atoms + * dpyinfo->x_dnd_atoms_size)); dpyinfo->x_dnd_atoms_size *= 2; - dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms, - sizeof (*dpyinfo->x_dnd_atoms) - * dpyinfo->x_dnd_atoms_size); } dpyinfo->x_dnd_atoms[dpyinfo->x_dnd_atoms_length++] = x_atom; @@ -2426,7 +2491,7 @@ unsigned long size = 160/event->format; int x, y; unsigned char *data = (unsigned char *) event->data.b; - int idata[5]; + unsigned int idata[5]; ptrdiff_t i; for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i) @@ -2444,7 +2509,7 @@ if (32 < BITS_PER_LONG && event->format == 32) { for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */ - idata[i] = (int) event->data.l[i]; + idata[i] = event->data.l[i]; data = (unsigned char *) idata; } === modified file 'src/xsmfns.c' --- src/xsmfns.c 2011-06-21 20:32:19 +0000 +++ src/xsmfns.c 2011-07-29 05:09:32 +0000 @@ -223,6 +223,9 @@ props[props_idx]->name = xstrdup (SmRestartCommand); props[props_idx]->type = xstrdup (SmLISTofARRAY8); /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */ + if (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *vp) - 3 + < initial_argc) + memory_full (SIZE_MAX); i = 3 + initial_argc; props[props_idx]->num_vals = i; vp = (SmPropValue *) xmalloc (i * sizeof(*vp)); === modified file 'src/xterm.c' --- src/xterm.c 2011-06-24 21:25:22 +0000 +++ src/xterm.c 2011-07-29 05:12:49 +0000 @@ -1625,19 +1625,21 @@ if (dpyinfo->color_cells == NULL) { Screen *screen = dpyinfo->screen; + int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); int i; - dpyinfo->ncolor_cells - = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (XColor) < ncolor_cells) + memory_full (SIZE_MAX); dpyinfo->color_cells - = (XColor *) xmalloc (dpyinfo->ncolor_cells + = (XColor *) xmalloc (ncolor_cells * sizeof *dpyinfo->color_cells); + dpyinfo->ncolor_cells = ncolor_cells; - for (i = 0; i < dpyinfo->ncolor_cells; ++i) + for (i = 0; i < ncolor_cells; ++i) dpyinfo->color_cells[i].pixel = i; XQueryColors (dpy, dpyinfo->cmap, - dpyinfo->color_cells, dpyinfo->ncolor_cells); + dpyinfo->color_cells, ncolor_cells); } *ncells = dpyinfo->ncolor_cells; @@ -4190,7 +4192,7 @@ x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ static struct window **scroll_bar_windows; -static size_t scroll_bar_windows_size; +static ptrdiff_t scroll_bar_windows_size; /* Send a client message with message type Xatom_Scrollbar for a @@ -4205,7 +4207,7 @@ XClientMessageEvent *ev = (XClientMessageEvent *) &event; struct window *w = XWINDOW (window); struct frame *f = XFRAME (w->frame); - size_t i; + ptrdiff_t i; BLOCK_INPUT; @@ -4226,12 +4228,16 @@ if (i == scroll_bar_windows_size) { - size_t new_size = max (10, 2 * scroll_bar_windows_size); - size_t nbytes = new_size * sizeof *scroll_bar_windows; - size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; - - if ((size_t) -1 / sizeof *scroll_bar_windows < new_size) + ptrdiff_t new_size, old_nbytes, nbytes; + /* Check the 32-bit XClientMessageEvent limit, as well as the + usual ptrdiff_t/size_t limit. */ + if (min (0x7fffffff, + min (PTRDIFF_MAX, SIZE_MAX) / sizeof *scroll_bar_windows / 2) + < scroll_bar_windows_size) memory_full (SIZE_MAX); + new_size = max (10, 2 * scroll_bar_windows_size); + nbytes = new_size * sizeof *scroll_bar_windows; + old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, nbytes); memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes); @@ -5813,7 +5819,7 @@ } inev; int count = 0; int do_help = 0; - int nbytes = 0; + ptrdiff_t nbytes = 0; struct frame *f = NULL; struct coding_system coding; XEvent event = *eventptr; @@ -6511,7 +6517,7 @@ } { /* Raw bytes, not keysym. */ - register int i; + ptrdiff_t i; int nchars, len; for (i = 0, nchars = 0; i < nbytes; i++) @@ -6524,7 +6530,11 @@ if (nchars < nbytes) { /* Decode the input data. */ - int require; + ptrdiff_t require; + + if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH + < nbytes) + memory_full (SIZE_MAX); /* The input should be decoded with `coding_system' which depends on which X*LookupString function @@ -9822,6 +9832,7 @@ struct x_display_info *dpyinfo; XrmDatabase xrdb; Mouse_HLInfo *hlinfo; + ptrdiff_t lim; BLOCK_INPUT; @@ -10040,12 +10051,15 @@ XSetAfterFunction (x_current_display, x_trace_wire); #endif /* ! 0 */ + lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@"; + if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name)) + memory_full (SIZE_MAX); dpyinfo->x_id_name = (char *) xmalloc (SBYTES (Vinvocation_name) + SBYTES (Vsystem_name) + 2); - sprintf (dpyinfo->x_id_name, "%s@%s", - SSDATA (Vinvocation_name), SSDATA (Vsystem_name)); + strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"), + SSDATA (Vsystem_name)); /* Figure out which modifier bits mean what. */ x_find_modifier_meanings (dpyinfo); # Begin bundle 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 ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-07-29 6:44 bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) Paul Eggert @ 2011-07-29 10:01 ` Jan Djärv 2011-07-29 16:21 ` Paul Eggert [not found] ` <handler.9196.B.131192196724343.ack@debbugs.gnu.org> 1 sibling, 1 reply; 13+ messages in thread From: Jan Djärv @ 2011-07-29 10:01 UTC (permalink / raw) To: Paul Eggert; +Cc: 9196 Hello. Since strlen is defined to return size_t and you store the result in a ptrdiff_t, does not that mean you have introduced a possible signed/unsigned conversion error? In gtkutil.c: + ptrdiff_t lim = min (TYPE_MAXIMUM (Window), + min (PTRDIFF_MAX, SIZE_MAX) / sizeof (GtkWidget *)); Isn't this a compile time constant? Should it not be a #define or something? IMHO, the check in gtkutil.c will only call memory_full when there is 2^31 (about 2 billion) scroll bars in Emacs. Isn't it overengineering to check for that case? In xgselect.c: + int gfds_size_max = + min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *gfds); Here a compile time constant is recalculated inside a loop. The xgselect.c is also overengineering IMHO. The number checked represents the number of file descriptor sources Glib is checking. I can understand checking sizes for strings that come from external sources, but only code adds file descriptor sources. If some bug causes the addition of 2 billion sources, a crash would be fine by me. Actually better than memory_full, because the core is much more useful. I haven't looked at the other files. I hope to find time to look at xselect.c at least. Jan D. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-07-29 10:01 ` Jan Djärv @ 2011-07-29 16:21 ` Paul Eggert 2011-07-29 16:49 ` Jan Djärv 0 siblings, 1 reply; 13+ messages in thread From: Paul Eggert @ 2011-07-29 16:21 UTC (permalink / raw) To: Jan Djärv; +Cc: 9196 First, thanks for taking a look at the patch. And in response to your comments ... On 07/29/11 03:01, Jan Djärv wrote: > a crash would be fine by me. Actually better than memory_full, > because the core is much more useful. We can easily arrange to crash, by replacing "memory_full (SIZE_MAX)" with "abort ()". I can do that for places where that's preferred. It sounds like xgselect.c is one of those places, so I'll do that; please let me know of any other places. > Since strlen is defined to return size_t and you store the result in > a ptrdiff_t, does not that mean you have introduced a possible > signed/unsigned conversion error? It would, if Emacs allowed objects with size greater than PTRDIFF_MAX. But Emacs doesn't, for two reasons. First, such objects would cause problems with C code, because pointer subtraction doesn't work within these objects, and Emacs uses pointer subtraction heavily. Second, the Emacs internal coding style prefers to avoid unsigned integers like size_t unless absolutely necessary (see <http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00514.html>). This is partly due to the confusion when comparing signed-to-unsigned. Also, it's nice to have the readily-available option of using hardware overflow-checking for signed integer overflow. Perhaps this should be documented somewhere ... > + ptrdiff_t lim = min (TYPE_MAXIMUM (Window), > + min (PTRDIFF_MAX, SIZE_MAX) / sizeof (GtkWidget *)); > > Isn't this a compile time constant? Should it not be a #define or something? It could be a #define, but it's needed only at that one location, and in that situation ordinary identifiers are clearer, less error-prone, and better for debugging than macros are. > IMHO, the check in gtkutil.c will only call memory_full when there > is 2^31 (about 2 billion) scroll bars in Emacs. Isn't it > overengineering to check for that case? I systematically looked for all places where memory is being allocated, and where size calculations might overflow during this, and fixed them all. It's better to have a systematic policy where all such size calculations are checked. Trying to decide heuristically which size overflows don't need checking because they can "never happen" would lead to further sources of maintenance error, and anyway the idea that some size overflows can "never happen" is uncomfortably close to the apocryphal story that "640K of memory should be enough for anybody". > In xgselect.c: > > + int gfds_size_max = > + min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *gfds); > > Here a compile time constant is recalculated inside a loop. Since it's a constant, the runtime cost of calculating it is zero, so there's no efficiency gain by moving it. Do you think it would be clearer to hoist it out of the loop? If so, we can easily do that; but there is something to be said for having the definition of the constant near its use. > The xgselect.c is also overengineering IMHO. The number checked > represents the number of file descriptor sources Glib is checking. > I can understand checking sizes for strings that come from external > sources, but only code adds file descriptor sources. If some bug > causes the addition of 2 billion sources 2 billion sources is not always the limit. On typical 32-bit hosts, the current code stops working at 500 million sources, or 250 million if one is worried about pointer subtraction. And if future glib versions change the associated struct, that 250-million limit could go down further. In cases like these, it's helpful to check the limit even if the check can "never fail". ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-07-29 16:21 ` Paul Eggert @ 2011-07-29 16:49 ` Jan Djärv 2011-07-29 21:03 ` Paul Eggert 0 siblings, 1 reply; 13+ messages in thread From: Jan Djärv @ 2011-07-29 16:49 UTC (permalink / raw) To: Paul Eggert; +Cc: 9196 Paul Eggert skrev 2011-07-29 18:21: > First, thanks for taking a look at the patch. And in response to your > comments ... > > On 07/29/11 03:01, Jan Djärv wrote: > >> a crash would be fine by me. Actually better than memory_full, >> because the core is much more useful. > > We can easily arrange to crash, by replacing "memory_full (SIZE_MAX)" > with "abort ()". I can do that for places where that's preferred. It > sounds like xgselect.c is one of those places, so I'll do that; please > let me know of any other places. The problem with abort is that gcc may optimize them to look like they occurred elsewhere. > I systematically looked for all places where memory is being > allocated, and where size calculations might overflow during this, and > fixed them all. It's better to have a systematic policy where all > such size calculations are checked. Trying to decide heuristically > which size overflows don't need checking because they can "never > happen" would lead to further sources of maintenance error, and anyway > the idea that some size overflows can "never happen" is uncomfortably > close to the apocryphal story that "640K of memory should be enough > for anybody". It is also a maintenance burden to keep all checks. More code that can go wrong, but it really add nothing. The difference with 640k is enough and 2 billion scroll bars is huge. If you create a scroll bar every tenth second, it will take approx 6.8 years to reach 2 billion. Why is it important to check for that? I do think it is important to reflect on what the code does and how limits are reached before adding more code that increases CPU and memory usage for no real benefit. >> In xgselect.c: >> >> + int gfds_size_max = >> + min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *gfds); >> >> Here a compile time constant is recalculated inside a loop. > > Since it's a constant, the runtime cost of calculating it is zero, so > there's no efficiency gain by moving it. I think you are assuming compiler optimizations here. They might be true for gcc, but not for other compilers. A define more clearly states that it is a constant than a computed variable. > Do you think it would be > clearer to hoist it out of the loop? Yes, and by declaring it const. But even better, a define. > If so, we can easily do that; > but there is something to be said for having the definition of the > constant near its use. > A define can be put anywhere. >> The xgselect.c is also overengineering IMHO. The number checked >> represents the number of file descriptor sources Glib is checking. >> I can understand checking sizes for strings that come from external >> sources, but only code adds file descriptor sources. If some bug >> causes the addition of 2 billion sources > > 2 billion sources is not always the limit. On typical 32-bit hosts, > the current code stops working at 500 million sources, or 250 million > if one is worried about pointer subtraction. And if future glib > versions change the associated struct, that 250-million limit could go > down further. In cases like these, it's helpful to check the limit > even if the check can "never fail". 250 million is way more than any OS can handle. What is the point of having Emacs check stuff that the OS simply can't handle anyway? Please come up with a real scenario when this may actually fail before adding checks. You aren't the one that has to take the time to update these checks when the code changes. You are putting maintenance burden on others without any real benefit. Jan D. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-07-29 16:49 ` Jan Djärv @ 2011-07-29 21:03 ` Paul Eggert 2011-07-30 5:52 ` Jan Djärv 0 siblings, 1 reply; 13+ messages in thread From: Paul Eggert @ 2011-07-29 21:03 UTC (permalink / raw) To: Jan Djärv; +Cc: 9196 On 07/29/11 09:49, Jan Djärv wrote: >>> + int gfds_size_max = >>> + min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *gfds); >>> >>> Here a compile time constant is recalculated inside a loop. >> >> Since it's a constant, the runtime cost of calculating it is zero, so >> there's no efficiency gain by moving it. > > I think you are assuming compiler optimizations here. They might be > true for gcc, but not for other compilers. A define more clearly > states that it is a constant than a computed variable. Sorry, I don't follow this. A 'define' wouldn't decrease the runtime cost, as a non-optimizing compiler would evaluate the expansion of the 'define' at runtime. Anyway, to address this issue I'll change it to an enum, which is guaranteed to be calculated at compile-time and clearly marks it as a constant. And I'll hoist it out of the function entirely. Something like this should do the trick: static GPollFD *gfds; static int gfds_size; enum { GFDS_SIZE_MAX = min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *gfds) }; > The problem with abort is that gcc may optimize them to look > like they occurred elsewhere. abort () is the standard way to trap within Emacs and other GNU programs. If there are problems with debugging calls to abort (), then we should address those problems, but surely that's a separate issue. Anyway, it's much easier to debug an abort () than a memory corruption. > It is also a maintenance burden to keep all checks.... > Please come up with a real scenario when this may actually fail > before adding checks. The scenario is when Emacs has more than about 250 million event sources. Admittedly this is quite unlikely now, but it may happen in the future, and the fix is easy now. Why not make sure Emacs is robust? We're talking about only two lines of code here: if (GFDS_SIZE_MAX / 2 < n_gfds) memory_full (SIZE_MAX); which take only 2 instructions in the typical case. Surely this is not too high a price to pay for reliability. If it's the code clutter that's the major objection here, we can use an inline function to shorten it to just one line, like this: check_size (n_gfds <= GFDS_SIZE_MAX / 2); This would have the same run-time cost (2 instructions), but would be easier to read. How about that idea? > You aren't the one that has to take the time > to update these checks when the code changes. If the code changes in such a way that these checks need to change, then the presence of the checks is a good thing. The checks will help remind programmers of the limits involved, and will help them avoid memory corruption in the future. Currently these issues are only in programmers' heads and are too often forgotten, and this can easily lead to bugs. Also, it's not really true that I won't be the one that has to take the time. I have been taking the time to maintain and improve these checks for months now. I've found several serious bugs in the process, some of which allow remote exploits. I expect to find more bugs, and I'll be happy to help in any future problems that crop up in this area. The goal is to have an Emacs implementation that is robust, rather than one that crashes when given input that was thought "couldn't happen". ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-07-29 21:03 ` Paul Eggert @ 2011-07-30 5:52 ` Jan Djärv 2011-07-30 19:16 ` Paul Eggert 0 siblings, 1 reply; 13+ messages in thread From: Jan Djärv @ 2011-07-30 5:52 UTC (permalink / raw) To: Paul Eggert; +Cc: 9196 Paul Eggert skrev 2011-07-29 23:03: > Also, it's not really true that I won't be the one that has to take > the time. I have been taking the time to maintain and improve these > checks for months now. I've found several serious bugs in the > process, some of which allow remote exploits. I expect to find more > bugs, and I'll be happy to help in any future problems that crop up > in this area. The goal is to have an Emacs implementation that is robust, > rather than one that crashes when given input that was thought > "couldn't happen". I have no problem with checks that fixes bugs. But the checks that check for more than 2 billion command line arguments or more than 2 billion scroll bars or more than 250 million i/o sources simply does not make sense. It is just clutter. Jan D. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-07-30 5:52 ` Jan Djärv @ 2011-07-30 19:16 ` Paul Eggert 2011-07-31 8:57 ` Jan Djärv 0 siblings, 1 reply; 13+ messages in thread From: Paul Eggert @ 2011-07-30 19:16 UTC (permalink / raw) To: Jan Djärv; +Cc: 9196 I take your point that the checks add clutter, so I'll revise the patch to address that problem, by adding a couple of memory allocators that do the proper overflow checking internally, so that callers don't need to test for integer overflow. This will take a bit of time to prepare and test, so please bear with me, but to give you a feel here's a draft of the revised patch to xgselect.c. This simplifies xgselect.c compared to what's in the trunk now. --- src/xgselect.c 2011-07-01 09:18:46 +0000 +++ src/xgselect.c 2011-07-30 18:19:51 +0000 @@ -54,10 +54,8 @@ do { if (n_gfds > gfds_size) { - while (n_gfds > gfds_size) - gfds_size *= 2; xfree (gfds); - gfds = xmalloc (sizeof (*gfds) * gfds_size); + gfds = xpmalloc (&gfds_size, n_gfds - gfds_size, INT_MAX, sizeof *gfds); } n_gfds = g_main_context_query (context, On 07/29/11 22:52, Jan Djärv wrote: > the checks that check for more than 2 billion command line arguments Those checks are necessary for GNU/Hurd, which places no limit on command line arguments, which means argc + 2 can overflow. That being said, the revised patch will address the clutter problem for the command-line issue as well, and the resulting emacs.c will be simpler than what's in the trunk now. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-07-30 19:16 ` Paul Eggert @ 2011-07-31 8:57 ` Jan Djärv 2011-08-05 2:33 ` Paul Eggert 0 siblings, 1 reply; 13+ messages in thread From: Jan Djärv @ 2011-07-31 8:57 UTC (permalink / raw) To: Paul Eggert; +Cc: 9196 Paul Eggert skrev 2011-07-30 21:16: > I take your point that the checks add clutter, so I'll > revise the patch to address that problem, by adding a > couple of memory allocators that do the proper overflow > checking internally, so that callers don't need to > test for integer overflow. > > This will take a bit of time to prepare and test, so > please bear with me, but to give you a feel here's a draft > of the revised patch to xgselect.c. This simplifies > xgselect.c compared to what's in the trunk now. > That is a good approach, very nice. > --- src/xgselect.c 2011-07-01 09:18:46 +0000 > +++ src/xgselect.c 2011-07-30 18:19:51 +0000 > @@ -54,10 +54,8 @@ > do { > if (n_gfds> gfds_size) > { > - while (n_gfds> gfds_size) > - gfds_size *= 2; > xfree (gfds); > - gfds = xmalloc (sizeof (*gfds) * gfds_size); > + gfds = xpmalloc (&gfds_size, n_gfds - gfds_size, INT_MAX, sizeof *gfds); > } > > n_gfds = g_main_context_query (context, > Jan D. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-07-31 8:57 ` Jan Djärv @ 2011-08-05 2:33 ` Paul Eggert 2011-08-05 9:26 ` Jan Djärv 0 siblings, 1 reply; 13+ messages in thread From: Paul Eggert @ 2011-08-05 2:33 UTC (permalink / raw) To: Jan Djärv; +Cc: 9196 On 07/31/11 01:57, Jan Djärv wrote: > That is a good approach, very nice. Thanks. Here's a revised patch for review, which takes that approach. It's relative to the current trunk. # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: eggert@cs.ucla.edu-20110805021934-x5nrdodqe23kjdg5 # target_branch: bzr+ssh://eggert@bzr.savannah.gnu.org/emacs/trunk # testament_sha1: 08476c1e7d5fc0bcd509fb3f909cd41ff6c7946f # timestamp: 2011-08-04 19:27:11 -0700 # source_branch: ../trunk # base_revision_id: yamaoka@jpl.org-20110804221404-ydk98tl1x07d17z8 # # Begin patch === modified file 'src/ChangeLog' --- src/ChangeLog 2011-08-04 17:04:39 +0000 +++ src/ChangeLog 2011-08-05 02:19:34 +0000 @@ -1,3 +1,413 @@ +2011-08-05 Paul Eggert <eggert@cs.ucla.edu> + + Integer and memory overflow issues. + + * charset.c (charset_table_size) + (struct charset_sort_data.priority): Now ptrdiff_t. + (charset_compare): Don't overflow if priorities differ greatly. + (Fsort_charsets): Don't assume list length fits in int. + Check for size-calculation overflow when allocating sort data. + (syms_of_charset): Allocate an initial charset table that is + just under 64 KiB, to avoid problems with glibc malloc and mmap. + + * cmds.c (internal_self_insert): Check for size-calculation overflow. + + * composite.h (struct composition.glyph_len): Now int, not unsigned. + The actual value is always <= INT_MAX, and leaving it unsigned made + overflow checking harder. + + * dispextern.h (struct glyph_matrix.rows_allocated) + (struct face_cache.size): Now ptrdiff_t, for convenience in use + with xpalloc. The values are still always <= INT_MAX. + + * indent.c (compute_motion): Adjust to region_cache_forward sig change. + + * lisp.h (xnmalloc, xnrealloc, xpalloc): New decls. + (SAFE_NALLOCA): New macro. + + * region-cache.c (struct boundary.pos, find_cache_boundary) + (move_cache_gap, insert_cache_boundary, delete_cache_boundaries) + (set_cache_region, invalidate_region_cache) + (revalidate_region_cache, know_region_cache, region_cache_forward) + (region_cache_backward, pp_cache): + Use ptrdiff_t, not EMACS_INT, since either will do. This is needed + so that ptrdiff_t * can be passed to xpalloc. + (struct region_cache): Similarly, for gap_start, gap_len, cache_len, + beg_unchanged, end_unchanged, buffer_beg, buffer_end members. + (pp_cache): Don't assume cache_len fits in int. + * region-cache.h: Adjust extern decls to match. + + * search.c (scan_buffer, Freplace_match): Use ptrdiff_t, not + EMACS_INT, since either will do, for xpalloc. + + * alloc.c: Include verify.h, and check that int fits in ptrdiff_t. + (xnmalloc, xnrealloc, xpalloc): New functions. + + * bidi.c (bidi_shelve_header_size): New constant. + (bidi_cache_ensure_space, bidi_shelve_cache): Use it. + (bidi_cache_ensure_space): Avoid integer overflow when allocating. + + * buffer.c (overlays_at, overlays_in, record_overlay_string) + (overlay_strings): + Don't update size of array until after memory allocation succeeds, + because xmalloc/xrealloc may not return. + (struct sortstrlist.bytes): Now ptrdiff_t, as EMACS_INT doesn't help + now that we have proper integer overflow checking. + (record_overlay_string, overlay_strings): Catch overflows when + calculating size of overlay_str_buf. + + * callproc.c (Fcall_process): Check for size overflow when + calculating size of args2. + (child_setup): Avoid overflow by using size_t rather than ptrdiff_t. + Normally we prefer signed values, but sticking with ptrdiff_t would + require adding more-complicated checks. + + * ccl.c (Fccl_execute_on_string): Check for memory overflow. + Use ptrdiff_t rather than EMACS_INT where ptrdiff_t will do. + Redo buffer-overflow calculations to avoid integer overflow. + Add a FIXME comment where memory seems to be over-allocated. + + * character.c (Fstring): Check for size-calculation overflow. + + * coding.c (produce_chars): Redo buffer-overflow calculations to avoid + unnecessary integer overflow. Check for size overflow. + (encode_coding_object): Don't update size until xmalloc succeeds. + + * composite.c (get_composition_id): Check for overflow in glyph + length calculations. + + Integer and memory overflow fixes for display code. + * dispextern.h (struct glyph_pool.nglyphs): Now ptrdiff_t, not int. + * dispnew.c (adjust_glyph_matrix, realloc_glyph_pool) + (scrolling_window): Check for overflow in size calculations. + (line_draw_cost, realloc_glyph_pool, add_row_entry): + Don't assume glyph table len fits in int. + (struct row_entry.bucket, row_entry_pool_size, row_entry_idx) + (row_table_size): Now ptrdiff_t, not int. + (scrolling_window): Avoid overflow in size calculations. + Don't update size until allocation succeeds. + * fns.c (concat): Check for overflow in size calculations. + (next_almost_prime): Verify NEXT_ALMOST_PRIME_LIMIT. + * lisp.h (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): New macros. + (NEXT_ALMOST_PRIME_LIMIT): New constant. + + * doc.c (get_doc_string_buffer_size): Now ptrdiff_t, not int. + (get_doc_string): Check for size calculation overflow. + Don't update size until allocation succeeds. + (get_doc_string, Fsubstitute_command_keys): Use ptrdiff_t, not + EMACS_INT, where ptrdiff_t will do. + (Fsubstitute_command_keys): Check for string overflow. + + * editfns.c (set_time_zone_rule): Don't assume environment length + fits in int. + (message_length): Now ptrdiff_t, not int. + (Fmessage_box): Don't update size until allocation succeeds. + Don't assume message length fits in int. + (Fformat): Use ptrdiff_t, not EMACS_INT, where ptrdiff_t will do. + + * emacs.c (main): Do not reallocate argv, since there is a null at + the end that can be overwritten, and this way there's no need to + worry about size-calculation overflow. + (sort_args): Check for size-calculation overflow. + + * eval.c (init_eval_once, grow_specpdl): Don't update size until + alloc succeeds. + (call_debugger, grow_specpdl): Redo calculations to avoid overflow. + + * frame.c (set_menu_bar_lines, x_set_frame_parameters) + (x_set_scroll_bar_width, x_figure_window_size): + Check for integer overflow. + (x_set_alpha): Do not assume XINT fits in int. + + * frame.h (struct frame): Use int, not EMACS_INT, where int works. + This is for the members text_lines, text_cols, total_lines, total_cols, + where the system imposes an 'int' limit. + + * fringe.c (Fdefine_fringe_bitmap): + Don't update size until alloc works. + + * ftfont.c (ftfont_get_open_type_spec, setup_otf_gstring) + (ftfont_shape_by_flt): Check for integer overflow in size calculations. + + * gtkutil.c (get_utf8_string, xg_store_widget_in_map): + Check for size-calculation overflow. + (get_utf8_string): Use ptrdiff_t, not size_t, where either will + do, as we prefer signed integers. + (id_to_widget.max_size, id_to_widget.used) + (xg_store_widget_in_map, xg_remove_widget_from_map) + (xg_get_widget_from_map, xg_get_scroll_id_for_window) + (xg_remove_scroll_bar, xg_update_scrollbar_pos): + Use and return ptrdiff_t, not int. + (xg_gtk_scroll_destroy): Don't assume ptrdiff_t fits in int. + * gtkutil.h: Change prototypes to match the above. + + * image.c (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): Remove; these + are duplicate now that they've been promoted to lisp.h. + (x_allocate_bitmap_record, x_alloc_image_color) + (make_image_cache, cache_image, xpm_load): + Don't update size until alloc is done. + (xpm_load, lookup_rgb_color, lookup_pixel_color, x_to_xcolors) + (x_detect_edges): + Check for size calculation overflow. + (ct_colors_allocated_max): New constant. + (x_to_xcolors, x_detect_edges): Reorder multiplicands to avoid + overflow. + + * keyboard.c (read_char, menu_bar_items, tool_bar_items) + (read_char_x_menu_prompt, read_char_minibuf_menu_width) + (read_char_minibuf_menu_prompt, follow_key, read_key_sequence): + Use ptrdiff_t, not int, to count maps. + (read_char_minibuf_menu_prompt): Check for overflow in size + calculations. Don't update size until allocation succeeds. Redo + calculations to avoid overflow. + * keyboard.h: Change prototypes to match the above. + + * keymap.c (cmm_size, current_minor_maps): Use ptrdiff_t, not int, + to count maps. + (current_minor_maps): Check for size calculation overflow. + * keymap.h: Change prototypes to match the above. + + * lread.c (read1, init_obarray): Don't update size until alloc done. + + * macros.c (Fstart_kbd_macro): Don't update size until alloc done. + (store_kbd_macro_char): Reorder multiplicands to avoid overflow. + + * nsterm.h (struct ns_color_table.size, struct ns_color_table.avail): + Now ptrdiff_t, not int. + * nsterm.m (ns_index_color): Use ptrdiff_t, not int, for table indexes. + (ns_draw_fringe_bitmap): Rewrite to avoid overflow. + + * process.c (Fnetwork_interface_list): Check for overflow + in size calculation. + + * region-cache.c (move_cache_gap): Check for size calculation overflow. + + * scroll.c (do_line_insertion_deletion_costs): Check for size calc + overflow. Don't bother calling xmalloc when xrealloc will do. + + * search.c (Freplace_match): Check for size calculation overflow. + (Fset_match_data): Don't assume list lengths fit in 'int'. + + * sysdep.c (system_process_attributes): Use ptrdiff_t, not int, + for command line length. Do not attempt to address one before the + beginning of an array, as that's not portable. + + * term.c (max_frame_lines): Remove; unused. + (encode_terminal_src_size, encode_terminal_dst_size): Now ptrdiff_t, + not int. + (encode_terminal_code, calculate_costs): Check for size + calculation overflow. + (encode_terminal_code): Use ptrdiff_t, not int, to record glyph + table lengths and related sizes. Don't update size until alloc + done. Redo calculations to avoid overflow. + (calculate_costs): Don't bother calling xmalloc when xrealloc will do. + + * termcap.c (tgetent): Use ptrdiff_t, not int, to record results of + subtracting pointers. + (gobble_line): Check for overflow more carefully. Don't update size + until alloc done. + + * tparam.c (tparam1): Use ptrdiff_t, not int, for sizes. + Don't update size until alloc done. + Redo size calculations to avoid overflow. + Check for size calculation overflow. + (main) [DEBUG]: Fix typo in invoking tparam1. + + * xdisp.c (store_mode_line_noprop_char, x_consider_frame_title): + Use ptrdiff_t, not int, for sizes. + (store_mode_line_noprop_char): Don't update size until alloc done. + + * xfaces.c (lface_id_to_name_size, Finternal_make_lisp_face): + Use ptrdiff_t, not int, for sizes. + (Finternal_make_lisp_face, cache_face): + Check for size calculation overflow. + (cache_face): Treat size calculation overflows as if they were + memory exhaustion (the usual treatment), rather than aborting. + + * xfns.c (x_encode_text, x_set_name_internal) + (Fx_change_window_property): Use ptrdiff_t, not int, to count + sizes, since they can exceed INT_MAX in size. Check for size + calculation overflow. + + * xgselect.c (gfds_size): Now ptrdiff_t, for convenience with xpalloc. + (xg_select): Check for size calculation overflow. + Don't update size until alloc done. + + * xrdb.c (get_environ_db): Don't assume path length fits in int, + as sprintf is limited to int lengths. + + * xselect.c (X_LONG_SIZE, X_USHRT_MAX, X_ULONG_MAX): New macros. + Use them to make the following changes clearer. + (MAX_SELECTION_QUANTUM): Make the other bounds on this value clearer. + This change doesn't affect the value now, but it may help remind + future maintainers not to raise the value too much later. + (SELECTION_QUANTUM): Remove, replacing with ... + (selection_quantum): ... new function, which avoids overflow. + All uses changed. + (struct selection_data.size): Now ptrdiff_t, not int, to avoid + assumption that selection length fits in 'int'. + (x_reply_selection_request, x_handle_selection_request) + (x_get_window_property, receive_incremental_selection) + (x_get_window_property_as_lisp_data, selection_data_to_lisp_data) + (lisp_data_to_selection_data, clean_local_selection_data): + Use ptrdiff_t, not int, to record length of selection. + (x_reply_selection_request, x_get_window_property) + (receive_incremental_selection, x_property_data_to_lisp): + Redo calculations to avoid overflow. + (x_reply_selection_request): When sending hint, ceiling it at + X_ULONG_MAX rather than relying on wraparound overflow to send + something. + (x_get_window_property, receive_incremental_selection) + (lisp_data_to_selection_data, x_property_data_to_lisp): + Check for size-calculation overflow. + (x_get_window_property, receive_incremental_selection) + (lisp_data_to_selection_data, Fx_register_dnd_atom): + Don't store size until memory allocation succeeds. + (x_get_window_property): Plug memory leak on memory exhaustion. + Don't double-block input; malloc is safe here. Don't assume 2**34 + - 4 fits in unsigned long. Add an xassert to check + XGetWindowProperty overflow. Be more careful about overflow + calculations, and distinguish size from memory overflow better. + (receive_incremental_selection): When tracing, don't assume + unsigned int is less than INT_MAX. + (x_selection_data_to_lisp_data): Remove unnecessary (and in theory + harmful) conversions of unsigned short to int. + (lisp_data_to_selection_data): Don't assume that integers + in the range -65535 through -1 fit in an X unsigned short. + Don't assume that ULONG_MAX == X_ULONG_MAX. Don't store into + result parameters unless successful. Rely on cons_to_unsigned + to report problems with elements; the old code wasn't right anyway. + (x_check_property_data): Check for int overflow; we cannot use + a wider type due to X limits. + (x_handle_dnd_message): Use unsigned int, to avoid int overflow. + + * xsmfns.c (smc_save_yourself_CB): Check for size calc overflow. + + * xterm.c (x_color_cells, x_send_scrollbar_event, handle_one_xevent) + (x_term_init): Check for size calculation overflow. + (x_color_cells): Don't store size until memory allocation succeeds. + (handle_one_xevent): Use ptrdiff_t, not int, for byte counts. + Don't assume alloca size is less than MAX_ALLOCA. + (x_term_init): Don't assume length fits in int (sprintf is limited + to int size). + + Use ptrdiff_t for composition IDs. + * character.c (lisp_string_width): + * composite.c (composition_table_size, n_compositions) + (get_composition_id, composition_gstring_from_id): + * dispextern.h (struct glyph_string.cmp_id, struct composition_it.id): + * xdisp.c (BUILD_COMPOSITE_GLYPH_STRING): + * window.c (Frecenter): + Use ptrdiff_t, not int, for composition IDs. + * composite.c (get_composition_id): Check for integer overflow. + * composite.h: Adjust prototypes to match the above changes. + + Use ptrdiff_t for hash table indexes. + * category.c (hash_get_category_set): + * ccl.c (ccl_driver): + * charset.h (struct charset.hash_index, CHECK_CHARSET_GET_ID): + * coding.c (coding_system_charset_list, detect_coding_system): + * coding.h (struct coding_system.id): + * composite.c (get_composition_id, gstring_lookup_cache): + * fns.c (hash_lookup, hash_put, Fgethash, Fputhash): + * image.c (xpm_get_color_table_h): + * lisp.h (hash_lookup, hash_put): + * minibuf.c (Ftest_completion): + Use ptrdiff_t for hash table indexes, not int (which is too + narrow, on 64-bit hosts) or EMACS_INT (which is too wide, on + 32-bit --with-wide-int hosts). + + * charset.c (Fdefine_charset_internal): Check for integer overflow. + Add a FIXME comment about memory leaks. + (syms_of_charset): Don't assume xmalloc returns. + + Don't assume that stated character widths fit in int. + * character.c (Fchar_width, c_string_width, lisp_string_width): + * character.h (CHAR_WIDTH): + * indent.c (MULTIBYTE_BYTES_WIDTH): + Use sanitize_char_width to avoid undefined and/or bad behavior + with outlandish widths. + * character.h (sanitize_tab_width): Renamed from sanitize_width, + now that we have two such functions. All uses changed. + (sanitize_char_width): New inline function. + + Don't assume that tab-width fits in int. + * character.h (sanitize_width): New inline function. + (SANE_TAB_WIDTH): New macro. + (ASCII_CHAR_WIDTH): Use it. + * indent.c (sane_tab_width): Remove. All uses replaced by + SANE_TAB_WIDTH (current_buffer). + * xdisp.c (init_iterator): Use SANE_TAB_WIDTH. + + * fileio.c: Integer overflow issues with file modes. + (Fset_file_modes, auto_save_1): Don't assume EMACS_INT fits in int. + + * charset.c (read_hex): New arg OVERFLOW. All uses changed. + Remove unreachable code. + (read_hex, load_charset_map_from_file): Check for integer overflow. + + * xterm.c: don't go over XClientMessageEvent limit + (scroll_bar_windows_size): Now ptrdiff_t, as we prefer signed. + (x_send_scroll_bar_event): Likewise. Check that the size does not + exceed limits imposed by XClientMessageEvent, as well as the usual + ptrdiff_t and size_t limits. + + * keyboard.c: Overflow, signedness and related fixes. + (make_lispy_movement): Use same integer type in forward decl + that is used in the definition. + (read_key_sequence, keyremap_step): + Change bufsize argument back to int, undoing my 2011-03-30 change. + We prefer signed types, and int is wide enough here. + (parse_tool_bar_item): Don't assume tool_bar_max_label_size is less + than TYPE_MAXIMUM (EMACS_INT) / 2. Don't let the label size grow + larger than STRING_BYTES_BOUND. Use ptrdiff_t for Emacs string + length, not size_t. Use ptrdiff_t for index, not int. + (keyremap_step, read_key_sequence): Redo bufsize check to avoid + possibility of integer overflow. + + Overflow, signedness and related fixes for images. + + * dispextern.h (struct it.stack[0].u.image.image_id) + (struct_it.image_id, struct image.id, struct image_cache.size) + (struct image_cache.used, struct image_cache.ref_count): + * gtkutil.c (update_frame_tool_bar): + * image.c (x_reference_bitmap, Fimage_size, Fimage_mask_p) + (Fimage_metadata, free_image_cache, clear_image_cache, lookup_image) + (cache_image, mark_image_cache, x_kill_gs_process, Flookup_image): + * nsmenu.m (update_frame_tool_bar): + * xdisp.c (calc_pixel_width_or_height): + * xfns.c (image_cache_refcount): + Image IDs are now ptrdiff_t, not int, to avoid arbitrary limits + on typical 64-bit hosts. + + * image.c (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): New macros. + (x_bitmap_pixmap, x_create_x_image_and_pixmap): + Omit unnecessary casts to int. + (parse_image_spec): Check that integers fall into 'int' range + when the callers expect that. + (image_ascent): Redo ascent calculation to avoid int overflow. + (clear_image_cache): Avoid overflow when sqrt (INT_MAX) < nimages. + (lookup_image): Remove unnecessary tests. + (xbm_image_p): Locals are now of int, not EMACS_INT, + since parse_image_check makes sure they fit into int. + (png_load, gif_load, svg_load_image): + Prefer int to unsigned where either will do. + (tiff_handler): New function, combining the cores of the + old tiff_error_handler and tiff_warning_handler. This + function is rewritten to use vsnprintf and thereby avoid + stack buffer overflows. It uses only the features of vsnprintf + that are common to both POSIX and native Microsoft. + (tiff_error_handler, tiff_warning_handler): Use it. + (tiff_load, gif_load, imagemagick_load_image): + Don't assume :index value fits in 'int'. + (gif_load): Omit unnecessary cast to double, and avoid double-rounding. + (imagemagick_load_image): Check that crop parameters fit into + the integer types that MagickCropImage accepts. Don't assume + Vimagemagick_render_type has a nonnegative value. Don't assume + size_t fits in 'long'. + (gs_load): Use printmax_t to print the widest integers possible. + Check for integer overflow when computing image height and width. + 2011-08-04 Jan Djärv <jan.h.d@swipnet.se> * Makefile.in (LIB_PTHREAD): New variable. === modified file 'src/alloc.c' --- src/alloc.c 2011-08-04 17:04:39 +0000 +++ src/alloc.c 2011-08-05 02:19:34 +0000 @@ -46,6 +46,7 @@ #include "syssignal.h" #include "termhooks.h" /* For struct terminal. */ #include <setjmp.h> +#include <verify.h> /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd memory. Can do this only if using gmalloc.c. */ @@ -733,6 +734,93 @@ } +/* Other parts of Emacs pass large int values to allocator functions + expecting ptrdiff_t. This is portable in practice, but check it to + be safe. */ +verify (INT_MAX <= PTRDIFF_MAX); + + +/* Allocate an array of NITEMS items, each of size ITEM_SIZE. + Signal an error on memory exhaustion, and block interrupt input. */ + +void * +xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size) +{ + xassert (0 <= nitems && 0 < item_size); + if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems) + memory_full (SIZE_MAX); + return xmalloc (nitems * item_size); +} + + +/* Reallocate an array PA to make it of NITEMS items, each of size ITEM_SIZE. + Signal an error on memory exhaustion, and block interrupt input. */ + +void * +xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) +{ + xassert (0 <= nitems && 0 < item_size); + if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems) + memory_full (SIZE_MAX); + return xrealloc (pa, nitems * item_size); +} + + +/* Grow PA, which points to an array of *NITEMS items, and return the + location of the reallocated array, updating *NITEMS to reflect its + new size. The new array will contain at least NITEMS_INCR_MIN more + items, but will not contain more than NITEMS_MAX items total. + ITEM_SIZE is the size of each item, in bytes. + + ITEM_SIZE and NITEMS_INCR_MIN must be positive. *NITEMS must be + nonnegative. If NITEMS_MAX is -1, it is treated as if it were + infinity. + + If PA is null, then allocate a new array instead of reallocating + the old one. Thus, to grow an array A without saving its old + contents, invoke xfree (A) immediately followed by xgrowalloc (0, + &NITEMS, ...). + + Block interrupt input as needed. If memory exhaustion occurs, set + *NITEMS to zero if PA is null, and signal an error (i.e., do not + return). */ + +void * +xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, + ptrdiff_t nitems_max, ptrdiff_t item_size) +{ + /* The approximate size to use for initial small allocation + requests. This is the largest "small" request for the GNU C + library malloc. */ + enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; + + /* If the array is tiny, grow it to about (but no greater than) + DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. */ + ptrdiff_t n = *nitems; + ptrdiff_t tiny_max = DEFAULT_MXFAST / item_size - n; + ptrdiff_t half_again = n >> 1; + ptrdiff_t incr_estimate = max (tiny_max, half_again); + + /* Adjust the increment according to three constraints: NITEMS_INCR_MIN, + NITEMS_MAX, and what the C language can represent safely. */ + ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / item_size; + ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max + ? nitems_max : C_language_max); + ptrdiff_t nitems_incr_max = n_max - n; + ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max)); + + xassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max); + if (! pa) + *nitems = 0; + if (nitems_incr_max < incr) + memory_full (SIZE_MAX); + n += incr; + pa = xrealloc (pa, n * item_size); + *nitems = n; + return pa; +} + + /* Like strdup, but uses xmalloc. */ char * === modified file 'src/bidi.c' --- src/bidi.c 2011-08-02 19:16:32 +0000 +++ src/bidi.c 2011-08-05 02:19:34 +0000 @@ -306,6 +306,21 @@ static ptrdiff_t bidi_cache_start = 0; /* start of cache for this "stack" level */ +/* 5-slot stack for saving the start of the previous level of the + cache. xdisp.c maintains a 5-slot stack for its iterator state, + and we need the same size of our stack. */ +static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; +static int bidi_cache_sp; + +/* Size of header used by bidi_shelve_cache. */ +enum + { + bidi_shelve_header_size = + (sizeof (bidi_cache_idx) + sizeof (bidi_cache_start_stack) + + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) + + sizeof (bidi_cache_last_idx)) + }; + /* Reset the cache state to the empty state. We only reset the part of the cache relevant to iteration of the current object. Previous objects, which are pushed on the display iterator's stack, are left @@ -463,21 +478,19 @@ /* Enlarge the cache as needed. */ if (idx >= bidi_cache_size) { - ptrdiff_t new_size; - /* The bidi cache cannot be larger than the largest Lisp string or buffer. */ ptrdiff_t string_or_buffer_bound = max (BUF_BYTES_MAX, STRING_BYTES_BOUND); /* Also, it cannot be larger than what C can represent. */ - ptrdiff_t c_bound = min (PTRDIFF_MAX, SIZE_MAX) / elsz; + ptrdiff_t c_bound = + (min (PTRDIFF_MAX, SIZE_MAX) - bidi_shelve_header_size) / elsz; - if (min (string_or_buffer_bound, c_bound) <= idx) - memory_full (SIZE_MAX); - new_size = idx - idx % BIDI_CACHE_CHUNK + BIDI_CACHE_CHUNK; - bidi_cache = (struct bidi_it *) xrealloc (bidi_cache, new_size * elsz); - bidi_cache_size = new_size; + bidi_cache = + xpalloc (bidi_cache, &bidi_cache_size, + max (BIDI_CACHE_CHUNK, idx - bidi_cache_size + 1), + min (string_or_buffer_bound, c_bound), elsz); } } @@ -568,11 +581,6 @@ /*********************************************************************** Pushing and popping the bidi iterator state ***********************************************************************/ -/* 5-slot stack for saving the start of the previous level of the - cache. xdisp.c maintains a 5-slot stack for its iterator state, - and we need the same size of our stack. */ -static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; -static int bidi_cache_sp; /* Push the bidi iterator state in preparation for reordering a different object, e.g. display string found at certain buffer @@ -629,11 +637,8 @@ if (bidi_cache_idx == 0) return NULL; - databuf = xmalloc (sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack) - + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) - + sizeof (bidi_cache_last_idx)); + databuf = xmalloc (bidi_shelve_header_size + + bidi_cache_idx * sizeof (struct bidi_it)); memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); memcpy (databuf + sizeof (bidi_cache_idx), bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); === modified file 'src/buffer.c' --- src/buffer.c 2011-07-28 17:46:21 +0000 +++ src/buffer.c 2011-08-05 02:15:35 +0000 @@ -2568,13 +2568,10 @@ Either make it bigger, or don't store any more in it. */ if (extend) { - if ((OVERLAY_COUNT_MAX - 4) / 2 < len) - memory_full (SIZE_MAX); - /* Make it work with an initial len == 0. */ - len = len * 2 + 4; - *len_ptr = len; - vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); + vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, + sizeof *vec); *vec_ptr = vec; + len = *len_ptr; } else inhibit_storing = 1; @@ -2611,13 +2608,10 @@ { if (extend) { - if ((OVERLAY_COUNT_MAX - 4) / 2 < len) - memory_full (SIZE_MAX); - /* Make it work with an initial len == 0. */ - len = len * 2 + 4; - *len_ptr = len; - vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); + vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, + sizeof *vec); *vec_ptr = vec; + len = *len_ptr; } else inhibit_storing = 1; @@ -2708,13 +2702,10 @@ Either make it bigger, or don't store any more in it. */ if (extend) { - if ((OVERLAY_COUNT_MAX - 4) / 2 < len) - memory_full (SIZE_MAX); - /* Make it work with an initial len == 0. */ - len = len * 2 + 4; - *len_ptr = len; - vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); + vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, + sizeof *vec); *vec_ptr = vec; + len = *len_ptr; } else inhibit_storing = 1; @@ -2756,13 +2747,10 @@ { if (extend) { - if ((OVERLAY_COUNT_MAX - 4) / 2 < len) - memory_full (SIZE_MAX); - /* Make it work with an initial len == 0. */ - len = len * 2 + 4; - *len_ptr = len; - vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object)); + vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX, + sizeof *vec); *vec_ptr = vec; + len = *len_ptr; } else inhibit_storing = 1; @@ -2944,7 +2932,7 @@ struct sortstr *buf; /* An array that expands as needed; never freed. */ ptrdiff_t size; /* Allocated length of that array. */ ptrdiff_t used; /* How much of the array is currently in use. */ - EMACS_INT bytes; /* Total length of the strings in buf. */ + ptrdiff_t bytes; /* Total length of the strings in buf. */ }; /* Buffers for storing information about the overlays touching a given @@ -2977,17 +2965,7 @@ EMACS_INT nbytes; if (ssl->used == ssl->size) - { - if (min (PTRDIFF_MAX, SIZE_MAX) / (sizeof (struct sortstr) * 2) - < ssl->size) - memory_full (SIZE_MAX); - else if (0 < ssl->size) - ssl->size *= 2; - else - ssl->size = 5; - ssl->buf = ((struct sortstr *) - xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr))); - } + ssl->buf = xpalloc (ssl->buf, &ssl->size, 5, -1, sizeof *ssl->buf); ssl->buf[ssl->used].string = str; ssl->buf[ssl->used].string2 = str2; ssl->buf[ssl->used].size = size; @@ -3002,6 +2980,8 @@ else nbytes = SBYTES (str); + if (INT_ADD_OVERFLOW (ssl->bytes, nbytes)) + memory_full (SIZE_MAX); ssl->bytes += nbytes; if (STRINGP (str2)) @@ -3014,6 +2994,8 @@ else nbytes = SBYTES (str2); + if (INT_ADD_OVERFLOW (ssl->bytes, nbytes)) + memory_full (SIZE_MAX); ssl->bytes += nbytes; } } @@ -3107,14 +3089,15 @@ Lisp_Object tem; EMACS_INT i; unsigned char *p; - EMACS_INT total = overlay_heads.bytes + overlay_tails.bytes; + ptrdiff_t total; + if (INT_ADD_OVERFLOW (overlay_heads.bytes, overlay_tails.bytes)) + memory_full (SIZE_MAX); + total = overlay_heads.bytes + overlay_tails.bytes; if (total > overlay_str_len) - { - overlay_str_len = total; - overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf, - total); - } + overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len, + total - overlay_str_len, -1, 1); + p = overlay_str_buf; for (i = overlay_tails.used; --i >= 0;) { === modified file 'src/callproc.c' --- src/callproc.c 2011-08-04 03:08:01 +0000 +++ src/callproc.c 2011-08-05 02:19:34 +0000 @@ -252,7 +252,7 @@ val = Qraw_text; else { - SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2); + SAFE_NALLOCA (args2, 1, nargs + 1); args2[0] = Qcall_process; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; coding_systems = Ffind_operation_coding_system (nargs + 1, args2); @@ -726,7 +726,7 @@ { ptrdiff_t i; - SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2); + SAFE_NALLOCA (args2, 1, nargs + 1); args2[0] = Qcall_process; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; coding_systems @@ -1024,7 +1024,7 @@ else { USE_SAFE_ALLOCA; - SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2); + SAFE_NALLOCA (args2, 1, nargs + 1); args2[0] = Qcall_process_region; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; coding_systems = Ffind_operation_coding_system (nargs + 1, args2); @@ -1153,7 +1153,7 @@ cleaned up in the usual way. */ { register char *temp; - register int i; + size_t i; /* size_t, because ptrdiff_t might overflow here! */ i = SBYTES (current_dir); #ifdef MSDOS === modified file 'src/category.c' --- src/category.c 2011-06-24 21:25:22 +0000 +++ src/category.c 2011-07-19 06:07:07 +0000 @@ -67,7 +67,7 @@ hash_get_category_set (Lisp_Object table, Lisp_Object category_set) { struct Lisp_Hash_Table *h; - EMACS_INT i; + ptrdiff_t i; EMACS_UINT hash; if (NILP (XCHAR_TABLE (table)->extras[1])) === modified file 'src/ccl.c' --- src/ccl.c 2011-06-24 21:25:22 +0000 +++ src/ccl.c 2011-08-05 02:15:35 +0000 @@ -1303,7 +1303,7 @@ case CCL_LookupIntConstTbl: { - EMACS_INT eop; + ptrdiff_t eop; struct Lisp_Hash_Table *h; GET_CCL_RANGE (eop, ccl_prog, ic++, 0, (VECTORP (Vtranslation_hash_table_vector) @@ -1329,7 +1329,7 @@ case CCL_LookupCharConstTbl: { - EMACS_INT eop; + ptrdiff_t eop; struct Lisp_Hash_Table *h; GET_CCL_RANGE (eop, ccl_prog, ic++, 0, (VECTORP (Vtranslation_hash_table_vector) @@ -2061,12 +2061,13 @@ Lisp_Object val; struct ccl_program ccl; int i; - EMACS_INT outbufsize; + ptrdiff_t outbufsize; unsigned char *outbuf, *outp; - EMACS_INT str_chars, str_bytes; + ptrdiff_t str_chars, str_bytes; #define CCL_EXECUTE_BUF_SIZE 1024 int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE]; - EMACS_INT consumed_chars, consumed_bytes, produced_chars; + ptrdiff_t consumed_chars, consumed_bytes, produced_chars; + int buf_magnification; if (setup_ccl_program (&ccl, ccl_prog) < 0) error ("Invalid CCL program"); @@ -2093,6 +2094,10 @@ ccl.ic = i; } + buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1; + + if ((min (PTRDIFF_MAX, SIZE_MAX) - 256) / buf_magnification < str_bytes) + memory_full (SIZE_MAX); outbufsize = (ccl.buf_magnification ? str_bytes * ccl.buf_magnification + 256 : str_bytes + 256); @@ -2127,12 +2132,18 @@ produced_chars += ccl.produced; if (NILP (unibyte_p)) { - if (outp - outbuf + MAX_MULTIBYTE_LENGTH * ccl.produced - > outbufsize) + /* FIXME: Surely this should be buf_magnification instead. + MAX_MULTIBYTE_LENGTH overestimates the storage needed. */ + int magnification = MAX_MULTIBYTE_LENGTH; + + ptrdiff_t offset = outp - outbuf; + ptrdiff_t shortfall; + if (INT_MULTIPLY_OVERFLOW (ccl.produced, magnification)) + memory_full (SIZE_MAX); + shortfall = ccl.produced * magnification - (outbufsize - offset); + if (0 < shortfall) { - EMACS_INT offset = outp - outbuf; - outbufsize += MAX_MULTIBYTE_LENGTH * ccl.produced; - outbuf = (unsigned char *) xrealloc (outbuf, outbufsize); + outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1); outp = outbuf + offset; } for (j = 0; j < ccl.produced; j++) @@ -2140,11 +2151,11 @@ } else { - if (outp - outbuf + ccl.produced > outbufsize) + ptrdiff_t offset = outp - outbuf; + ptrdiff_t shortfall = ccl.produced - (outbufsize - offset); + if (0 < shortfall) { - EMACS_INT offset = outp - outbuf; - outbufsize += ccl.produced; - outbuf = (unsigned char *) xrealloc (outbuf, outbufsize); + outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1); outp = outbuf + offset; } for (j = 0; j < ccl.produced; j++) === modified file 'src/character.c' --- src/character.c 2011-07-12 21:17:39 +0000 +++ src/character.c 2011-08-05 02:15:35 +0000 @@ -326,7 +326,7 @@ disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil; if (VECTORP (disp)) - width = ASIZE (disp); + width = sanitize_char_width (ASIZE (disp)); else width = CHAR_WIDTH (c); @@ -358,7 +358,7 @@ { val = DISP_CHAR_VECTOR (dp, c); if (VECTORP (val)) - thiswidth = ASIZE (val); + thiswidth = sanitize_char_width (ASIZE (val)); else thiswidth = CHAR_WIDTH (c); } @@ -423,7 +423,7 @@ { EMACS_INT chars, bytes, thiswidth; Lisp_Object val; - int cmp_id; + ptrdiff_t cmp_id; EMACS_INT ignore, end; if (find_composition (i, -1, &ignore, &end, &val, string) @@ -451,7 +451,7 @@ { val = DISP_CHAR_VECTOR (dp, c); if (VECTORP (val)) - thiswidth = ASIZE (val); + thiswidth = sanitize_char_width (ASIZE (val)); else thiswidth = CHAR_WIDTH (c); } @@ -902,7 +902,7 @@ Lisp_Object str; USE_SAFE_ALLOCA; - SAFE_ALLOCA (buf, unsigned char *, MAX_MULTIBYTE_LENGTH * n); + SAFE_NALLOCA (buf, MAX_MULTIBYTE_LENGTH, n); p = buf; for (i = 0; i < n; i++) === modified file 'src/character.h' --- src/character.h 2011-07-06 23:28:00 +0000 +++ src/character.h 2011-07-19 00:42:24 +0000 @@ -556,6 +556,16 @@ } while (0) +/* Return a non-outlandish value for the tab width. */ + +#define SANE_TAB_WIDTH(buf) \ + sanitize_tab_width (XFASTINT (BVAR (buf, tab_width))) +static inline int +sanitize_tab_width (EMACS_INT width) +{ + return 0 < width && width <= 1000 ? width : 8; +} + /* Return the width of ASCII character C. The width is measured by how many columns C will occupy on the screen when displayed in the current buffer. */ @@ -563,12 +573,20 @@ #define ASCII_CHAR_WIDTH(c) \ (c < 0x20 \ ? (c == '\t' \ - ? XFASTINT (BVAR (current_buffer, tab_width)) \ + ? SANE_TAB_WIDTH (current_buffer) \ : (c == '\n' ? 0 : (NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2))) \ : (c < 0x7f \ ? 1 \ : ((NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2)))) +/* Return a non-outlandish value for a character width. */ + +static inline int +sanitize_char_width (EMACS_INT width) +{ + return 0 <= width && width <= 1000 ? width : 1000; +} + /* Return the width of character C. The width is measured by how many columns C will occupy on the screen when displayed in the current buffer. */ @@ -576,7 +594,7 @@ #define CHAR_WIDTH(c) \ (ASCII_CHAR_P (c) \ ? ASCII_CHAR_WIDTH (c) \ - : XINT (CHAR_TABLE_REF (Vchar_width_table, c))) + : sanitize_char_width (XINT (CHAR_TABLE_REF (Vchar_width_table, c)))) /* If C is a variation selector, return the index numnber of the variation selector (1..256). Otherwise, return 0. */ === modified file 'src/charset.c' --- src/charset.c 2011-06-14 18:57:19 +0000 +++ src/charset.c 2011-08-05 02:15:35 +0000 @@ -61,7 +61,7 @@ /* Table of struct charset. */ struct charset *charset_table; -static int charset_table_size; +static ptrdiff_t charset_table_size; static int charset_table_used; Lisp_Object Qcharsetp; @@ -419,7 +419,7 @@ paying attention to comment character '#'. */ static inline unsigned -read_hex (FILE *fp, int *eof) +read_hex (FILE *fp, int *eof, int *overflow) { int c; unsigned n; @@ -441,15 +441,16 @@ *eof = 1; return 0; } - *eof = 0; n = 0; - if (c == 'x') - while ((c = getc (fp)) != EOF && isxdigit (c)) + while (isxdigit (c = getc (fp))) + { + if (UINT_MAX >> 4 < n) + *overflow = 1; n = ((n << 4) - | (c <= '9' ? c - '0' : c <= 'F' ? c - 'A' + 10 : c - 'a' + 10)); - else - while ((c = getc (fp)) != EOF && isdigit (c)) - n = (n * 10) + c - '0'; + | (c - ('0' <= c && c <= '9' ? '0' + : 'A' <= c && c <= 'F' ? 'A' - 10 + : 'a' - 10))); + } if (c != EOF) ungetc (c, fp); return n; @@ -479,7 +480,6 @@ unsigned max_code = CHARSET_MAX_CODE (charset); int fd; FILE *fp; - int eof; Lisp_Object suffixes; struct charset_map_entries *head, *entries; int n_entries, count; @@ -504,22 +504,27 @@ memset (entries, 0, sizeof (struct charset_map_entries)); n_entries = 0; - eof = 0; while (1) { - unsigned from, to; - int c; + unsigned from, to, c; int idx; + int eof = 0, overflow = 0; - from = read_hex (fp, &eof); + from = read_hex (fp, &eof, &overflow); if (eof) break; if (getc (fp) == '-') - to = read_hex (fp, &eof); + to = read_hex (fp, &eof, &overflow); else to = from; - c = (int) read_hex (fp, &eof); + if (eof) + break; + c = read_hex (fp, &eof, &overflow); + if (eof) + break; + if (overflow) + continue; if (from < min_code || to > max_code || from > to || c > MAX_CHAR) continue; @@ -1145,13 +1150,25 @@ hash_code); if (charset_table_used == charset_table_size) { - struct charset *new_table - = (struct charset *) xmalloc (sizeof (struct charset) - * (charset_table_size + 16)); - memcpy (new_table, charset_table, - sizeof (struct charset) * charset_table_size); - charset_table_size += 16; + /* Ensure that charset IDs fit into 'int' as well as into the + restriction imposed by fixnums. Although the 'int' restriction + could be removed, too much other code would need altering; for + example, the IDs are stuffed into struct + coding_system.charbuf[i] entries, which are 'int'. */ + int old_size = charset_table_size; + struct charset *new_table = + xpalloc (0, &charset_table_size, 1, + min (INT_MAX, MOST_POSITIVE_FIXNUM), + sizeof *charset_table); + memcpy (new_table, charset_table, old_size * sizeof *new_table); charset_table = new_table; + /* FIXME: Doesn't this leak memory? The old charset_table becomes + unreachable. It could be that this is intentional, because the + old charset table may be in a dumped emacs, and reallocating such + a table may not work. If the memory leak is intentional, a + comment should be added to explain this. If not, the old + charset_table should be freed, by passing it as the 1st argument + to xpalloc and removing the memcpy. */ } id = charset_table_used++; new_definition_p = 1; @@ -2210,14 +2227,16 @@ { Lisp_Object charset; int id; - int priority; + ptrdiff_t priority; }; static int charset_compare (const void *d1, const void *d2) { const struct charset_sort_data *data1 = d1, *data2 = d2; - return (data1->priority - data2->priority); + if (data1->priority != data2->priority) + return data1->priority < data2->priority ? -1 : 1; + return 0; } DEFUN ("sort-charsets", Fsort_charsets, Ssort_charsets, 1, 1, 0, @@ -2227,7 +2246,8 @@ (Lisp_Object charsets) { Lisp_Object len = Flength (charsets); - int n = XFASTINT (len), i, j, done; + ptrdiff_t n = XFASTINT (len), i, j; + int done; Lisp_Object tail, elt, attrs; struct charset_sort_data *sort_data; int id, min_id = INT_MAX, max_id = INT_MIN; @@ -2235,7 +2255,7 @@ if (n == 0) return Qnil; - SAFE_ALLOCA (sort_data, struct charset_sort_data *, sizeof (*sort_data) * n); + SAFE_NALLOCA (sort_data, 1, n); for (tail = charsets, i = 0; CONSP (tail); tail = XCDR (tail), i++) { elt = XCAR (tail); @@ -2310,6 +2330,17 @@ void syms_of_charset (void) { + /* Allocate an initial charset table that is just under 64 KiB in size. + This should be large enough so that the charset table need not be + reallocated during an initial bootstrap. Allocating anything larger than + 64 KiB in an initial run may not work, because glibc malloc might use + mmap for larger allocations, and these don't work well across dumped + systems. */ + enum { + initial_malloc_max = (1 << 16) - 1, + charset_table_size_init = initial_malloc_max / sizeof (struct charset) + }; + DEFSYM (Qcharsetp, "charsetp"); DEFSYM (Qascii, "ascii"); @@ -2342,9 +2373,9 @@ Vcharset_hash_table = Fmake_hash_table (2, args); } - charset_table_size = 128; - charset_table = ((struct charset *) - xmalloc (sizeof (struct charset) * charset_table_size)); + charset_table = (struct charset *) xmalloc (sizeof (struct charset) + * charset_table_size_init); + charset_table_size = charset_table_size_init; charset_table_used = 0; defsubr (&Scharsetp); === modified file 'src/charset.h' --- src/charset.h 2011-06-15 18:57:45 +0000 +++ src/charset.h 2011-07-19 06:07:07 +0000 @@ -148,7 +148,7 @@ int id; /* Index to Vcharset_hash_table. */ - EMACS_INT hash_index; + ptrdiff_t hash_index; /* Dimension of the charset: 1, 2, 3, or 4. */ int dimension; @@ -341,7 +341,7 @@ number of the charset. Otherwise, signal an error. */ #define CHECK_CHARSET_GET_ID(x, id) \ do { \ - int idx; \ + ptrdiff_t idx; \ \ if (! SYMBOLP (x) || (idx = CHARSET_SYMBOL_HASH_INDEX (x)) < 0) \ wrong_type_argument (Qcharsetp, (x)); \ === modified file 'src/cmds.c' --- src/cmds.c 2011-06-24 21:25:22 +0000 +++ src/cmds.c 2011-08-05 02:15:35 +0000 @@ -471,7 +471,7 @@ { USE_SAFE_ALLOCA; char *strn, *p; - SAFE_ALLOCA (strn, char *, n * len); + SAFE_NALLOCA (strn, len, n); for (p = strn; n > 0; n--, p += len) memcpy (p, str, len); insert_and_inherit (strn, p - strn); === modified file 'src/coding.c' --- src/coding.c 2011-07-01 11:03:55 +0000 +++ src/coding.c 2011-07-28 20:31:29 +0000 @@ -5838,7 +5838,7 @@ Lisp_Object coding_system_charset_list (Lisp_Object coding_system) { - int id; + ptrdiff_t id; Lisp_Object attrs, charset_list; CHECK_CODING_SYSTEM_GET_ID (coding_system, id); @@ -6683,8 +6683,12 @@ break; } - if (dst + MAX_MULTIBYTE_LENGTH * to_nchars > dst_end) + if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars) { + if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf)) + / MAX_MULTIBYTE_LENGTH) + < to_nchars) + memory_full (SIZE_MAX); dst = alloc_destination (coding, buf_end - buf + MAX_MULTIBYTE_LENGTH * to_nchars, @@ -7888,11 +7892,10 @@ } else if (EQ (dst_object, Qt)) { + ptrdiff_t dst_bytes = max (1, coding->src_chars); coding->dst_object = Qnil; - coding->dst_bytes = coding->src_chars; - if (coding->dst_bytes == 0) - coding->dst_bytes = 1; - coding->destination = (unsigned char *) xmalloc (coding->dst_bytes); + coding->destination = (unsigned char *) xmalloc (dst_bytes); + coding->dst_bytes = dst_bytes; coding->dst_multibyte = 0; } else @@ -8076,7 +8079,7 @@ Lisp_Object attrs, eol_type; Lisp_Object val = Qnil; struct coding_system coding; - int id; + ptrdiff_t id; struct coding_detection_info detect_info; enum coding_category base_category; int null_byte_found = 0, eight_bit_found = 0; === modified file 'src/coding.h' --- src/coding.h 2011-04-11 06:58:57 +0000 +++ src/coding.h 2011-07-19 06:07:07 +0000 @@ -415,7 +415,7 @@ setup_coding_system. At the early stage of building time, this value is -1 in the array coding_categories to indicate that no coding-system of that category is yet defined. */ - int id; + ptrdiff_t id; /* Flag bits of the coding system. The meaning of each bit is common to all types of coding systems. */ === modified file 'src/composite.c' --- src/composite.c 2011-07-09 06:28:40 +0000 +++ src/composite.c 2011-08-05 02:15:35 +0000 @@ -142,10 +142,10 @@ struct composition **composition_table; /* The current size of `composition_table'. */ -static int composition_table_size; +static ptrdiff_t composition_table_size; /* Number of compositions currently made. */ -int n_compositions; +ptrdiff_t n_compositions; /* Hash table for compositions. The key is COMPONENTS-VEC of `composition' property. The value is the corresponding @@ -172,19 +172,30 @@ If the composition is invalid, return -1. */ -int +ptrdiff_t get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars, Lisp_Object prop, Lisp_Object string) { Lisp_Object id, length, components, key, *key_contents; - int glyph_len; + ptrdiff_t glyph_len; struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); - EMACS_INT hash_index; + ptrdiff_t hash_index; EMACS_UINT hash_code; + enum composition_method method; struct composition *cmp; EMACS_INT i; int ch; + /* Maximum length of a string of glyphs. XftGlyphExtents limits + this to INT_MAX, and Emacs limits it further. Divide INT_MAX - 1 + by 2 because x_produce_glyphs computes glyph_len * 2 + 1. Divide + the size by MAX_MULTIBYTE_LENGTH because encode_terminal_code + multiplies glyph_len by MAX_MULTIBYTE_LENGTH. */ + enum { + GLYPH_LEN_MAX = min ((INT_MAX - 1) / 2, + min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH) + }; + /* PROP should be Form-A: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC) or @@ -258,21 +269,9 @@ /* This composition is a new one. We must register it. */ /* Check if we have sufficient memory to store this information. */ - if (composition_table_size == 0) - { - composition_table_size = 256; - composition_table - = (struct composition **) xmalloc (sizeof (composition_table[0]) - * composition_table_size); - } - else if (composition_table_size <= n_compositions) - { - composition_table_size += 256; - composition_table - = (struct composition **) xrealloc (composition_table, - sizeof (composition_table[0]) - * composition_table_size); - } + if (composition_table_size <= n_compositions) + composition_table = xpalloc (composition_table, &composition_table_size, + 1, -1, sizeof *composition_table); key_contents = XVECTOR (key)->contents; @@ -316,20 +315,26 @@ /* Register the composition in composition_hash_table. */ hash_index = hash_put (hash_table, key, id, hash_code); + method = (NILP (components) + ? COMPOSITION_RELATIVE + : ((INTEGERP (components) || STRINGP (components)) + ? COMPOSITION_WITH_ALTCHARS + : COMPOSITION_WITH_RULE_ALTCHARS)); + + glyph_len = (method == COMPOSITION_WITH_RULE_ALTCHARS + ? (ASIZE (key) + 1) / 2 + : ASIZE (key)); + + if (GLYPH_LEN_MAX < glyph_len) + memory_full (SIZE_MAX); + /* Register the composition in composition_table. */ cmp = (struct composition *) xmalloc (sizeof (struct composition)); - cmp->method = (NILP (components) - ? COMPOSITION_RELATIVE - : ((INTEGERP (components) || STRINGP (components)) - ? COMPOSITION_WITH_ALTCHARS - : COMPOSITION_WITH_RULE_ALTCHARS)); + cmp->method = method; cmp->hash_index = hash_index; - glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS - ? (ASIZE (key) + 1) / 2 - : ASIZE (key)); cmp->glyph_len = glyph_len; - cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2); + cmp->offsets = xnmalloc (glyph_len, 2 * sizeof *cmp->offsets); cmp->font = NULL; if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) @@ -656,7 +661,7 @@ gstring_lookup_cache (Lisp_Object header) { struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); - EMACS_INT i = hash_lookup (h, header, NULL); + ptrdiff_t i = hash_lookup (h, header, NULL); return (i >= 0 ? HASH_VALUE (h, i) : Qnil); } @@ -691,7 +696,7 @@ } Lisp_Object -composition_gstring_from_id (int id) +composition_gstring_from_id (ptrdiff_t id) { struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); === modified file 'src/composite.h' --- src/composite.h 2011-06-12 23:25:12 +0000 +++ src/composite.h 2011-08-05 02:15:35 +0000 @@ -170,7 +170,7 @@ struct composition { /* Number of glyphs of the composition components. */ - unsigned glyph_len; + int glyph_len; /* Width, ascent, and descent pixels of the composition. */ short pixel_width, ascent, descent; @@ -193,7 +193,7 @@ void *font; /* Pointer to an array of x-offset and y-offset (by pixels) of - glyphs. This points to a sufficient memory space (sizeof (int) * + glyphs. This points to a sufficient memory space (sizeof (short) * glyph_len * 2) that is allocated when the composition is registered in composition_table. X-offset and Y-offset of Nth glyph are (2N)th and (2N+1)th elements respectively. */ @@ -204,7 +204,7 @@ COMPOSITION-ID. */ extern struct composition **composition_table; /* Number of the currently registered compositions. */ -extern int n_compositions; +extern ptrdiff_t n_compositions; /* Mask bits for CHECK_MASK arg to update_compositions. For a change in the region FROM and TO, check compositions ... */ @@ -216,8 +216,8 @@ extern Lisp_Object Qcomposition; extern Lisp_Object composition_hash_table; -extern int get_composition_id (EMACS_INT, EMACS_INT, EMACS_INT, - Lisp_Object, Lisp_Object); +extern ptrdiff_t get_composition_id (EMACS_INT, EMACS_INT, EMACS_INT, + Lisp_Object, Lisp_Object); extern int find_composition (EMACS_INT, EMACS_INT, EMACS_INT *, EMACS_INT *, Lisp_Object *, Lisp_Object); extern void update_compositions (EMACS_INT, EMACS_INT, int); @@ -299,7 +299,7 @@ struct font_metrics; extern Lisp_Object composition_gstring_put_cache (Lisp_Object, EMACS_INT); -extern Lisp_Object composition_gstring_from_id (int); +extern Lisp_Object composition_gstring_from_id (ptrdiff_t); extern int composition_gstring_p (Lisp_Object); extern int composition_gstring_width (Lisp_Object, EMACS_INT, EMACS_INT, struct font_metrics *); === modified file 'src/dispextern.h' --- src/dispextern.h 2011-08-02 19:16:32 +0000 +++ src/dispextern.h 2011-08-05 02:19:34 +0000 @@ -575,7 +575,7 @@ struct glyph *glyphs; /* Allocated size of `glyphs'. */ - int nglyphs; + ptrdiff_t nglyphs; /* Number of rows and columns in a matrix. */ int nrows, ncolumns; @@ -625,7 +625,7 @@ struct glyph_row *rows; /* Number of elements allocated for the vector rows above. */ - int rows_allocated; + ptrdiff_t rows_allocated; /* The number of rows used by the window if all lines were displayed with the smallest possible character height. */ @@ -1240,7 +1240,7 @@ struct composition *cmp; /* If not negative, this string describes a compos. */ - int cmp_id; + ptrdiff_t cmp_id; /* Start and end glyph indices in a glyph-string. */ int cmp_from, cmp_to; @@ -1708,7 +1708,8 @@ struct face **faces_by_id; /* The allocated size, and number of used slots of faces_by_id. */ - int size, used; + ptrdiff_t size; + int used; /* Flag indicating that attributes of the `menu' face have been changed. */ @@ -2058,7 +2059,7 @@ EMACS_INT stop_pos; /* ID number of the composition or glyph-string. If negative, we are not iterating over a composition now. */ - int id; + ptrdiff_t id; /* If non-negative, character that triggers the automatic composition at `stop_pos', and this is an automatic composition. If negative, this is a static composition. This is set to -2 @@ -2248,7 +2249,7 @@ struct { Lisp_Object object; struct it_slice slice; - int image_id; + ptrdiff_t image_id; } image; /* method == GET_FROM_COMPOSITION */ struct { @@ -2378,7 +2379,7 @@ enum glyphless_display_method glyphless_method; /* If what == IT_IMAGE, the id of the image to display. */ - int image_id; + ptrdiff_t image_id; /* Values from `slice' property. */ struct it_slice slice; @@ -2828,7 +2829,7 @@ EMACS_UINT hash; /* Image id of this image. */ - int id; + ptrdiff_t id; /* Hash collision chain. */ struct image *next, *prev; @@ -2847,13 +2848,13 @@ struct image **images; /* Allocated size of `images'. */ - unsigned size; + ptrdiff_t size; /* Number of images in the cache. */ - unsigned used; + ptrdiff_t used; /* Reference count (number of frames sharing this cache). */ - int refcount; + ptrdiff_t refcount; }; @@ -3120,7 +3121,7 @@ extern int x_bitmap_height (struct frame *, ptrdiff_t); extern int x_bitmap_width (struct frame *, ptrdiff_t); extern int x_bitmap_pixmap (struct frame *, ptrdiff_t); -extern void x_reference_bitmap (struct frame *, int); +extern void x_reference_bitmap (struct frame *, ptrdiff_t); extern ptrdiff_t x_create_bitmap_from_data (struct frame *, char *, unsigned int, unsigned int); extern ptrdiff_t x_create_bitmap_from_file (struct frame *, Lisp_Object); @@ -3141,7 +3142,7 @@ void mark_image_cache (struct image_cache *); int valid_image_p (Lisp_Object); void prepare_image_for_display (struct frame *, struct image *); -int lookup_image (struct frame *, Lisp_Object); +ptrdiff_t lookup_image (struct frame *, Lisp_Object); unsigned long image_background (struct image *, struct frame *, XImagePtr_or_DC ximg); === modified file 'src/dispnew.c' --- src/dispnew.c 2011-07-14 20:40:35 +0000 +++ src/dispnew.c 2011-08-05 02:15:35 +0000 @@ -499,12 +499,12 @@ /* Enlarge MATRIX->rows if necessary. New rows are cleared. */ if (matrix->rows_allocated < dim.height) { - ptrdiff_t size = dim.height * sizeof (struct glyph_row); + int old_alloc = matrix->rows_allocated; new_rows = dim.height - matrix->rows_allocated; - matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size); - memset (matrix->rows + matrix->rows_allocated, 0, - new_rows * sizeof *matrix->rows); - matrix->rows_allocated = dim.height; + matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated, + new_rows, INT_MAX, sizeof *matrix->rows); + memset (matrix->rows + old_alloc, 0, + (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows); } else new_rows = 0; @@ -576,9 +576,8 @@ while (row < end) { row->glyphs[LEFT_MARGIN_AREA] - = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA], - (dim.width - * sizeof (struct glyph))); + = xnrealloc (row->glyphs[LEFT_MARGIN_AREA], + dim.width, sizeof (struct glyph)); /* The mode line never has marginal areas. */ if (row == matrix->rows + dim.height - 1 @@ -1217,7 +1216,7 @@ struct glyph *end = beg + row->used[TEXT_AREA]; int len; Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE; - int glyph_table_len = GLYPH_TABLE_LENGTH; + ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH; /* Ignore trailing and leading spaces if we can. */ if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */ @@ -1391,7 +1390,7 @@ static int realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim) { - int needed; + ptrdiff_t needed; int changed_p; changed_p = (pool->glyphs == 0 @@ -1399,24 +1398,17 @@ || matrix_dim.width != pool->ncolumns); /* Enlarge the glyph pool. */ - needed = matrix_dim.width * matrix_dim.height; + needed = matrix_dim.width; + if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height)) + memory_full (SIZE_MAX); + needed *= matrix_dim.height; if (needed > pool->nglyphs) { - ptrdiff_t size = needed * sizeof (struct glyph); - - if (pool->glyphs) - { - pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size); - memset (pool->glyphs + pool->nglyphs, 0, - size - pool->nglyphs * sizeof (struct glyph)); - } - else - { - pool->glyphs = (struct glyph *) xmalloc (size); - memset (pool->glyphs, 0, size); - } - - pool->nglyphs = needed; + ptrdiff_t old_nglyphs = pool->nglyphs; + pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs, + needed - old_nglyphs, -1, sizeof *pool->glyphs); + memset (pool->glyphs + old_nglyphs, 0, + (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs); } /* Remember the number of rows and columns because (a) we use them @@ -4166,7 +4158,7 @@ int new_line_number; /* Bucket index of this row_entry in the hash table row_table. */ - int bucket; + ptrdiff_t bucket; /* The row described by this entry. */ struct glyph_row *row; @@ -4180,29 +4172,29 @@ that we need a larger one. */ static struct row_entry *row_entry_pool; -static int row_entry_pool_size; +static ptrdiff_t row_entry_pool_size; /* Index of next free entry in row_entry_pool. */ -static int row_entry_idx; +static ptrdiff_t row_entry_idx; /* The hash table used during scrolling, and the table's size. This table is used to quickly identify equal rows in the desired and current matrix. */ static struct row_entry **row_table; -static int row_table_size; +static ptrdiff_t row_table_size; /* Vectors of pointers to row_entry structures belonging to the current and desired matrix, and the size of the vectors. */ static struct row_entry **old_lines, **new_lines; -static int old_lines_size, new_lines_size; +static ptrdiff_t old_lines_size, new_lines_size; /* A pool to allocate run structures from, and its size. */ static struct run *run_pool; -static int runs_size; +static ptrdiff_t runs_size; /* A vector of runs of lines found during scrolling. */ @@ -4214,7 +4206,7 @@ add_row_entry (struct glyph_row *row) { struct row_entry *entry; - int i = row->hash % row_table_size; + ptrdiff_t i = row->hash % row_table_size; entry = row_table[i]; while (entry && !row_equal_p (entry->row, row, 1)) @@ -4267,9 +4259,10 @@ struct glyph_matrix *desired_matrix = w->desired_matrix; struct glyph_matrix *current_matrix = w->current_matrix; int yb = window_text_bottom_y (w); - int i, j, first_old, first_new, last_old, last_new; - int nruns, n, run_idx; - ptrdiff_t nbytes; + ptrdiff_t i; + int j, first_old, first_new, last_old, last_new; + int nruns, run_idx; + ptrdiff_t n; struct row_entry *entry; struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); @@ -4354,45 +4347,59 @@ if (last_new == first_new) return 0; + /* Check for integer overflow in size calculation. + + If next_almost_prime checks (N) for divisibility by 2..10, then + it can return at most N + 10, e.g., next_almost_prime (1) == 11. + So, set next_almost_prime_increment_max to 10. + + It's just a coincidence that next_almost_prime_increment_max == + NEXT_ALMOST_PRIME_LIMIT - 1. If NEXT_ALMOST_PRIME_LIMIT were + 13, then next_almost_prime_increment_max would be 14, e.g., + because next_almost_prime (113) would be 127. */ + { + verify (NEXT_ALMOST_PRIME_LIMIT == 11); + enum { next_almost_prime_increment_max = 10 }; + ptrdiff_t row_table_max = + (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table) + - next_almost_prime_increment_max); + ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows; + if (current_nrows_max < current_matrix->nrows) + memory_full (SIZE_MAX); + } + /* Reallocate vectors, tables etc. if necessary. */ if (current_matrix->nrows > old_lines_size) - { - old_lines_size = current_matrix->nrows; - nbytes = old_lines_size * sizeof *old_lines; - old_lines = (struct row_entry **) xrealloc (old_lines, nbytes); - } + old_lines = xpalloc (old_lines, &old_lines_size, + current_matrix->nrows - old_lines_size, + INT_MAX, sizeof *old_lines); if (desired_matrix->nrows > new_lines_size) - { - new_lines_size = desired_matrix->nrows; - nbytes = new_lines_size * sizeof *new_lines; - new_lines = (struct row_entry **) xrealloc (new_lines, nbytes); - } + new_lines = xpalloc (new_lines, &new_lines_size, + desired_matrix->nrows - new_lines_size, + INT_MAX, sizeof *new_lines); - n = desired_matrix->nrows + current_matrix->nrows; - if (3 * n > row_table_size) + n = desired_matrix->nrows; + n += current_matrix->nrows; + if (row_table_size < 3 * n) { - row_table_size = next_almost_prime (3 * n); - nbytes = row_table_size * sizeof *row_table; - row_table = (struct row_entry **) xrealloc (row_table, nbytes); - memset (row_table, 0, nbytes); + ptrdiff_t size = next_almost_prime (3 * n); + row_table = xnrealloc (row_table, size, sizeof *row_table); + row_table_size = size; + memset (row_table, 0, size * sizeof *row_table); } if (n > row_entry_pool_size) - { - row_entry_pool_size = n; - nbytes = row_entry_pool_size * sizeof *row_entry_pool; - row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes); - } + row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size, + n - row_entry_pool_size, + -1, sizeof *row_entry_pool); if (desired_matrix->nrows > runs_size) { + runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs); + run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool); runs_size = desired_matrix->nrows; - nbytes = runs_size * sizeof *runs; - runs = (struct run **) xrealloc (runs, nbytes); - nbytes = runs_size * sizeof *run_pool; - run_pool = (struct run *) xrealloc (run_pool, nbytes); } nruns = run_idx = 0; === modified file 'src/doc.c' --- src/doc.c 2011-07-15 15:31:36 +0000 +++ src/doc.c 2011-08-05 02:15:35 +0000 @@ -39,7 +39,7 @@ extern Lisp_Object Qclosure; /* Buffer used for reading from documentation file. */ static char *get_doc_string_buffer; -static int get_doc_string_buffer_size; +static ptrdiff_t get_doc_string_buffer_size; static unsigned char *read_bytecode_pointer; static Lisp_Object Fdocumentation_property (Lisp_Object, Lisp_Object, @@ -166,18 +166,17 @@ p = get_doc_string_buffer; while (1) { - EMACS_INT space_left = (get_doc_string_buffer_size + ptrdiff_t space_left = (get_doc_string_buffer_size - (p - get_doc_string_buffer)); int nread; /* Allocate or grow the buffer if we need to. */ if (space_left == 0) { - EMACS_INT in_buffer = p - get_doc_string_buffer; - get_doc_string_buffer_size += 16 * 1024; - get_doc_string_buffer - = (char *) xrealloc (get_doc_string_buffer, - get_doc_string_buffer_size + 1); + ptrdiff_t in_buffer = p - get_doc_string_buffer; + get_doc_string_buffer = + xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size, + 16 * 1024, -1, 1); p = get_doc_string_buffer + in_buffer; space_left = (get_doc_string_buffer_size - (p - get_doc_string_buffer)); @@ -713,16 +712,16 @@ int changed = 0; register unsigned char *strp; register char *bufp; - EMACS_INT idx; - EMACS_INT bsize; + ptrdiff_t idx; + ptrdiff_t bsize; Lisp_Object tem; Lisp_Object keymap; unsigned char *start; - EMACS_INT length, length_byte; + ptrdiff_t length, length_byte; Lisp_Object name; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; int multibyte; - EMACS_INT nchars; + ptrdiff_t nchars; if (NILP (string)) return Qnil; @@ -774,7 +773,7 @@ } else if (strp[0] == '\\' && strp[1] == '[') { - EMACS_INT start_idx; + ptrdiff_t start_idx; int follow_remap = 1; changed = 1; @@ -813,7 +812,9 @@ if (NILP (tem)) /* but not on any keys */ { - EMACS_INT offset = bufp - buf; + ptrdiff_t offset = bufp - buf; + if (STRING_BYTES_BOUND - 4 < bsize) + string_overflow (); buf = (char *) xrealloc (buf, bsize += 4); bufp = buf + offset; memcpy (bufp, "M-x ", 4); @@ -836,7 +837,7 @@ else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<')) { struct buffer *oldbuf; - EMACS_INT start_idx; + ptrdiff_t start_idx; /* This is for computing the SHADOWS arg for describe_map_tree. */ Lisp_Object active_maps = Fcurrent_active_maps (Qnil, Qnil); Lisp_Object earlier_maps; @@ -907,7 +908,9 @@ length_byte = SBYTES (tem); subst: { - EMACS_INT offset = bufp - buf; + ptrdiff_t offset = bufp - buf; + if (STRING_BYTES_BOUND - length_byte < bsize) + string_overflow (); buf = (char *) xrealloc (buf, bsize += length_byte); bufp = buf + offset; memcpy (bufp, start, length_byte); === modified file 'src/editfns.c' --- src/editfns.c 2011-07-28 00:15:43 +0000 +++ src/editfns.c 2011-07-29 05:31:12 +0000 @@ -2100,7 +2100,7 @@ void set_time_zone_rule (const char *tzstring) { - int envptrs; + ptrdiff_t envptrs; char **from, **to, **newenv; /* Make the ENVIRON vector longer with room for TZSTRING. */ @@ -3350,7 +3350,7 @@ static char *message_text; /* Allocated length of that buffer. */ -static int message_length; +static ptrdiff_t message_length; DEFUN ("message", Fmessage, Smessage, 1, MANY, 0, doc: /* Display a message at the bottom of the screen. @@ -3432,8 +3432,8 @@ } if (SBYTES (val) > message_length) { + message_text = (char *) xrealloc (message_text, SBYTES (val)); message_length = SBYTES (val); - message_text = (char *)xrealloc (message_text, message_length); } memcpy (message_text, SDATA (val), SBYTES (val)); message2 (message_text, SBYTES (val), @@ -4158,7 +4158,7 @@ character. CONVBYTES says how much room is needed. Allocate enough room (and then some) and do it again. */ { - EMACS_INT used = p - buf; + ptrdiff_t used = p - buf; if (max_bufsize - used < convbytes) string_overflow (); === modified file 'src/emacs.c' --- src/emacs.c 2011-08-04 17:04:39 +0000 +++ src/emacs.c 2011-08-05 02:19:34 +0000 @@ -1358,24 +1358,17 @@ /* If we have the form --display=NAME, convert it into -d name. This requires inserting a new element into argv. */ - if (displayname != 0 && skip_args - count_before == 1) + if (displayname && count_before < skip_args) { - char **new = (char **) xmalloc (sizeof (char *) * (argc + 2)); - int j; - - for (j = 0; j < count_before + 1; j++) - new[j] = argv[j]; - new[count_before + 1] = (char *) "-d"; - new[count_before + 2] = displayname; - for (j = count_before + 2; j <argc; j++) - new[j + 1] = argv[j]; - argv = new; - argc++; + if (skip_args == count_before + 1) + { + memmove (argv + count_before + 3, argv + count_before + 2, + (argc - (count_before + 2)) * sizeof *argv); + argv[count_before + 2] = displayname; + argc++; + } + argv[count_before + 1] = (char *) "-d"; } - /* Change --display to -d, when its arg is separate. */ - else if (displayname != 0 && skip_args > count_before - && argv[count_before + 1][1] == '-') - argv[count_before + 1] = (char *) "-d"; if (! no_site_lisp) { @@ -1838,8 +1831,8 @@ 0 for an option that takes no arguments, 1 for an option that takes one argument, etc. -1 for an ordinary non-option argument. */ - int *options = (int *) xmalloc (sizeof (int) * argc); - int *priority = (int *) xmalloc (sizeof (int) * argc); + int *options = xnmalloc (argc, sizeof *options); + int *priority = xnmalloc (argc, sizeof *priority); int to = 1; int incoming_used = 1; int from; === modified file 'src/eval.c' --- src/eval.c 2011-07-07 02:14:52 +0000 +++ src/eval.c 2011-08-05 02:15:35 +0000 @@ -133,8 +133,9 @@ void init_eval_once (void) { - specpdl_size = 50; - specpdl = (struct specbinding *) xmalloc (specpdl_size * sizeof (struct specbinding)); + enum { size = 50 }; + specpdl = (struct specbinding *) xmalloc (size * sizeof (struct specbinding)); + specpdl_size = size; specpdl_ptr = specpdl; /* Don't forget to update docs (lispref node "Local Variables"). */ max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */ @@ -192,7 +193,7 @@ if (lisp_eval_depth + 40 > max_lisp_eval_depth) max_lisp_eval_depth = lisp_eval_depth + 40; - if (SPECPDL_INDEX () + 100 > max_specpdl_size) + if (max_specpdl_size - 100 < SPECPDL_INDEX ()) max_specpdl_size = SPECPDL_INDEX () + 100; #ifdef HAVE_WINDOW_SYSTEM @@ -3274,17 +3275,21 @@ grow_specpdl (void) { register int count = SPECPDL_INDEX (); - if (specpdl_size >= max_specpdl_size) + int max_size = + min (max_specpdl_size, + min (max (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct specbinding), + INT_MAX)); + int size; + if (max_size <= specpdl_size) { if (max_specpdl_size < 400) - max_specpdl_size = 400; - if (specpdl_size >= max_specpdl_size) + max_size = max_specpdl_size = 400; + if (max_size <= specpdl_size) signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil); } - specpdl_size *= 2; - if (specpdl_size > max_specpdl_size) - specpdl_size = max_specpdl_size; - specpdl = (struct specbinding *) xrealloc (specpdl, specpdl_size * sizeof (struct specbinding)); + size = specpdl_size < max_size / 2 ? 2 * specpdl_size : max_size; + specpdl = xnrealloc (specpdl, size, sizeof *specpdl); + specpdl_size = size; specpdl_ptr = specpdl + count; } === modified file 'src/fileio.c' --- src/fileio.c 2011-07-19 20:33:28 +0000 +++ src/fileio.c 2011-07-19 20:37:27 +0000 @@ -2912,7 +2912,7 @@ encoded_absname = ENCODE_FILE (absname); - if (chmod (SSDATA (encoded_absname), XINT (mode)) < 0) + if (chmod (SSDATA (encoded_absname), XINT (mode) & 07777) < 0) report_file_error ("Doing chmod", Fcons (absname, Qnil)); return Qnil; @@ -5114,11 +5114,11 @@ { if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0) /* But make sure we can overwrite it later! */ - auto_save_mode_bits = st.st_mode | 0600; + auto_save_mode_bits = (st.st_mode | 0600) & 0777; else if ((modes = Ffile_modes (BVAR (current_buffer, filename)), INTEGERP (modes))) /* Remote files don't cooperate with stat. */ - auto_save_mode_bits = XINT (modes) | 0600; + auto_save_mode_bits = (XINT (modes) | 0600) & 0777; } return === modified file 'src/fns.c' --- src/fns.c 2011-07-08 00:51:25 +0000 +++ src/fns.c 2011-08-05 02:15:35 +0000 @@ -602,7 +602,7 @@ prev = Qnil; if (STRINGP (val)) - SAFE_ALLOCA (textprops, struct textprop_rec *, sizeof (struct textprop_rec) * nargs); + SAFE_NALLOCA (textprops, 1, nargs); for (argnum = 0; argnum < nargs; argnum++) { @@ -3395,11 +3395,13 @@ /* Value is the next integer I >= N, N >= 0 which is "almost" a prime - number. */ + number. A number is "almost" a prime number if it is not divisible + by any integer in the range 2 .. (NEXT_ALMOST_PRIME_LIMIT - 1). */ EMACS_INT next_almost_prime (EMACS_INT n) { + verify (NEXT_ALMOST_PRIME_LIMIT == 11); for (n |= 1; ; n += 2) if (n % 3 != 0 && n % 5 != 0 && n % 7 != 0) return n; @@ -3787,11 +3789,11 @@ the hash code of KEY. Value is the index of the entry in H matching KEY, or -1 if not found. */ -EMACS_INT +ptrdiff_t hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash) { EMACS_UINT hash_code; - EMACS_INT start_of_bucket; + ptrdiff_t start_of_bucket; Lisp_Object idx; hash_code = h->hashfn (h, key); @@ -3821,11 +3823,11 @@ HASH is a previously computed hash code of KEY. Value is the index of the entry in H matching KEY. */ -EMACS_INT +ptrdiff_t hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value, EMACS_UINT hash) { - EMACS_INT start_of_bucket, i; + ptrdiff_t start_of_bucket, i; xassert ((hash & ~INTMASK) == 0); @@ -4482,7 +4484,7 @@ (Lisp_Object key, Lisp_Object table, Lisp_Object dflt) { struct Lisp_Hash_Table *h = check_hash_table (table); - EMACS_INT i = hash_lookup (h, key, NULL); + ptrdiff_t i = hash_lookup (h, key, NULL); return i >= 0 ? HASH_VALUE (h, i) : dflt; } @@ -4494,7 +4496,7 @@ (Lisp_Object key, Lisp_Object value, Lisp_Object table) { struct Lisp_Hash_Table *h = check_hash_table (table); - EMACS_INT i; + ptrdiff_t i; EMACS_UINT hash; i = hash_lookup (h, key, &hash); === modified file 'src/frame.c' --- src/frame.c 2011-07-22 05:02:24 +0000 +++ src/frame.c 2011-07-29 05:31:12 +0000 @@ -160,7 +160,7 @@ if (FRAME_MINIBUF_ONLY_P (f)) return; - if (INTEGERP (value)) + if (TYPE_RANGED_INTEGERP (int, value)) nlines = XINT (value); else nlines = 0; @@ -2992,7 +2992,7 @@ f->size_hint_flags &= ~ (XNegative | YNegative); if (EQ (left, Qminus)) f->size_hint_flags |= XNegative; - else if (INTEGERP (left)) + else if (TYPE_RANGED_INTEGERP (int, left)) { leftpos = XINT (left); if (leftpos < 0) @@ -3000,21 +3000,21 @@ } else if (CONSP (left) && EQ (XCAR (left), Qminus) && CONSP (XCDR (left)) - && INTEGERP (XCAR (XCDR (left)))) + && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX)) { leftpos = - XINT (XCAR (XCDR (left))); f->size_hint_flags |= XNegative; } else if (CONSP (left) && EQ (XCAR (left), Qplus) && CONSP (XCDR (left)) - && INTEGERP (XCAR (XCDR (left)))) + && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left)))) { leftpos = XINT (XCAR (XCDR (left))); } if (EQ (top, Qminus)) f->size_hint_flags |= YNegative; - else if (INTEGERP (top)) + else if (TYPE_RANGED_INTEGERP (int, top)) { toppos = XINT (top); if (toppos < 0) @@ -3022,14 +3022,14 @@ } else if (CONSP (top) && EQ (XCAR (top), Qminus) && CONSP (XCDR (top)) - && INTEGERP (XCAR (XCDR (top)))) + && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX)) { toppos = - XINT (XCAR (XCDR (top))); f->size_hint_flags |= YNegative; } else if (CONSP (top) && EQ (XCAR (top), Qplus) && CONSP (XCDR (top)) - && INTEGERP (XCAR (XCDR (top)))) + && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top)))) { toppos = XINT (XCAR (XCDR (top))); } @@ -3481,7 +3481,7 @@ x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); do_pending_window_change (0); } - else if (INTEGERP (arg) && XINT (arg) > 0 + else if (RANGED_INTEGERP (1, arg, INT_MAX) && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) { if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM) @@ -3520,7 +3520,7 @@ { double alpha = 1.0; double newval[2]; - int i, ialpha; + int i; Lisp_Object item; for (i = 0; i < 2; i++) @@ -3544,7 +3544,7 @@ } else if (INTEGERP (item)) { - ialpha = XINT (item); + EMACS_INT ialpha = XINT (item); if (ialpha < 0 || 100 < ialpha) args_out_of_range (make_number (0), make_number (100)); else @@ -4031,11 +4031,15 @@ if (!EQ (tem0, Qunbound)) { CHECK_NUMBER (tem0); + if (! (0 <= XINT (tem0) && XINT (tem0) <= INT_MAX)) + xsignal1 (Qargs_out_of_range, tem0); FRAME_LINES (f) = XINT (tem0); } if (!EQ (tem1, Qunbound)) { CHECK_NUMBER (tem1); + if (! (0 <= XINT (tem1) && XINT (tem1) <= INT_MAX)) + xsignal1 (Qargs_out_of_range, tem1); SET_FRAME_COLS (f, XINT (tem1)); } if (!NILP (tem2) && !EQ (tem2, Qunbound)) @@ -4066,12 +4070,10 @@ ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF); - if (INTEGERP (Vtool_bar_button_margin) - && XINT (Vtool_bar_button_margin) > 0) + if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX)) margin = XFASTINT (Vtool_bar_button_margin); else if (CONSP (Vtool_bar_button_margin) - && INTEGERP (XCDR (Vtool_bar_button_margin)) - && XINT (XCDR (Vtool_bar_button_margin)) > 0) + && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin), INT_MAX)) margin = XFASTINT (XCDR (Vtool_bar_button_margin)); else margin = 0; @@ -4097,14 +4099,14 @@ } else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus) && CONSP (XCDR (tem0)) - && INTEGERP (XCAR (XCDR (tem0)))) + && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem0)), INT_MAX)) { f->top_pos = - XINT (XCAR (XCDR (tem0))); window_prompting |= YNegative; } else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus) && CONSP (XCDR (tem0)) - && INTEGERP (XCAR (XCDR (tem0)))) + && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem0)))) { f->top_pos = XINT (XCAR (XCDR (tem0))); } @@ -4125,14 +4127,14 @@ } else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus) && CONSP (XCDR (tem1)) - && INTEGERP (XCAR (XCDR (tem1)))) + && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem1)), INT_MAX)) { f->left_pos = - XINT (XCAR (XCDR (tem1))); window_prompting |= XNegative; } else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus) && CONSP (XCDR (tem1)) - && INTEGERP (XCAR (XCDR (tem1)))) + && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem1)))) { f->left_pos = XINT (XCAR (XCDR (tem1))); } === modified file 'src/frame.h' --- src/frame.h 2011-06-11 21:31:32 +0000 +++ src/frame.h 2011-07-28 21:51:29 +0000 @@ -258,11 +258,11 @@ /* Size of this frame, excluding fringes, scroll bars etc., in units of canonical characters. */ - EMACS_INT text_lines, text_cols; + int text_lines, text_cols; /* Total size of this frame (i.e. its native window), in units of canonical characters. */ - EMACS_INT total_lines, total_cols; + int total_lines, total_cols; /* New text height and width for pending size change. 0 if no change pending. */ === modified file 'src/fringe.c' --- src/fringe.c 2011-06-24 21:25:22 +0000 +++ src/fringe.c 2011-07-28 23:47:01 +0000 @@ -1610,22 +1610,25 @@ if (n == max_fringe_bitmaps) { - if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS) + int bitmaps = max_fringe_bitmaps + 20; + if (MAX_FRINGE_BITMAPS < bitmaps) error ("No free fringe bitmap slots"); i = max_fringe_bitmaps; - max_fringe_bitmaps += 20; fringe_bitmaps = ((struct fringe_bitmap **) - xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *))); + xrealloc (fringe_bitmaps, bitmaps * sizeof *fringe_bitmaps)); fringe_faces - = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object)); + = (Lisp_Object *) xrealloc (fringe_faces, + bitmaps * sizeof *fringe_faces); - for (; i < max_fringe_bitmaps; i++) + for (i = max_fringe_bitmaps; i < bitmaps; i++) { fringe_bitmaps[i] = NULL; fringe_faces[i] = Qnil; } + + max_fringe_bitmaps = bitmaps; } } === modified file 'src/ftfont.c' --- src/ftfont.c 2011-06-18 18:09:17 +0000 +++ src/ftfont.c 2011-08-05 02:15:35 +0000 @@ -682,7 +682,10 @@ if (NILP (val)) continue; len = Flength (val); - spec->features[i] = malloc (sizeof (int) * XINT (len)); + spec->features[i] = + (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len) + ? 0 + : malloc (sizeof (int) * XINT (len))); if (! spec->features[i]) { if (i > 0 && spec->features[0]) @@ -1761,15 +1764,10 @@ static void setup_otf_gstring (int size) { - if (otf_gstring.size == 0) - { - otf_gstring.glyphs = (OTF_Glyph *) xmalloc (sizeof (OTF_Glyph) * size); - otf_gstring.size = size; - } - else if (otf_gstring.size < size) - { - otf_gstring.glyphs = xrealloc (otf_gstring.glyphs, - sizeof (OTF_Glyph) * size); + if (otf_gstring.size < size) + { + otf_gstring.glyphs = xnrealloc (otf_gstring.glyphs, + size, sizeof (OTF_Glyph)); otf_gstring.size = size; } otf_gstring.used = size; @@ -2445,17 +2443,19 @@ } } + if (INT_MAX / 2 < len) + memory_full (SIZE_MAX); + if (gstring.allocated == 0) { - gstring.allocated = len * 2; gstring.glyph_size = sizeof (MFLTGlyph); - gstring.glyphs = xmalloc (sizeof (MFLTGlyph) * gstring.allocated); + gstring.glyphs = xnmalloc (len * 2, sizeof (MFLTGlyph)); + gstring.allocated = len * 2; } else if (gstring.allocated < len * 2) { + gstring.glyphs = xnrealloc (gstring.glyphs, len * 2, sizeof (MFLTGlyph)); gstring.allocated = len * 2; - gstring.glyphs = xrealloc (gstring.glyphs, - sizeof (MFLTGlyph) * gstring.allocated); } memset (gstring.glyphs, 0, sizeof (MFLTGlyph) * len); for (i = 0; i < len; i++) @@ -2504,9 +2504,11 @@ int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt); if (result != -2) break; - gstring.allocated += gstring.allocated; - gstring.glyphs = xrealloc (gstring.glyphs, - sizeof (MFLTGlyph) * gstring.allocated); + if (INT_MAX / 2 < gstring.allocated) + memory_full (SIZE_MAX); + gstring.glyphs = xnrealloc (gstring.glyphs, + gstring.allocated, 2 * sizeof (MFLTGlyph)); + gstring.allocated *= 2; } if (gstring.used > LGSTRING_GLYPH_LEN (lgstring)) return Qnil; === modified file 'src/gtkutil.c' --- src/gtkutil.c 2011-08-04 17:04:39 +0000 +++ src/gtkutil.c 2011-08-05 02:19:34 +0000 @@ -487,7 +487,8 @@ if (!utf8_str) { /* Probably some control characters in str. Escape them. */ - size_t nr_bad = 0; + ptrdiff_t len; + ptrdiff_t nr_bad = 0; gsize bytes_read; gsize bytes_written; unsigned char *p = (unsigned char *)str; @@ -511,7 +512,10 @@ } if (cp) g_free (cp); - up = utf8_str = xmalloc (strlen (str) + nr_bad * 4 + 1); + len = strlen (str); + if ((min (PTRDIFF_MAX, SIZE_MAX) - len - 1) / 4 < nr_bad) + memory_full (SIZE_MAX); + up = utf8_str = xmalloc (len + nr_bad * 4 + 1); p = (unsigned char *)str; while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read, @@ -3296,8 +3300,8 @@ static struct { GtkWidget **widgets; - int max_size; - int used; + ptrdiff_t max_size; + ptrdiff_t used; } id_to_widget; /* Grow this much every time we need to allocate more */ @@ -3306,17 +3310,20 @@ /* Store the widget pointer W in id_to_widget and return the integer index. */ -static int +static ptrdiff_t xg_store_widget_in_map (GtkWidget *w) { - int i; + ptrdiff_t i; if (id_to_widget.max_size == id_to_widget.used) { - int new_size = id_to_widget.max_size + ID_TO_WIDGET_INCR; + ptrdiff_t new_size; + if (TYPE_MAXIMUM (Window) - ID_TO_WIDGET_INCR < id_to_widget.max_size) + memory_full (SIZE_MAX); - id_to_widget.widgets = xrealloc (id_to_widget.widgets, - sizeof (GtkWidget *)*new_size); + new_size = id_to_widget.max_size + ID_TO_WIDGET_INCR; + id_to_widget.widgets = xnrealloc (id_to_widget.widgets, + new_size, sizeof (GtkWidget *)); for (i = id_to_widget.max_size; i < new_size; ++i) id_to_widget.widgets[i] = 0; @@ -3345,7 +3352,7 @@ Called when scroll bar is destroyed. */ static void -xg_remove_widget_from_map (int idx) +xg_remove_widget_from_map (ptrdiff_t idx) { if (idx < id_to_widget.max_size && id_to_widget.widgets[idx] != 0) { @@ -3357,7 +3364,7 @@ /* Get the widget pointer at IDX from id_to_widget. */ static GtkWidget * -xg_get_widget_from_map (int idx) +xg_get_widget_from_map (ptrdiff_t idx) { if (idx < id_to_widget.max_size && id_to_widget.widgets[idx] != 0) return id_to_widget.widgets[idx]; @@ -3396,10 +3403,10 @@ /* Return the scrollbar id for X Window WID on display DPY. Return -1 if WID not in id_to_widget. */ -int +ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid) { - int idx; + ptrdiff_t idx; GtkWidget *w; w = xg_win_to_widget (dpy, wid); @@ -3421,7 +3428,7 @@ static void xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data) { - int id = (intptr_t) data; + intptr_t id = (intptr_t) data; xg_remove_widget_from_map (id); } @@ -3496,7 +3503,7 @@ /* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */ void -xg_remove_scroll_bar (FRAME_PTR f, int scrollbar_id) +xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id) { GtkWidget *w = xg_get_widget_from_map (scrollbar_id); if (w) @@ -3515,7 +3522,7 @@ void xg_update_scrollbar_pos (FRAME_PTR f, - int scrollbar_id, + ptrdiff_t scrollbar_id, int top, int left, int width, @@ -4429,7 +4436,7 @@ int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)); int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)); int idx; - int img_id; + ptrdiff_t img_id; int icon_size = 0; struct image *img = NULL; Lisp_Object image; === modified file 'src/gtkutil.h' --- src/gtkutil.h 2011-06-14 21:08:20 +0000 +++ src/gtkutil.h 2011-07-28 23:58:05 +0000 @@ -114,17 +114,17 @@ extern int xg_have_tear_offs (void); -extern int xg_get_scroll_id_for_window (Display *dpy, Window wid); +extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid); extern void xg_create_scroll_bar (FRAME_PTR f, struct scroll_bar *bar, GCallback scroll_callback, GCallback end_callback, const char *scroll_bar_name); -extern void xg_remove_scroll_bar (FRAME_PTR f, int scrollbar_id); +extern void xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id); extern void xg_update_scrollbar_pos (FRAME_PTR f, - int scrollbar_id, + ptrdiff_t scrollbar_id, int top, int left, int width, @@ -185,4 +185,3 @@ #endif /* USE_GTK */ #endif /* GTKUTIL_H */ - === modified file 'src/image.c' --- src/image.c 2011-07-29 07:05:17 +0000 +++ src/image.c 2011-08-05 02:19:34 +0000 @@ -196,7 +196,7 @@ int x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) { - return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; + return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; } #endif @@ -218,9 +218,9 @@ if (dpyinfo->bitmaps == NULL) { + dpyinfo->bitmaps + = (Bitmap_Record *) xmalloc (10 * sizeof (Bitmap_Record)); dpyinfo->bitmaps_size = 10; - dpyinfo->bitmaps - = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record)); dpyinfo->bitmaps_last = 1; return 1; } @@ -235,17 +235,18 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2 < dpyinfo->bitmaps_size) memory_full (SIZE_MAX); - dpyinfo->bitmaps_size *= 2; dpyinfo->bitmaps = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps, - dpyinfo->bitmaps_size * sizeof (Bitmap_Record)); + (dpyinfo->bitmaps_size + * (2 * sizeof (Bitmap_Record)))); + dpyinfo->bitmaps_size *= 2; return ++dpyinfo->bitmaps_last; } /* Add one reference to the reference count of the bitmap with id ID. */ void -x_reference_bitmap (FRAME_PTR f, int id) +x_reference_bitmap (FRAME_PTR f, ptrdiff_t id) { ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; } @@ -807,29 +808,30 @@ break; case IMAGE_POSITIVE_INTEGER_VALUE: - if (!INTEGERP (value) || XINT (value) <= 0) + if (! RANGED_INTEGERP (1, value, INT_MAX)) return 0; break; case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR: - if (INTEGERP (value) && XINT (value) >= 0) + if (RANGED_INTEGERP (1, value, INT_MAX)) break; if (CONSP (value) - && INTEGERP (XCAR (value)) && INTEGERP (XCDR (value)) - && XINT (XCAR (value)) >= 0 && XINT (XCDR (value)) >= 0) + && RANGED_INTEGERP (1, XCAR (value), INT_MAX) + && RANGED_INTEGERP (1, XCDR (value), INT_MAX)) break; return 0; case IMAGE_ASCENT_VALUE: if (SYMBOLP (value) && EQ (value, Qcenter)) break; - else if (INTEGERP (value) - && XINT (value) >= 0 - && XINT (value) <= 100) + else if (RANGED_INTEGERP (0, value, 100)) break; return 0; case IMAGE_NON_NEGATIVE_INTEGER_VALUE: + /* Unlike the other integer-related cases, this one does not + verify that VALUE fits in 'int'. This is because callers + want EMACS_INT. */ if (!INTEGERP (value) || XINT (value) < 0) return 0; break; @@ -849,7 +851,7 @@ break; case IMAGE_INTEGER_VALUE: - if (!INTEGERP (value)) + if (! TYPE_RANGED_INTEGERP (int, value)) return 0; break; @@ -919,7 +921,7 @@ if (valid_image_p (spec)) { struct frame *f = check_x_frame (frame); - int id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec); struct image *img = IMAGE_FROM_ID (f, id); int width = img->width + 2 * img->hmargin; int height = img->height + 2 * img->vmargin; @@ -949,7 +951,7 @@ if (valid_image_p (spec)) { struct frame *f = check_x_frame (frame); - int id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec); struct image *img = IMAGE_FROM_ID (f, id); if (img->mask) mask = Qt; @@ -972,7 +974,7 @@ if (valid_image_p (spec)) { struct frame *f = check_x_frame (frame); - int id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec); struct image *img = IMAGE_FROM_ID (f, id); ext = img->lisp_data; } @@ -1125,7 +1127,7 @@ ascent = height / 2; } else - ascent = (int) (height * img->ascent / 100.0); + ascent = height * (img->ascent / 100.0); return ascent; } @@ -1371,11 +1373,12 @@ { /* This isn't called frequently so we get away with simply reallocating the color vector to the needed size, here. */ - ++img->ncolors; + ptrdiff_t ncolors = img->ncolors + 1; img->colors = (unsigned long *) xrealloc (img->colors, - img->ncolors * sizeof *img->colors); - img->colors[img->ncolors - 1] = color.pixel; + ncolors * sizeof *img->colors); + img->colors[ncolors - 1] = color.pixel; + img->ncolors = ncolors; result = color.pixel; } else @@ -1403,8 +1406,9 @@ int size; memset (c, 0, sizeof *c); - c->size = 50; - c->images = (struct image **) xmalloc (c->size * sizeof *c->images); + size = 50; + c->images = (struct image **) xmalloc (size * sizeof *c->images); + c->size = size; size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; c->buckets = (struct image **) xmalloc (size); memset (c->buckets, 0, size); @@ -1470,7 +1474,7 @@ struct image_cache *c = FRAME_IMAGE_CACHE (f); if (c) { - int i; + ptrdiff_t i; /* Cache should not be referenced by any frame when freed. */ xassert (c->refcount == 0); @@ -1500,7 +1504,7 @@ if (c) { - int i, nfreed = 0; + ptrdiff_t i, nfreed = 0; /* Block input so that we won't be interrupted by a SIGIO while being in an inconsistent state. */ @@ -1524,8 +1528,8 @@ { /* Free cache based on timestamp. */ EMACS_TIME t; - time_t old; - int delay, nimages = 0; + double old, delay; + ptrdiff_t nimages = 0; for (i = 0; i < c->used; ++i) if (c->images[i]) @@ -1533,9 +1537,10 @@ /* If the number of cached images has grown unusually large, decrease the cache eviction delay (Bug#6230). */ - delay = XFASTINT (Vimage_cache_eviction_delay); + delay = XINT (Vimage_cache_eviction_delay); if (nimages > 40) - delay = max (1, 1600 * delay / (nimages*nimages)); + delay = 1600 * delay / nimages / nimages; + delay = max (delay, 1); EMACS_GET_TIME (t); old = EMACS_SECS (t) - delay; @@ -1711,7 +1716,7 @@ /* Return the id of image with Lisp specification SPEC on frame F. SPEC must be a valid Lisp image specification (see valid_image_p). */ -int +ptrdiff_t lookup_image (struct frame *f, Lisp_Object spec) { struct image *img; @@ -1770,15 +1775,12 @@ img->ascent = CENTERED_IMAGE_ASCENT; margin = image_spec_value (spec, QCmargin, NULL); - if (INTEGERP (margin) && XINT (margin) >= 0) + if (INTEGERP (margin)) img->vmargin = img->hmargin = XFASTINT (margin); - else if (CONSP (margin) && INTEGERP (XCAR (margin)) - && INTEGERP (XCDR (margin))) + else if (CONSP (margin)) { - if (XINT (XCAR (margin)) > 0) - img->hmargin = XFASTINT (XCAR (margin)); - if (XINT (XCDR (margin)) > 0) - img->vmargin = XFASTINT (XCDR (margin)); + img->hmargin = XFASTINT (XCAR (margin)); + img->vmargin = XFASTINT (XCDR (margin)); } relief = image_spec_value (spec, QCrelief, NULL); @@ -1825,7 +1827,7 @@ cache_image (struct frame *f, struct image *img) { struct image_cache *c = FRAME_IMAGE_CACHE (f); - int i; + ptrdiff_t i; /* Find a free slot in c->images. */ for (i = 0; i < c->used; ++i) @@ -1837,9 +1839,10 @@ { if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size) memory_full (SIZE_MAX); + c->images = + (struct image **) xrealloc (c->images, + c->size * (2 * sizeof *c->images)); c->size *= 2; - c->images = (struct image **) xrealloc (c->images, - c->size * sizeof *c->images); } /* Add IMG to c->images, and assign IMG an id. */ @@ -1879,7 +1882,7 @@ { if (c) { - int i; + ptrdiff_t i; for (i = 0; i < c->used; ++i) if (c->images[i]) mark_image (c->images[i]); @@ -2076,7 +2079,7 @@ DWORD err = GetLastError (); Lisp_Object errcode; /* All system errors are < 10000, so the following is safe. */ - XSETINT (errcode, (int) err); + XSETINT (errcode, err); image_error ("Unable to create bitmap, error code %d", errcode, Qnil); x_destroy_x_image (*ximg); return 0; @@ -2355,7 +2358,7 @@ else { Lisp_Object data; - EMACS_INT width, height; + int width, height; /* Entries for `:width', `:height' and `:data' must be present. */ if (!kw[XBM_WIDTH].count @@ -3587,9 +3590,8 @@ #endif /* HAVE_NTGUI */ /* Remember allocated colors. */ + img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors); img->ncolors = attrs.nalloc_pixels; - img->colors = (unsigned long *) xmalloc (img->ncolors - * sizeof *img->colors); for (i = 0; i < attrs.nalloc_pixels; ++i) { img->colors[i] = attrs.alloc_pixels[i]; @@ -3813,8 +3815,8 @@ int chars_len) { struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); - int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len), - NULL); + ptrdiff_t i = + hash_lookup (table, make_unibyte_string (chars_start, chars_len), NULL); return i >= 0 ? HASH_VALUE (table, i) : Qnil; } @@ -4163,6 +4165,12 @@ /* Number of entries in the color table. */ static int ct_colors_allocated; +enum +{ + ct_colors_allocated_max = + min (INT_MAX, + min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long)) +}; /* Initialize the color table. */ @@ -4249,7 +4257,14 @@ XColor color; Colormap cmap; int rc; - +#else + COLORREF color; +#endif + + if (ct_colors_allocated_max <= ct_colors_allocated) + return FRAME_FOREGROUND_PIXEL (f); + +#ifdef HAVE_X_WINDOWS color.red = r; color.green = g; color.blue = b; @@ -4271,7 +4286,6 @@ return FRAME_FOREGROUND_PIXEL (f); #else - COLORREF color; #ifdef HAVE_NTGUI color = PALETTERGB (r, g, b); #else @@ -4312,6 +4326,9 @@ Colormap cmap; int rc; + if (ct_colors_allocated_max <= ct_colors_allocated) + return FRAME_FOREGROUND_PIXEL (f); + #ifdef HAVE_X_WINDOWS cmap = FRAME_X_COLORMAP (f); color.pixel = pixel; @@ -4450,7 +4467,9 @@ HGDIOBJ prev; #endif /* HAVE_NTGUI */ - colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors); + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height) + memory_full (SIZE_MAX); + colors = (XColor *) xmalloc (sizeof *colors * img->width * img->height); #ifndef HAVE_NTGUI /* Get the X image IMG->pixmap. */ @@ -4602,7 +4621,9 @@ #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) - new = (XColor *) xmalloc (img->width * img->height * sizeof *new); + if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height) + memory_full (SIZE_MAX); + new = (XColor *) xmalloc (sizeof *new * img->width * img->height); for (y = 0; y < img->height; ++y) { @@ -5880,7 +5901,7 @@ for (x = 0; x < width; ++x) { - unsigned r, g, b; + int r, g, b; r = *p++ << 8; g = *p++ << 8; @@ -6745,17 +6766,29 @@ } +static void tiff_handler (const char *, const char *, const char *, va_list) + ATTRIBUTE_FORMAT_PRINTF (3, 0); +static void +tiff_handler (const char *log_format, const char *title, + const char *format, va_list ap) +{ + /* doprnt is not suitable here, as TIFF handlers are called from + libtiff and are passed arbitrary printf directives. Instead, use + vsnprintf, taking care to be portable to nonstandard environments + where vsnprintf returns -1 on buffer overflow. Since it's just a + log entry, it's OK to truncate it. */ + char buf[4000]; + int len = vsnprintf (buf, sizeof buf, format, ap); + add_to_log (log_format, build_string (title), + make_string (buf, max (0, min (len, sizeof buf - 1)))); +} + static void tiff_error_handler (const char *, const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (2, 0); static void tiff_error_handler (const char *title, const char *format, va_list ap) { - char buf[512]; - int len; - - len = sprintf (buf, "TIFF error: %s ", title); - vsprintf (buf + len, format, ap); - add_to_log (buf, Qnil, Qnil); + tiff_handler ("TIFF error: %s %s", title, format, ap); } @@ -6764,12 +6797,7 @@ static void tiff_warning_handler (const char *title, const char *format, va_list ap) { - char buf[512]; - int len; - - len = sprintf (buf, "TIFF warning: %s ", title); - vsprintf (buf + len, format, ap); - add_to_log (buf, Qnil, Qnil); + tiff_handler ("TIFF warning: %s %s", title, format, ap); } @@ -6845,8 +6873,9 @@ image = image_spec_value (img->spec, QCindex, NULL); if (INTEGERP (image)) { - int ino = XFASTINT (image); - if (!fn_TIFFSetDirectory (tiff, ino)) + EMACS_INT ino = XFASTINT (image); + if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t) + && fn_TIFFSetDirectory (tiff, ino))) { image_error ("Invalid image number `%s' in image `%s'", image, img->spec); @@ -7145,7 +7174,7 @@ Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL); Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL); unsigned long bgcolor = 0; - int idx; + EMACS_INT idx; if (NILP (specified_data)) { @@ -7375,7 +7404,7 @@ img->lisp_data = Qnil; if (gif->SavedImages[idx].ExtensionBlockCount > 0) { - unsigned int delay = 0; + int delay = 0; ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks; for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++) /* Append (... FUNCTION "BYTES") */ @@ -7396,7 +7425,7 @@ if (delay) img->lisp_data = Fcons (Qdelay, - Fcons (make_float (((double) delay) * 0.01), + Fcons (make_float (delay / 100.0), img->lisp_data)); } @@ -7572,10 +7601,10 @@ Lisp_Object image; Lisp_Object value; Lisp_Object crop; - long ino; + EMACS_INT ino; int desired_width, desired_height; double rotation; - int imagemagick_rendermethod; + EMACS_INT imagemagick_rendermethod; int pixelwidth; ImageInfo *image_info; ExceptionInfo *exception; @@ -7602,7 +7631,7 @@ status = MagickPingImageBlob (ping_wand, contents, size); } - if (ino >= MagickGetNumberImages (ping_wand)) + if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand))) { image_error ("Invalid image number `%s' in image `%s'", image, img->spec); @@ -7677,28 +7706,28 @@ efficient. */ crop = image_spec_value (img->spec, QCcrop, NULL); - if (CONSP (crop) && INTEGERP (XCAR (crop))) + if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop))) { /* After some testing, it seems MagickCropImage is the fastest crop function in ImageMagick. This crop function seems to do less copying than the alternatives, but it still reads the entire image into memory - before croping, which is aparently difficult to avoid when using + before cropping, which is apparently difficult to avoid when using imagemagick. */ - int w, h; - w = XFASTINT (XCAR (crop)); + size_t crop_width = XINT (XCAR (crop)); crop = XCDR (crop); - if (CONSP (crop) && INTEGERP (XCAR (crop))) + if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop))) { - h = XFASTINT (XCAR (crop)); + size_t crop_height = XINT (XCAR (crop)); crop = XCDR (crop); - if (CONSP (crop) && INTEGERP (XCAR (crop))) + if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop))) { - x = XFASTINT (XCAR (crop)); + ssize_t crop_x = XINT (XCAR (crop)); crop = XCDR (crop); - if (CONSP (crop) && INTEGERP (XCAR (crop))) + if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop))) { - y = XFASTINT (XCAR (crop)); - MagickCropImage (image_wand, w, h, x, y); + ssize_t crop_y = XINT (XCAR (crop)); + MagickCropImage (image_wand, crop_width, crop_height, + crop_x, crop_y); } } } @@ -7744,9 +7773,11 @@ init_color_table (); imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type) - ? XFASTINT (Vimagemagick_render_type) : 0); + ? XINT (Vimagemagick_render_type) : 0); if (imagemagick_rendermethod == 0) { + size_t image_height; + /* Try to create a x pixmap to hold the imagemagick pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) @@ -7775,7 +7806,8 @@ goto imagemagick_error; } - for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++) + image_height = MagickGetImageHeight (image_wand); + for (y = 0; y < image_height; y++) { pixels = PixelGetNextIteratorRow (iterator, &width); if (pixels == (PixelWand **) NULL) @@ -8281,10 +8313,10 @@ { for (x = 0; x < width; ++x) { - unsigned red; - unsigned green; - unsigned blue; - unsigned opacity; + int red; + int green; + int blue; + int opacity; red = *pixels++; green = *pixels++; @@ -8465,7 +8497,8 @@ static int gs_load (struct frame *f, struct image *img) { - char buffer[100]; + uprintmax_t printnum1, printnum2; + char buffer[sizeof " " + INT_STRLEN_BOUND (printmax_t)]; Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; Lisp_Object frame; double in_width, in_height; @@ -8477,16 +8510,19 @@ info. */ pt_width = image_spec_value (img->spec, QCpt_width, NULL); in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0; - img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx; + in_width *= FRAME_X_DISPLAY_INFO (f)->resx; pt_height = image_spec_value (img->spec, QCpt_height, NULL); in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0; - img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; + in_height *= FRAME_X_DISPLAY_INFO (f)->resy; - if (!check_image_size (f, img->width, img->height)) + if (! (in_width <= INT_MAX && in_height <= INT_MAX + && check_image_size (f, in_width, in_height))) { image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); return 0; } + img->width = in_width; + img->height = in_height; /* Create the pixmap. */ xassert (img->pixmap == NO_PIXMAP); @@ -8511,14 +8547,14 @@ if successful. We do not record_unwind_protect here because other places in redisplay like calling window scroll functions don't either. Let the Lisp loader use `unwind-protect' instead. */ - sprintf (buffer, "%lu %lu", - (unsigned long) FRAME_X_WINDOW (f), - (unsigned long) img->pixmap); + printnum1 = FRAME_X_WINDOW (f); + printnum2 = img->pixmap; + sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2); window_and_pixmap_id = build_string (buffer); - sprintf (buffer, "%lu %lu", - FRAME_FOREGROUND_PIXEL (f), - FRAME_BACKGROUND_PIXEL (f)); + printnum1 = FRAME_FOREGROUND_PIXEL (f); + printnum2 = FRAME_BACKGROUND_PIXEL (f); + sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2); pixel_colors = build_string (buffer); XSETFRAME (frame, f); @@ -8543,7 +8579,8 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f) { struct image_cache *c = FRAME_IMAGE_CACHE (f); - int class, i; + int class; + ptrdiff_t i; struct image *img; /* Find the image containing PIXMAP. */ @@ -8647,7 +8684,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") (Lisp_Object spec) { - int id = -1; + ptrdiff_t id = -1; if (valid_image_p (spec)) id = lookup_image (SELECTED_FRAME (), spec); === modified file 'src/indent.c' --- src/indent.c 2011-07-14 21:35:23 +0000 +++ src/indent.c 2011-08-05 02:15:35 +0000 @@ -284,7 +284,7 @@ else \ { \ if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \ - width = ASIZE (DISP_CHAR_VECTOR (dp, ch)); \ + width = sanitize_char_width (ASIZE (DISP_CHAR_VECTOR (dp, ch))); \ else \ width = CHAR_WIDTH (ch); \ } \ @@ -318,15 +318,6 @@ last_known_column_point = 0; } -/* Return a non-outlandish value for the tab width. */ - -static int -sane_tab_width (void) -{ - EMACS_INT n = XFASTINT (BVAR (current_buffer, tab_width)); - return 0 < n && n <= 1000 ? n : 8; -} - EMACS_INT current_column (void) { @@ -335,7 +326,7 @@ register int tab_seen; EMACS_INT post_tab; register int c; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); register struct Lisp_Char_Table *dp = buffer_display_table (); @@ -515,7 +506,7 @@ static void scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) { - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); register struct Lisp_Char_Table *dp = buffer_display_table (); int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); @@ -732,7 +723,7 @@ register int tab_seen; int post_tab; register int c; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); int ctl_arrow = !NILP (current_buffer->ctl_arrow); register struct Lisp_Char_Table *dp = buffer_display_table (); int b, e; @@ -808,7 +799,7 @@ { EMACS_INT mincol; register EMACS_INT fromcol; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); CHECK_NUMBER (column); if (NILP (minimum)) @@ -867,7 +858,7 @@ position_indentation (register int pos_byte) { register EMACS_INT column = 0; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); register unsigned char *p; register unsigned char *stop; unsigned char *start; @@ -1116,7 +1107,7 @@ register EMACS_INT pos; EMACS_INT pos_byte; register int c = 0; - int tab_width = sane_tab_width (); + int tab_width = SANE_TAB_WIDTH (current_buffer); register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); register struct Lisp_Char_Table *dp = window_display_table (win); EMACS_INT selective @@ -1432,7 +1423,7 @@ the text character-by-character. */ if (current_buffer->width_run_cache && pos >= next_width_run) { - EMACS_INT run_end; + ptrdiff_t run_end; int common_width = region_cache_forward (current_buffer, current_buffer->width_run_cache, === modified file 'src/keyboard.c' --- src/keyboard.c 2011-08-04 17:04:39 +0000 +++ src/keyboard.c 2011-08-05 02:19:34 +0000 @@ -435,16 +435,16 @@ static int read_avail_input (int); static void get_input_pending (int *, int); static int readable_events (int); -static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *, +static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *, Lisp_Object, int *); -static Lisp_Object read_char_minibuf_menu_prompt (int, int, +static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t, Lisp_Object *); static Lisp_Object make_lispy_event (struct input_event *); #if defined (HAVE_MOUSE) || defined (HAVE_GPM) static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object, enum scroll_bar_part, Lisp_Object, Lisp_Object, - unsigned long); + Time); #endif static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object, Lisp_Object, const char *const *, @@ -1300,7 +1300,7 @@ /* This is the actual command reading loop, sans error-handling encapsulation. */ -static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object, +static int read_key_sequence (Lisp_Object *, int, Lisp_Object, int, int, int); void safe_run_hooks (Lisp_Object); static void adjust_point_for_property (EMACS_INT, int); @@ -2267,7 +2267,8 @@ Value is t if we showed a menu and the user rejected it. */ Lisp_Object -read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event, +read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, + Lisp_Object prev_event, int *used_mouse_menu, struct timeval *end_time) { volatile Lisp_Object c; @@ -7405,7 +7406,7 @@ { /* The number of keymaps we're scanning right now, and the number of keymaps we have allocated space for. */ - int nmaps; + ptrdiff_t nmaps; /* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1] in the current keymaps, or nil where it is not a prefix. */ @@ -7413,7 +7414,7 @@ Lisp_Object def, tail; - int mapno; + ptrdiff_t mapno; Lisp_Object oquit; /* In order to build the menus, we need to call the keymap @@ -7458,7 +7459,7 @@ recognized when the menu-bar (or mode-line) is updated, which does not normally happen after every command. */ Lisp_Object tem; - int nminor; + ptrdiff_t nminor; nminor = current_minor_maps (NULL, &tmaps); maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); nmaps = 0; @@ -7962,7 +7963,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems) { Lisp_Object *maps; - int nmaps, i; + ptrdiff_t nmaps, i; Lisp_Object oquit; Lisp_Object *tmaps; @@ -8002,7 +8003,7 @@ recognized when the tool-bar (or mode-line) is updated, which does not normally happen after every command. */ Lisp_Object tem; - int nminor; + ptrdiff_t nminor; nminor = current_minor_maps (NULL, &tmaps); maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0])); nmaps = 0; @@ -8274,10 +8275,11 @@ Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION); const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : ""; const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : ""; - EMACS_INT max_lbl = 2 * tool_bar_max_label_size; + ptrdiff_t max_lbl = + 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)); char *buf = (char *) xmalloc (max_lbl + 1); Lisp_Object new_lbl; - size_t caption_len = strlen (capt); + ptrdiff_t caption_len = strlen (capt); if (caption_len <= max_lbl && capt[0] != '\0') { @@ -8290,7 +8292,7 @@ if (strlen (label) <= max_lbl && label[0] != '\0') { - int j; + ptrdiff_t j; if (label != buf) strcpy (buf, label); @@ -8399,10 +8401,10 @@ and do auto-saving in the inner call of read_char. */ static Lisp_Object -read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event, - int *used_mouse_menu) +read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps, + Lisp_Object prev_event, int *used_mouse_menu) { - int mapno; + ptrdiff_t mapno; if (used_mouse_menu) *used_mouse_menu = 0; @@ -8430,7 +8432,7 @@ Lisp_Object *realmaps = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); Lisp_Object value; - int nmaps1 = 0; + ptrdiff_t nmaps1 = 0; /* Use the maps that are not nil. */ for (mapno = 0; mapno < nmaps; mapno++) @@ -8481,17 +8483,18 @@ We make this bigger when necessary, and never free it. */ static char *read_char_minibuf_menu_text; /* Size of that buffer. */ -static int read_char_minibuf_menu_width; +static ptrdiff_t read_char_minibuf_menu_width; static Lisp_Object -read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps) +read_char_minibuf_menu_prompt (int commandflag, + ptrdiff_t nmaps, Lisp_Object *maps) { - int mapno; + ptrdiff_t mapno; register Lisp_Object name; - int nlength; + ptrdiff_t nlength; /* FIXME: Use the minibuffer's frame width. */ - int width = FRAME_COLS (SELECTED_FRAME ()) - 4; - int idx = -1; + ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4; + ptrdiff_t idx = -1; int nobindings = 1; Lisp_Object rest, vector; char *menu; @@ -8516,16 +8519,13 @@ /* Make sure we have a big enough buffer for the menu text. */ width = max (width, SBYTES (name)); - if (read_char_minibuf_menu_text == 0) - { - read_char_minibuf_menu_width = width + 4; - read_char_minibuf_menu_text = (char *) xmalloc (width + 4); - } - else if (width + 4 > read_char_minibuf_menu_width) - { - read_char_minibuf_menu_width = width + 4; + if (STRING_BYTES_BOUND - 4 < width) + memory_full (SIZE_MAX); + if (width + 4 > read_char_minibuf_menu_width) + { read_char_minibuf_menu_text = (char *) xrealloc (read_char_minibuf_menu_text, width + 4); + read_char_minibuf_menu_width = width + 4; } menu = read_char_minibuf_menu_text; @@ -8544,7 +8544,7 @@ while (1) { int notfirst = 0; - int i = nlength; + ptrdiff_t i = nlength; Lisp_Object obj; Lisp_Object orig_defn_macro; @@ -8643,7 +8643,7 @@ < width || !notfirst) { - int thiswidth; + ptrdiff_t thiswidth; /* Punctuate between strings. */ if (notfirst) @@ -8659,9 +8659,7 @@ if (! char_matches) { /* Add as much of string as fits. */ - thiswidth = SCHARS (desc); - if (thiswidth + i > width) - thiswidth = width - i; + thiswidth = min (SCHARS (desc), width - i); memcpy (menu + i, SDATA (desc), thiswidth); i += thiswidth; strcpy (menu + i, " = "); @@ -8669,9 +8667,7 @@ } /* Add as much of string as fits. */ - thiswidth = SCHARS (s); - if (thiswidth + i > width) - thiswidth = width - i; + thiswidth = min (SCHARS (s), width - i); memcpy (menu + i, SDATA (s), thiswidth); i += thiswidth; menu[i] = 0; @@ -8746,10 +8742,10 @@ NEXT may be the same array as CURRENT. */ static int -follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs, - Lisp_Object *next) +follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current, + Lisp_Object *defs, Lisp_Object *next) { - int i, first_binding; + ptrdiff_t i, first_binding; first_binding = nmaps; for (i = nmaps - 1; i >= 0; i--) @@ -8849,7 +8845,7 @@ The return value is non-zero if the remapping actually took place. */ static int -keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey, +keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey, int input, int doit, int *diff, Lisp_Object prompt) { Lisp_Object next, key; @@ -8871,7 +8867,7 @@ *diff = len - (fkey->end - fkey->start); - if (input + *diff >= bufsize) + if (bufsize - input <= *diff) error ("Key sequence too long"); /* Shift the keys that follow fkey->end. */ @@ -8942,7 +8938,7 @@ from the selected window's buffer. */ static int -read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt, +read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, int dont_downcase_last, int can_return_switch_frame, int fix_current_buffer) { @@ -8959,8 +8955,8 @@ /* The number of keymaps we're scanning right now, and the number of keymaps we have allocated space for. */ - int nmaps; - int nmaps_allocated = 0; + ptrdiff_t nmaps; + ptrdiff_t nmaps_allocated = 0; /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in the current keymaps. */ @@ -8984,7 +8980,7 @@ /* The index in submaps[] of the first keymap that has a binding for this key sequence. In other words, the lowest i such that submaps[i] is non-nil. */ - int first_binding; + ptrdiff_t first_binding; /* Index of the first key that has no binding. It is useless to try fkey.start larger than that. */ int first_unbound; @@ -9145,8 +9141,8 @@ } else { - int nminor; - int total; + ptrdiff_t nminor; + ptrdiff_t total; Lisp_Object *maps; nminor = current_minor_maps (0, &maps); @@ -9212,7 +9208,8 @@ echo_local_start and keys_local_start allow us to throw away just one key. */ int echo_local_start IF_LINT (= 0); - int keys_local_start, local_first_binding; + int keys_local_start; + ptrdiff_t local_first_binding; eassert (indec.end == t || (indec.end > t && indec.end <= mock_input)); eassert (indec.start <= indec.end); @@ -9549,7 +9546,7 @@ && (NILP (fake_prefixed_keys) || NILP (Fmemq (key, fake_prefixed_keys)))) { - if (t + 1 >= bufsize) + if (bufsize - t <= 1) error ("Key sequence too long"); keybuf[t] = posn; @@ -9630,7 +9627,7 @@ insert the dummy prefix event `menu-bar'. */ if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) { - if (t + 1 >= bufsize) + if (bufsize - t <= 1) error ("Key sequence too long"); keybuf[t] = posn; keybuf[t+1] = key; === modified file 'src/keyboard.h' --- src/keyboard.h 2011-07-07 17:55:38 +0000 +++ src/keyboard.h 2011-07-29 00:30:00 +0000 @@ -440,7 +440,7 @@ extern Lisp_Object parse_modifiers (Lisp_Object); extern Lisp_Object reorder_modifiers (Lisp_Object); -extern Lisp_Object read_char (int, int, Lisp_Object *, Lisp_Object, +extern Lisp_Object read_char (int, ptrdiff_t, Lisp_Object *, Lisp_Object, int *, EMACS_TIME *); extern int parse_solitary_modifier (Lisp_Object symbol); === modified file 'src/keymap.c' --- src/keymap.c 2011-08-03 21:40:06 +0000 +++ src/keymap.c 2011-08-05 02:19:34 +0000 @@ -1399,7 +1399,7 @@ some systems, static gets macro-defined to be the empty string. Ickypoo. */ static Lisp_Object *cmm_modes = NULL, *cmm_maps = NULL; -static int cmm_size = 0; +static ptrdiff_t cmm_size = 0; /* Store a pointer to an array of the currently active minor modes in *modeptr, a pointer to an array of the keymaps of the currently @@ -1419,10 +1419,10 @@ loop. Instead, we'll use realloc/malloc and silently truncate the list, let the key sequence be read, and hope some other piece of code signals the error. */ -int +ptrdiff_t current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr) { - int i = 0; + ptrdiff_t i = 0; int list_number = 0; Lisp_Object alist, assoc, var, val; Lisp_Object emulation_alists; @@ -1465,9 +1465,16 @@ if (i >= cmm_size) { - int newsize, allocsize; + ptrdiff_t newsize, allocsize; Lisp_Object *newmodes, *newmaps; + /* Check for size calculation overflow. Other code + (e.g., read_key_sequence) adds 3 to the count + later, so subtract 3 from the limit here. */ + if (min (PTRDIFF_MAX, SIZE_MAX) / (2 * sizeof *newmodes) - 3 + < cmm_size) + break; + newsize = cmm_size == 0 ? 30 : cmm_size * 2; allocsize = newsize * sizeof *newmodes; === modified file 'src/keymap.h' --- src/keymap.h 2011-07-07 17:19:10 +0000 +++ src/keymap.h 2011-07-29 00:32:09 +0000 @@ -38,7 +38,7 @@ EXFUN (Fset_keymap_parent, 2); extern int describe_map_tree (Lisp_Object, int, Lisp_Object, Lisp_Object, const char *, int, int, int, int); -extern int current_minor_maps (Lisp_Object **, Lisp_Object **); +extern ptrdiff_t current_minor_maps (Lisp_Object **, Lisp_Object **); extern void initial_define_key (Lisp_Object, int, const char *); extern void initial_define_lispy_key (Lisp_Object, const char *, const char *); extern void syms_of_keymap (void); === modified file 'src/lisp.h' --- src/lisp.h 2011-08-02 03:49:09 +0000 +++ src/lisp.h 2011-08-05 02:19:34 +0000 @@ -1704,6 +1704,11 @@ #define NUMBERP(x) (INTEGERP (x) || FLOATP (x)) #define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0) +#define RANGED_INTEGERP(lo, x, hi) \ + (INTEGERP (x) && (lo) <= XINT (x) && XINT (x) <= (hi)) +#define TYPE_RANGED_INTEGERP(type, x) \ + RANGED_INTEGERP (TYPE_MINIMUM (type), x, TYPE_MAXIMUM (type)) + #define INTEGERP(x) (LISP_INT_TAG_P (XTYPE ((x)))) #define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol) #define MISCP(x) (XTYPE ((x)) == Lisp_Misc) @@ -2551,6 +2556,7 @@ /* Defined in fns.c */ extern Lisp_Object QCrehash_size, QCrehash_threshold; +enum { NEXT_ALMOST_PRIME_LIMIT = 11 }; extern EMACS_INT next_almost_prime (EMACS_INT); extern Lisp_Object larger_vector (Lisp_Object, EMACS_INT, Lisp_Object); extern void sweep_weak_hash_tables (void); @@ -2562,8 +2568,8 @@ Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -EMACS_INT hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); -EMACS_INT hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, +ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); +ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, EMACS_UINT); void init_weak_hash_tables (void); extern void init_fns (void); @@ -3569,6 +3575,9 @@ extern POINTER_TYPE *xmalloc (size_t); extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t); extern void xfree (POINTER_TYPE *); +extern void *xnmalloc (ptrdiff_t, ptrdiff_t); +extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t); +extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern char *xstrdup (const char *); @@ -3686,6 +3695,23 @@ } \ } while (0) +/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * + NITEMS items, each of the same type as *BUF. MULTIPLIER must + positive. The code is tuned for MULTIPLIER being a constant. */ + +#define SAFE_NALLOCA(buf, multiplier, nitems) \ + do { \ + if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \ + (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \ + else \ + { \ + (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ + sa_must_free = 1; \ + record_unwind_protect (safe_alloca_unwind, \ + make_save_value (buf, 0)); \ + } \ + } while (0) + /* SAFE_FREE frees xmalloced memory and enables GC as needed. */ #define SAFE_FREE() \ === modified file 'src/lread.c' --- src/lread.c 2011-07-28 20:23:19 +0000 +++ src/lread.c 2011-07-29 05:31:12 +0000 @@ -2613,14 +2613,14 @@ if (saved_doc_string_size == 0) { + saved_doc_string = (char *) xmalloc (nskip + extra); saved_doc_string_size = nskip + extra; - saved_doc_string = (char *) xmalloc (saved_doc_string_size); } if (nskip > saved_doc_string_size) { - saved_doc_string_size = nskip + extra; saved_doc_string = (char *) xrealloc (saved_doc_string, - saved_doc_string_size); + nskip + extra); + saved_doc_string_size = nskip + extra; } saved_doc_string_position = file_tell (instream); @@ -2883,7 +2883,8 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size) memory_full (SIZE_MAX); read_buffer = (char *) xrealloc (read_buffer, - read_buffer_size *= 2); + read_buffer_size * 2); + read_buffer_size *= 2; p = read_buffer + offset; end = read_buffer + read_buffer_size; } @@ -3026,7 +3027,8 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size) memory_full (SIZE_MAX); read_buffer = (char *) xrealloc (read_buffer, - read_buffer_size *= 2); + read_buffer_size * 2); + read_buffer_size *= 2; p = read_buffer + offset; end = read_buffer + read_buffer_size; } @@ -3056,7 +3058,8 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size) memory_full (SIZE_MAX); read_buffer = (char *) xrealloc (read_buffer, - read_buffer_size *= 2); + read_buffer_size * 2); + read_buffer_size *= 2; p = read_buffer + offset; end = read_buffer + read_buffer_size; } @@ -3938,6 +3941,7 @@ init_obarray (void) { Lisp_Object oblength; + ptrdiff_t size = 100 + MAX_MULTIBYTE_LENGTH; XSETFASTINT (oblength, OBARRAY_SIZE); @@ -3970,8 +3974,8 @@ DEFSYM (Qvariable_documentation, "variable-documentation"); - read_buffer_size = 100 + MAX_MULTIBYTE_LENGTH; - read_buffer = (char *) xmalloc (read_buffer_size); + read_buffer = (char *) xmalloc (size); + read_buffer_size = size; } \f void === modified file 'src/macros.c' --- src/macros.c 2011-06-24 21:25:22 +0000 +++ src/macros.c 2011-07-29 01:00:29 +0000 @@ -62,9 +62,9 @@ if (!current_kboard->kbd_macro_buffer) { - current_kboard->kbd_macro_bufsize = 30; current_kboard->kbd_macro_buffer = (Lisp_Object *)xmalloc (30 * sizeof (Lisp_Object)); + current_kboard->kbd_macro_bufsize = 30; } update_mode_lines++; if (NILP (append)) @@ -202,7 +202,7 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *kb->kbd_macro_buffer / 2 < kb->kbd_macro_bufsize) memory_full (SIZE_MAX); - nbytes = kb->kbd_macro_bufsize * 2 * sizeof *kb->kbd_macro_buffer; + nbytes = kb->kbd_macro_bufsize * (2 * sizeof *kb->kbd_macro_buffer); kb->kbd_macro_buffer = (Lisp_Object *) xrealloc (kb->kbd_macro_buffer, nbytes); kb->kbd_macro_bufsize *= 2; === modified file 'src/minibuf.c' --- src/minibuf.c 2011-07-19 17:33:06 +0000 +++ src/minibuf.c 2011-08-05 02:15:35 +0000 @@ -1723,7 +1723,7 @@ (Lisp_Object string, Lisp_Object collection, Lisp_Object predicate) { Lisp_Object regexps, tail, tem = Qnil; - EMACS_INT i = 0; + ptrdiff_t i = 0; CHECK_STRING (string); === modified file 'src/nsmenu.m' --- src/nsmenu.m 2011-07-28 18:30:59 +0000 +++ src/nsmenu.m 2011-07-29 05:31:12 +0000 @@ -1014,7 +1014,7 @@ BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P)); BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P)); int idx; - int img_id; + ptrdiff_t img_id; struct image *img; Lisp_Object image; Lisp_Object helpObj; === modified file 'src/nsterm.h' --- src/nsterm.h 2011-07-28 18:50:05 +0000 +++ src/nsterm.h 2011-07-29 05:31:12 +0000 @@ -416,8 +416,8 @@ /* this to map between emacs color indices and NSColor objects */ struct ns_color_table { - unsigned int size; - unsigned int avail; + ptrdiff_t size; + ptrdiff_t avail; #ifdef __OBJC__ NSColor **colors; NSMutableSet *empty_indices; === modified file 'src/nsterm.m' --- src/nsterm.m 2011-07-28 18:41:21 +0000 +++ src/nsterm.m 2011-08-05 02:15:35 +0000 @@ -1341,7 +1341,7 @@ ns_index_color (NSColor *color, struct frame *f) { struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table; - int idx; + ptrdiff_t idx; NSNumber *index; if (!color_table->colors) @@ -1356,7 +1356,7 @@ /* do we already have this color ? */ { - int i; + ptrdiff_t i; for (i = 1; i < color_table->avail; i++) { if (color_table->colors[i] && [color_table->colors[i] isEqual: color]) @@ -1371,17 +1371,14 @@ { index = [color_table->empty_indices anyObject]; [color_table->empty_indices removeObject: index]; - idx = [index unsignedIntValue]; + idx = [index unsignedLongValue]; } else { if (color_table->avail == color_table->size) - { - color_table->size += NS_COLOR_CAPACITY; - color_table->colors - = (NSColor **)xrealloc (color_table->colors, - color_table->size * sizeof (NSColor *)); - } + color_table->colors = + xpalloc (color_table->colors, &color_table->size, 1, + min (ULONG_MAX, PTRDIFF_MAX), sizeof *color_table->colors); idx = color_table->avail++; } @@ -2321,7 +2318,7 @@ if (!img) { unsigned short *bits = p->bits + p->dh; - int len = 8 * p->h/8; + int len = p->h; int i; unsigned char *cbits = xmalloc (len); @@ -4857,7 +4854,7 @@ } } - + #if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 /* if we get here we should send the key for input manager processing */ if (firstTime && [[NSInputManager currentInputManager] === modified file 'src/process.c' --- src/process.c 2011-07-16 18:27:08 +0000 +++ src/process.c 2011-08-05 02:15:35 +0000 @@ -3558,7 +3558,7 @@ { struct ifconf ifconf; struct ifreq *ifreqs = NULL; - int ifaces = 0; + ptrdiff_t ifaces = 0; int buf_size, s; Lisp_Object res; @@ -3567,15 +3567,9 @@ return Qnil; again: - ifaces += 25; + ifreqs = xpalloc (ifreqs, &ifaces, 25, + INT_MAX / sizeof *ifreqs, sizeof *ifreqs); buf_size = ifaces * sizeof (ifreqs[0]); - ifreqs = (struct ifreq *)xrealloc(ifreqs, buf_size); - if (!ifreqs) - { - close (s); - return Qnil; - } - ifconf.ifc_len = buf_size; ifconf.ifc_req = ifreqs; if (ioctl (s, SIOCGIFCONF, &ifconf)) === modified file 'src/region-cache.c' --- src/region-cache.c 2011-04-19 00:34:42 +0000 +++ src/region-cache.c 2011-08-05 02:15:35 +0000 @@ -63,7 +63,7 @@ revalidate_region_cache to see how this helps. */ struct boundary { - EMACS_INT pos; + ptrdiff_t pos; int value; }; @@ -73,16 +73,16 @@ struct boundary *boundaries; /* boundaries[gap_start ... gap_start + gap_len - 1] is the gap. */ - EMACS_INT gap_start, gap_len; + ptrdiff_t gap_start, gap_len; /* The number of elements allocated to boundaries, not including the gap. */ - EMACS_INT cache_len; + ptrdiff_t cache_len; /* The areas that haven't changed since the last time we cleaned out invalid entries from the cache. These overlap when the buffer is entirely unchanged. */ - EMACS_INT beg_unchanged, end_unchanged; + ptrdiff_t beg_unchanged, end_unchanged; /* The first and last positions in the buffer. Because boundaries store their positions relative to the start (BEG) and end (Z) of @@ -92,7 +92,7 @@ Yes, buffer_beg is always 1. It's there for symmetry with buffer_end and the BEG and BUF_BEG macros. */ - EMACS_INT buffer_beg, buffer_end; + ptrdiff_t buffer_beg, buffer_end; }; /* Return the position of boundary i in cache c. */ @@ -173,17 +173,17 @@ This operation should be logarithmic in the number of cache entries. It would be nice if it took advantage of locality of reference, too, by searching entries near the last entry found. */ -static EMACS_INT -find_cache_boundary (struct region_cache *c, EMACS_INT pos) +static ptrdiff_t +find_cache_boundary (struct region_cache *c, ptrdiff_t pos) { - EMACS_INT low = 0, high = c->cache_len; + ptrdiff_t low = 0, high = c->cache_len; while (low + 1 < high) { /* mid is always a valid index, because low < high and ">> 1" rounds down. */ - EMACS_INT mid = (low + high) >> 1; - EMACS_INT boundary = BOUNDARY_POS (c, mid); + ptrdiff_t mid = (low >> 1) + (high >> 1) + (low & high & 1); + ptrdiff_t boundary = BOUNDARY_POS (c, mid); if (pos < boundary) high = mid; @@ -208,13 +208,13 @@ /* Move the gap of cache C to index POS, and make sure it has space for at least MIN_SIZE boundaries. */ static void -move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size) +move_cache_gap (struct region_cache *c, ptrdiff_t pos, ptrdiff_t min_size) { /* Copy these out of the cache and into registers. */ - EMACS_INT gap_start = c->gap_start; - EMACS_INT gap_len = c->gap_len; - EMACS_INT buffer_beg = c->buffer_beg; - EMACS_INT buffer_end = c->buffer_end; + ptrdiff_t gap_start = c->gap_start; + ptrdiff_t gap_len = c->gap_len; + ptrdiff_t buffer_beg = c->buffer_beg; + ptrdiff_t buffer_end = c->buffer_end; if (pos < 0 || pos > c->cache_len) @@ -246,17 +246,11 @@ when the portion after the gap is smallest. */ if (gap_len < min_size) { - EMACS_INT i; - - /* Always make at least NEW_CACHE_GAP elements, as long as we're - expanding anyway. */ - if (min_size < NEW_CACHE_GAP) - min_size = NEW_CACHE_GAP; + ptrdiff_t i; c->boundaries = - (struct boundary *) xrealloc (c->boundaries, - ((min_size + c->cache_len) - * sizeof (*c->boundaries))); + xpalloc (c->boundaries, &c->cache_len, min_size, -1, + sizeof *c->boundaries); /* Some systems don't provide a version of the copy routine that can be trusted to shift memory upward into an overlapping @@ -293,7 +287,7 @@ /* Insert a new boundary in cache C; it will have cache index I, and have the specified POS and VALUE. */ static void -insert_cache_boundary (struct region_cache *c, EMACS_INT i, EMACS_INT pos, +insert_cache_boundary (struct region_cache *c, ptrdiff_t i, ptrdiff_t pos, int value) { /* i must be a valid cache index. */ @@ -331,9 +325,9 @@ static void delete_cache_boundaries (struct region_cache *c, - EMACS_INT start, EMACS_INT end) + ptrdiff_t start, ptrdiff_t end) { - EMACS_INT len = end - start; + ptrdiff_t len = end - start; /* Gotta be in range. */ if (start < 0 @@ -384,7 +378,7 @@ /* Set the value in cache C for the region START..END to VALUE. */ static void set_cache_region (struct region_cache *c, - EMACS_INT start, EMACS_INT end, int value) + ptrdiff_t start, ptrdiff_t end, int value) { if (start > end) abort (); @@ -407,8 +401,8 @@ index of the earliest boundary after the last character in start..end. (This tortured terminology is intended to answer all the "< or <=?" sort of questions.) */ - EMACS_INT start_ix = find_cache_boundary (c, start); - EMACS_INT end_ix = find_cache_boundary (c, end - 1) + 1; + ptrdiff_t start_ix = find_cache_boundary (c, start); + ptrdiff_t end_ix = find_cache_boundary (c, end - 1) + 1; /* We must remember the value established by the last boundary before end; if that boundary's domain stretches beyond end, @@ -486,7 +480,7 @@ args to pass are the same before and after such an operation.) */ void invalidate_region_cache (struct buffer *buf, struct region_cache *c, - EMACS_INT head, EMACS_INT tail) + ptrdiff_t head, ptrdiff_t tail) { /* Let chead = c->beg_unchanged, and ctail = c->end_unchanged. @@ -624,7 +618,7 @@ corresponds to the modified region of the buffer. */ else { - EMACS_INT modified_ix; + ptrdiff_t modified_ix; /* These positions are correct, relative to both the cache basis and the buffer basis. */ @@ -693,7 +687,7 @@ no newlines", in the case of the line cache). */ void know_region_cache (struct buffer *buf, struct region_cache *c, - EMACS_INT start, EMACS_INT end) + ptrdiff_t start, ptrdiff_t end) { revalidate_region_cache (buf, c); @@ -708,14 +702,14 @@ position after POS where the knownness changes. */ int region_cache_forward (struct buffer *buf, struct region_cache *c, - EMACS_INT pos, EMACS_INT *next) + ptrdiff_t pos, ptrdiff_t *next) { revalidate_region_cache (buf, c); { - EMACS_INT i = find_cache_boundary (c, pos); + ptrdiff_t i = find_cache_boundary (c, pos); int i_value = BOUNDARY_VALUE (c, i); - EMACS_INT j; + ptrdiff_t j; /* Beyond the end of the buffer is unknown, by definition. */ if (pos >= BUF_Z (buf)) @@ -744,7 +738,7 @@ the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest position before POS where the knownness changes. */ int region_cache_backward (struct buffer *buf, struct region_cache *c, - EMACS_INT pos, EMACS_INT *next) + ptrdiff_t pos, ptrdiff_t *next) { revalidate_region_cache (buf, c); @@ -757,9 +751,9 @@ } { - EMACS_INT i = find_cache_boundary (c, pos - 1); + ptrdiff_t i = find_cache_boundary (c, pos - 1); int i_value = BOUNDARY_VALUE (c, i); - EMACS_INT j; + ptrdiff_t j; if (next) { @@ -785,18 +779,18 @@ void pp_cache (struct region_cache *c) { - int i; - EMACS_INT beg_u = c->buffer_beg + c->beg_unchanged; - EMACS_INT end_u = c->buffer_end - c->end_unchanged; + ptrdiff_t i; + ptrdiff_t beg_u = c->buffer_beg + c->beg_unchanged; + ptrdiff_t end_u = c->buffer_end - c->end_unchanged; fprintf (stderr, - "basis: %"pI"d..%"pI"d modified: %"pI"d..%"pI"d\n", + "basis: %"pD"d..%"pD"d modified: %"pD"d..%"pD"d\n", c->buffer_beg, c->buffer_end, beg_u, end_u); for (i = 0; i < c->cache_len; i++) { - EMACS_INT pos = BOUNDARY_POS (c, i); + ptrdiff_t pos = BOUNDARY_POS (c, i); putc (((pos < beg_u) ? 'v' : (pos == beg_u) ? '-' @@ -806,6 +800,6 @@ : (pos == end_u) ? '-' : ' '), stderr); - fprintf (stderr, "%"pI"d : %d\n", pos, BOUNDARY_VALUE (c, i)); + fprintf (stderr, "%"pD"d : %d\n", pos, BOUNDARY_VALUE (c, i)); } } === modified file 'src/region-cache.h' --- src/region-cache.h 2011-04-14 06:48:41 +0000 +++ src/region-cache.h 2011-08-05 02:15:35 +0000 @@ -72,7 +72,7 @@ no newlines", in the case of the line cache). */ extern void know_region_cache (struct buffer *BUF, struct region_cache *CACHE, - EMACS_INT START, EMACS_INT END); + ptrdiff_t START, ptrdiff_t END); /* Indicate that a section of BUF has changed, to invalidate CACHE. HEAD is the number of chars unchanged at the beginning of the buffer. @@ -84,7 +84,7 @@ args to pass are the same before and after such an operation.) */ extern void invalidate_region_cache (struct buffer *BUF, struct region_cache *CACHE, - EMACS_INT HEAD, EMACS_INT TAIL); + ptrdiff_t HEAD, ptrdiff_t TAIL); /* The scanning functions. @@ -100,13 +100,13 @@ position after POS where the knownness changes. */ extern int region_cache_forward (struct buffer *BUF, struct region_cache *CACHE, - EMACS_INT POS, - EMACS_INT *NEXT); + ptrdiff_t POS, + ptrdiff_t *NEXT); /* Return true if the text immediately before POS in BUF is known, for the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest position before POS where the knownness changes. */ extern int region_cache_backward (struct buffer *BUF, struct region_cache *CACHE, - EMACS_INT POS, - EMACS_INT *NEXT); + ptrdiff_t POS, + ptrdiff_t *NEXT); === modified file 'src/scroll.c' --- src/scroll.c 2011-06-22 18:15:23 +0000 +++ src/scroll.c 2011-08-05 02:15:35 +0000 @@ -969,32 +969,14 @@ const char *cleanup_string, int coefficient) { - if (FRAME_INSERT_COST (frame) != 0) - { - FRAME_INSERT_COST (frame) = - (int *) xrealloc (FRAME_INSERT_COST (frame), - FRAME_LINES (frame) * sizeof (int)); - FRAME_DELETEN_COST (frame) = - (int *) xrealloc (FRAME_DELETEN_COST (frame), - FRAME_LINES (frame) * sizeof (int)); - FRAME_INSERTN_COST (frame) = - (int *) xrealloc (FRAME_INSERTN_COST (frame), - FRAME_LINES (frame) * sizeof (int)); - FRAME_DELETE_COST (frame) = - (int *) xrealloc (FRAME_DELETE_COST (frame), - FRAME_LINES (frame) * sizeof (int)); - } - else - { - FRAME_INSERT_COST (frame) = - (int *) xmalloc (FRAME_LINES (frame) * sizeof (int)); - FRAME_DELETEN_COST (frame) = - (int *) xmalloc (FRAME_LINES (frame) * sizeof (int)); - FRAME_INSERTN_COST (frame) = - (int *) xmalloc (FRAME_LINES (frame) * sizeof (int)); - FRAME_DELETE_COST (frame) = - (int *) xmalloc (FRAME_LINES (frame) * sizeof (int)); - } + FRAME_INSERT_COST (frame) = + xnrealloc (FRAME_INSERT_COST (frame), FRAME_LINES (frame), sizeof (int)); + FRAME_DELETEN_COST (frame) = + xnrealloc (FRAME_DELETEN_COST (frame), FRAME_LINES (frame), sizeof (int)); + FRAME_INSERTN_COST (frame) = + xnrealloc (FRAME_INSERTN_COST (frame), FRAME_LINES (frame), sizeof (int)); + FRAME_DELETE_COST (frame) = + xnrealloc (FRAME_DELETE_COST (frame), FRAME_LINES (frame), sizeof (int)); ins_del_costs (frame, ins_line_string, multi_ins_string, === modified file 'src/search.c' --- src/search.c 2011-07-14 18:45:36 +0000 +++ src/search.c 2011-08-05 02:15:35 +0000 @@ -683,7 +683,7 @@ to see where we can avoid some scanning. */ if (target == '\n' && newline_cache) { - EMACS_INT next_change; + ptrdiff_t next_change; immediate_quit = 0; while (region_cache_forward (current_buffer, newline_cache, start_byte, &next_change)) @@ -755,7 +755,7 @@ /* Consult the newline cache, if appropriate. */ if (target == '\n' && newline_cache) { - EMACS_INT next_change; + ptrdiff_t next_change; immediate_quit = 0; while (region_cache_backward (current_buffer, newline_cache, start_byte, &next_change)) @@ -2640,15 +2640,17 @@ perform substitution on the replacement string. */ if (NILP (literal)) { - EMACS_INT length = SBYTES (newtext); + ptrdiff_t length = SBYTES (newtext); unsigned char *substed; - EMACS_INT substed_alloc_size, substed_len; + ptrdiff_t substed_alloc_size, substed_len; int buf_multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); int str_multibyte = STRING_MULTIBYTE (newtext); int really_changed = 0; - substed_alloc_size = length * 2 + 100; - substed = (unsigned char *) xmalloc (substed_alloc_size + 1); + substed_alloc_size = ((STRING_BYTES_BOUND - 100) / 2 < length + ? STRING_BYTES_BOUND + : length * 2 + 100); + substed = (unsigned char *) xmalloc (substed_alloc_size); substed_len = 0; /* Go thru NEWTEXT, producing the actual text to insert in @@ -2659,7 +2661,7 @@ { unsigned char str[MAX_MULTIBYTE_LENGTH]; const unsigned char *add_stuff = NULL; - EMACS_INT add_len = 0; + ptrdiff_t add_len = 0; int idx = -1; if (str_multibyte) @@ -2723,7 +2725,7 @@ set up ADD_STUFF and ADD_LEN to point to it. */ if (idx >= 0) { - EMACS_INT begbyte = CHAR_TO_BYTE (search_regs.start[idx]); + ptrdiff_t begbyte = CHAR_TO_BYTE (search_regs.start[idx]); add_len = CHAR_TO_BYTE (search_regs.end[idx]) - begbyte; if (search_regs.start[idx] < GPT && GPT < search_regs.end[idx]) move_gap (search_regs.start[idx]); @@ -2734,12 +2736,11 @@ is invariably ADD_LEN bytes starting at ADD_STUFF. */ /* Make sure SUBSTED is big enough. */ - if (substed_len + add_len >= substed_alloc_size) - { - substed_alloc_size = substed_len + add_len + 500; - substed = (unsigned char *) xrealloc (substed, - substed_alloc_size + 1); - } + if (substed_alloc_size - substed_len < add_len) + substed = + xpalloc (substed, &substed_alloc_size, + add_len - (substed_alloc_size - substed_len), + STRING_BYTES_BOUND, 1); /* Now add to the end of SUBSTED. */ if (add_stuff) @@ -2973,7 +2974,7 @@ If optional arg RESEAT is non-nil, make markers on LIST point nowhere. */) (register Lisp_Object list, Lisp_Object reseat) { - register int i; + ptrdiff_t i; register Lisp_Object marker; if (running_asynch_code) @@ -2987,31 +2988,21 @@ /* Allocate registers if they don't already exist. */ { - int length = XFASTINT (Flength (list)) / 2; + ptrdiff_t length = XFASTINT (Flength (list)) / 2; if (length > search_regs.num_regs) { - if (search_regs.num_regs == 0) - { - search_regs.start - = (regoff_t *) xmalloc (length * sizeof (regoff_t)); - search_regs.end - = (regoff_t *) xmalloc (length * sizeof (regoff_t)); - } - else - { - search_regs.start - = (regoff_t *) xrealloc (search_regs.start, - length * sizeof (regoff_t)); - search_regs.end - = (regoff_t *) xrealloc (search_regs.end, - length * sizeof (regoff_t)); - } + ptrdiff_t num_regs = search_regs.num_regs; + search_regs.start = + xpalloc (search_regs.start, &num_regs, length - num_regs, + min (PTRDIFF_MAX, UINT_MAX), sizeof (regoff_t)); + search_regs.end = + xrealloc (search_regs.end, num_regs * sizeof (regoff_t)); - for (i = search_regs.num_regs; i < length; i++) + for (i = search_regs.num_regs; i < num_regs; i++) search_regs.start[i] = -1; - search_regs.num_regs = length; + search_regs.num_regs = num_regs; } for (i = 0; CONSP (list); i++) === modified file 'src/sysdep.c' --- src/sysdep.c 2011-07-11 06:05:57 +0000 +++ src/sysdep.c 2011-07-29 01:16:54 +0000 @@ -2640,7 +2640,7 @@ ssize_t nread; const char *cmd = NULL; char *cmdline = NULL; - size_t cmdsize = 0, cmdline_size; + ptrdiff_t cmdsize = 0, cmdline_size; unsigned char c; int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount; unsigned long long u_time, s_time, cutime, cstime, start; @@ -2822,8 +2822,10 @@ if (fd >= 0) { char ch; - for (cmdline_size = 0; emacs_read (fd, &ch, 1) == 1; cmdline_size++) + for (cmdline_size = 0; cmdline_size < STRING_BYTES_BOUND; cmdline_size++) { + if (emacs_read (fd, &ch, 1) != 1) + break; c = ch; if (isspace (c) || c == '\\') cmdline_size++; /* for later quoting, see below */ @@ -2844,7 +2846,7 @@ nread = 0; } /* We don't want trailing null characters. */ - for (p = cmdline + nread - 1; p > cmdline && !*p; p--) + for (p = cmdline + nread; p > cmdline + 1 && !p[-1]; p--) nread--; for (p = cmdline; p < cmdline + nread; p++) { === modified file 'src/term.c' --- src/term.c 2011-07-14 17:28:42 +0000 +++ src/term.c 2011-08-05 02:15:35 +0000 @@ -136,10 +136,6 @@ static int max_frame_cols; -/* The largest frame height in any call to calculate_costs. */ - -static int max_frame_lines; - /* Non-zero if we have dropped our controlling tty and therefore should not open a frame on stdout. */ static int no_controlling_tty; @@ -497,8 +493,8 @@ static unsigned char *encode_terminal_src; static unsigned char *encode_terminal_dst; /* Allocated sizes of the above buffers. */ -static int encode_terminal_src_size; -static int encode_terminal_dst_size; +static ptrdiff_t encode_terminal_src_size; +static ptrdiff_t encode_terminal_dst_size; /* Encode SRC_LEN glyphs starting at SRC to terminal output codes. Set CODING->produced to the byte-length of the resulting byte @@ -509,8 +505,8 @@ { struct glyph *src_end = src + src_len; unsigned char *buf; - int nchars, nbytes, required; - register int tlen = GLYPH_TABLE_LENGTH; + ptrdiff_t nchars, nbytes, required; + ptrdiff_t tlen = GLYPH_TABLE_LENGTH; register Lisp_Object *tbase = GLYPH_TABLE_BASE; Lisp_Object charset_list; @@ -518,13 +514,13 @@ multibyte-form. But, it may be enlarged on demand if Vglyph_table contains a string or a composite glyph is encountered. */ - required = MAX_MULTIBYTE_LENGTH * src_len; + if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len) + memory_full (SIZE_MAX); + required = src_len; + required *= MAX_MULTIBYTE_LENGTH; if (encode_terminal_src_size < required) { - if (encode_terminal_src) - encode_terminal_src = xrealloc (encode_terminal_src, required); - else - encode_terminal_src = xmalloc (required); + encode_terminal_src = xrealloc (encode_terminal_src, required); encode_terminal_src_size = required; } @@ -544,19 +540,21 @@ if (src->u.cmp.automatic) { gstring = composition_gstring_from_id (src->u.cmp.id); - required = src->slice.cmp.to + 1 - src->slice.cmp.from; + required = src->slice.cmp.to - src->slice.cmp.from + 1; } else { cmp = composition_table[src->u.cmp.id]; - required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len; + required = cmp->glyph_len; + required *= MAX_MULTIBYTE_LENGTH; } - if (encode_terminal_src_size < nbytes + required) + if (encode_terminal_src_size - nbytes < required) { - encode_terminal_src_size = nbytes + required; - encode_terminal_src = xrealloc (encode_terminal_src, - encode_terminal_src_size); + encode_terminal_src = + xpalloc (encode_terminal_src, &encode_terminal_src_size, + required - (encode_terminal_src_size - nbytes), + -1, 1); buf = encode_terminal_src + nbytes; } @@ -627,11 +625,11 @@ if (NILP (string)) { nbytes = buf - encode_terminal_src; - if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH) + if (encode_terminal_src_size - nbytes < MAX_MULTIBYTE_LENGTH) { - encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH; - encode_terminal_src = xrealloc (encode_terminal_src, - encode_terminal_src_size); + encode_terminal_src = + xpalloc (encode_terminal_src, &encode_terminal_src_size, + MAX_MULTIBYTE_LENGTH, -1, 1); buf = encode_terminal_src + nbytes; } if (CHAR_BYTE8_P (c) @@ -659,11 +657,13 @@ if (! STRING_MULTIBYTE (string)) string = string_to_multibyte (string); nbytes = buf - encode_terminal_src; - if (encode_terminal_src_size < nbytes + SBYTES (string)) + if (encode_terminal_src_size - nbytes < SBYTES (string)) { - encode_terminal_src_size = nbytes + SBYTES (string); - encode_terminal_src = xrealloc (encode_terminal_src, - encode_terminal_src_size); + encode_terminal_src = + xpalloc (encode_terminal_src, &encode_terminal_src_size, + (SBYTES (string) + - (encode_terminal_src_size - nbytes)), + -1, 1); buf = encode_terminal_src + nbytes; } memcpy (buf, SDATA (string), SBYTES (string)); @@ -684,12 +684,9 @@ coding->source = encode_terminal_src; if (encode_terminal_dst_size == 0) { + encode_terminal_dst = xrealloc (encode_terminal_dst, + encode_terminal_src_size); encode_terminal_dst_size = encode_terminal_src_size; - if (encode_terminal_dst) - encode_terminal_dst = xrealloc (encode_terminal_dst, - encode_terminal_dst_size); - else - encode_terminal_dst = xmalloc (encode_terminal_dst_size); } coding->destination = encode_terminal_dst; coding->dst_bytes = encode_terminal_dst_size; @@ -1156,21 +1153,17 @@ char_ins_del_vector (i.e., char_ins_del_cost) isn't used because X turns off char_ins_del_ok. */ - max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); + if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2 + < max_frame_cols) + memory_full (SIZE_MAX); - if (char_ins_del_vector != 0) - char_ins_del_vector - = (int *) xrealloc (char_ins_del_vector, - (sizeof (int) - + 2 * max_frame_cols * sizeof (int))); - else - char_ins_del_vector - = (int *) xmalloc (sizeof (int) - + 2 * max_frame_cols * sizeof (int)); + char_ins_del_vector = + xrealloc (char_ins_del_vector, + (sizeof (int) + 2 * sizeof (int) * max_frame_cols)); memset (char_ins_del_vector, 0, - (sizeof (int) + 2 * max_frame_cols * sizeof (int))); + (sizeof (int) + 2 * sizeof (int) * max_frame_cols)); if (f && (!tty->TS_ins_line && !tty->TS_del_line)) === modified file 'src/termcap.c' --- src/termcap.c 2011-07-10 08:20:10 +0000 +++ src/termcap.c 2011-08-05 02:15:35 +0000 @@ -480,7 +480,7 @@ /* If BP is malloc'd by us, make sure it is big enough. */ if (malloc_size) { - int offset1 = bp1 - bp, offset2 = tc_search_point - bp; + ptrdiff_t offset1 = bp1 - bp, offset2 = tc_search_point - bp; malloc_size = offset1 + buf.size; bp = termcap_name = (char *) xrealloc (bp, malloc_size); bp1 = termcap_name + offset1; @@ -619,7 +619,6 @@ register char *end; register int nread; register char *buf = bufp->beg; - register char *tem; if (!append_end) append_end = bufp->ptr; @@ -636,14 +635,14 @@ { if (bufp->full == bufp->size) { - if ((PTRDIFF_MAX - 1) / 2 < bufp->size) - memory_full (SIZE_MAX); - bufp->size *= 2; + ptrdiff_t ptr_offset = bufp->ptr - buf; + ptrdiff_t append_end_offset = append_end - buf; /* Add 1 to size to ensure room for terminating null. */ - tem = (char *) xrealloc (buf, bufp->size + 1); - bufp->ptr = (bufp->ptr - buf) + tem; - append_end = (append_end - buf) + tem; - bufp->beg = buf = tem; + ptrdiff_t size = bufp->size + 1; + bufp->beg = buf = xpalloc (buf, &size, 1, -1, 1); + bufp->size = size - 1; + bufp->ptr = buf + ptr_offset; + append_end = buf + append_end_offset; } } else === modified file 'src/termhooks.h' --- src/termhooks.h 2011-06-06 19:43:39 +0000 +++ src/termhooks.h 2011-07-20 00:09:31 +0000 @@ -288,12 +288,12 @@ /* The next four modifier bits are used also in keyboard events at the Lisp level. - It's probably not the greatest idea to use the 2^23 bit for any + It's probably not the greatest idea to use the 2^28 bit for any modifier. It may or may not be the sign bit, depending on - VALBITS, so using it to represent a modifier key means that + FIXNUM_BITS, so using it to represent a modifier key means that characters thus modified have different integer equivalents depending on the architecture they're running on. Oh, and - applying XINT to a character whose 2^23 bit is set sign-extends + applying XINT to a character whose 2^28 bit is set might sign-extend it, so you get a bunch of bits in the mask you didn't want. The CHAR_ macros are defined in lisp.h. */ === modified file 'src/tparam.c' --- src/tparam.c 2011-07-10 08:20:10 +0000 +++ src/tparam.c 2011-08-05 02:15:35 +0000 @@ -79,24 +79,25 @@ register const char *p = string; register char *op = outstring; char *outend; - int outlen = 0; + char *new = 0; + ptrdiff_t outlen = 0; register int tem; int *old_argp = argp; /* can move */ int *fixed_argp = argp; /* never moves */ int explicit_param_p = 0; /* set by %p */ - int doleft = 0; - int doup = 0; + ptrdiff_t doleft = 0; + ptrdiff_t doup = 0; + ptrdiff_t append_len = 0; outend = outstring + len; while (1) { /* If the buffer might be too short, make it bigger. */ - if (op + 5 >= outend) + while (outend - op - append_len <= 5) { - register char *new; - int offset = op - outstring; + ptrdiff_t offset = op - outstring; if (outlen == 0) { @@ -106,8 +107,7 @@ } else { - outlen *= 2; - new = (char *) xrealloc (outstring, outlen); + new = xpalloc (outstring, &outlen, 1, -1, 1); } op = new + offset; @@ -167,11 +167,15 @@ and this is one of them, increment it. */ while (tem == 0 || tem == '\n' || tem == '\t') { + ptrdiff_t append_len_incr; tem++; if (argp == old_argp) - doup++, outend -= strlen (up); + doup++, append_len_incr = strlen (up); else - doleft++, outend -= strlen (left); + doleft++, append_len_incr = strlen (left); + if (INT_ADD_OVERFLOW (append_len, append_len_incr)) + memory_full (SIZE_MAX); + append_len += append_len_incr; } } *op++ = tem ? tem : 0200; @@ -273,7 +277,7 @@ args[0] = atoi (argv[2]); args[1] = atoi (argv[3]); args[2] = atoi (argv[4]); - tparam1 (argv[1], buf, "LEFT", "UP", args); + tparam1 (argv[1], buf, 50, "LEFT", "UP", args); printf ("%s\n", buf); return 0; } === modified file 'src/window.c' --- src/window.c 2011-07-14 17:28:42 +0000 +++ src/window.c 2011-07-19 21:39:36 +0000 @@ -5069,7 +5069,7 @@ && (!EQ (Vrecenter_redisplay, Qtty) || !NILP (Ftty_type (selected_frame)))) { - int i; + ptrdiff_t i; /* Invalidate pixel data calculated for all compositions. */ for (i = 0; i < n_compositions; i++) === modified file 'src/xdisp.c' --- src/xdisp.c 2011-08-03 05:24:30 +0000 +++ src/xdisp.c 2011-08-05 02:19:34 +0000 @@ -2478,10 +2478,7 @@ else if (INTEGERP (w->redisplay_end_trigger)) it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger); - /* Correct bogus values of tab_width. */ - it->tab_width = XINT (BVAR (current_buffer, tab_width)); - if (it->tab_width <= 0 || it->tab_width > 1000) - it->tab_width = 8; + it->tab_width = SANE_TAB_WIDTH (current_buffer); /* Are lines in the display truncated? */ if (base_face_id != DEFAULT_FACE_ID @@ -10379,13 +10376,14 @@ store_mode_line_noprop_char (char c) { /* If output position has reached the end of the allocated buffer, - double the buffer's size. */ + increase the buffer's size. */ if (mode_line_noprop_ptr == mode_line_noprop_buf_end) { - int len = MODE_LINE_NOPROP_LEN (0); - int new_size = 2 * len * sizeof *mode_line_noprop_buf; - mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size); - mode_line_noprop_buf_end = mode_line_noprop_buf + new_size; + ptrdiff_t len = MODE_LINE_NOPROP_LEN (0); + ptrdiff_t size = len; + mode_line_noprop_buf = + xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1); + mode_line_noprop_buf_end = mode_line_noprop_buf + size; mode_line_noprop_ptr = mode_line_noprop_buf + len; } @@ -10447,9 +10445,9 @@ /* Do we have more than one visible frame on this X display? */ Lisp_Object tail; Lisp_Object fmt; - int title_start; + ptrdiff_t title_start; char *title; - int len; + ptrdiff_t len; struct it it; int count = SPECPDL_INDEX (); @@ -21260,7 +21258,7 @@ if (FRAME_WINDOW_P (it->f) && valid_image_p (prop)) { - int id = lookup_image (it->f, prop); + ptrdiff_t id = lookup_image (it->f, prop); struct image *img = IMAGE_FROM_ID (it->f, id); return OK_PIXELS (width_p ? img->width : img->height); @@ -22132,7 +22130,7 @@ do { \ int face_id = (row)->glyphs[area][START].face_id; \ struct face *base_face = FACE_FROM_ID (f, face_id); \ - int cmp_id = (row)->glyphs[area][START].u.cmp.id; \ + ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \ struct composition *cmp = composition_table[cmp_id]; \ XChar2b *char2b; \ struct glyph_string *first_s IF_LINT (= NULL); \ === modified file 'src/xfaces.c' --- src/xfaces.c 2011-07-28 00:15:43 +0000 +++ src/xfaces.c 2011-08-05 02:15:35 +0000 @@ -403,7 +403,7 @@ /* A vector mapping Lisp face Id's to face names. */ static Lisp_Object *lface_id_to_name; -static int lface_id_to_name_size; +static ptrdiff_t lface_id_to_name_size; /* TTY color-related functions (defined in tty-colors.el). */ @@ -2667,12 +2667,10 @@ The mapping from Lisp face to Lisp face id is given by the property `face' of the Lisp face name. */ if (next_lface_id == lface_id_to_name_size) - { - int new_size = max (50, 2 * lface_id_to_name_size); - int sz = new_size * sizeof *lface_id_to_name; - lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz); - lface_id_to_name_size = new_size; - } + lface_id_to_name = + xpalloc (lface_id_to_name, &lface_id_to_name_size, 1, + min (INT_MAX, MOST_POSITIVE_FIXNUM), + sizeof *lface_id_to_name); lface_id_to_name[next_lface_id] = face; Fput (face, Qface, make_number (next_lface_id)); @@ -4410,15 +4408,8 @@ if (i == c->used) { if (c->used == c->size) - { - int new_size, sz; - new_size = min (2 * c->size, MAX_FACE_ID); - if (new_size == c->size) - abort (); /* Alternatives? ++kfs */ - sz = new_size * sizeof *c->faces_by_id; - c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz); - c->size = new_size; - } + c->faces_by_id = xpalloc (c->faces_by_id, &c->size, 1, MAX_FACE_ID, + sizeof *c->faces_by_id); c->used++; } === modified file 'src/xfns.c' --- src/xfns.c 2011-07-23 12:15:53 +0000 +++ src/xfns.c 2011-08-05 02:15:35 +0000 @@ -145,7 +145,8 @@ Lisp_Object Qfont_param; #if GLYPH_DEBUG -static int image_cache_refcount, dpyinfo_refcount; +static ptrdiff_t image_cache_refcount; +static int dpyinfo_refcount; #endif #if defined (USE_GTK) && defined (HAVE_FREETYPE) @@ -1470,7 +1471,8 @@ the result should be `COMPOUND_TEXT'. */ static unsigned char * -x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, int *text_bytes, int *stringp, int *freep) +x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, + ptrdiff_t *text_bytes, int *stringp, int *freep) { int result = string_xstring_p (string); struct coding_system coding; @@ -1488,8 +1490,8 @@ coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK); /* We suppress producing escape sequences for composition. */ coding.common_flags &= ~CODING_ANNOTATION_MASK; + coding.destination = xnmalloc (SCHARS (string), 2); coding.dst_bytes = SCHARS (string) * 2; - coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); encode_coding_object (&coding, string, 0, 0, SCHARS (string), SBYTES (string), Qnil); *text_bytes = coding.produced; @@ -1511,7 +1513,8 @@ BLOCK_INPUT; { XTextProperty text, icon; - int bytes, stringp; + ptrdiff_t bytes; + int stringp; int do_free_icon_value = 0, do_free_text_value = 0; Lisp_Object coding_system; Lisp_Object encoded_name; @@ -1550,6 +1553,8 @@ : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); text.format = 8; text.nitems = bytes; + if (text.nitems != bytes) + error ("Window name too large"); if (!STRINGP (f->icon_name)) { @@ -1565,6 +1570,8 @@ : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); icon.format = 8; icon.nitems = bytes; + if (icon.nitems != bytes) + error ("Icon name too large"); encoded_icon_name = ENCODE_UTF_8 (f->icon_name); } @@ -4193,21 +4200,19 @@ if (CONSP (value)) { + ptrdiff_t elsize; + nelements = x_check_property_data (value); if (nelements == -1) error ("Bad data in VALUE, must be number, string or cons"); - if (element_format == 8) - data = (unsigned char *) xmalloc (nelements); - else if (element_format == 16) - data = (unsigned char *) xmalloc (nelements*2); - else /* format == 32 */ - /* The man page for XChangeProperty: - "If the specified format is 32, the property data must be a - long array." - This applies even if long is more than 64 bits. The X library - converts to 32 bits before sending to the X server. */ - data = (unsigned char *) xmalloc (nelements * sizeof(long)); + /* The man page for XChangeProperty: + "If the specified format is 32, the property data must be a + long array." + This applies even if long is more than 32 bits. The X library + converts to 32 bits before sending to the X server. */ + elsize = element_format == 32 ? sizeof (long) : element_format >> 3; + data = xnmalloc (nelements, elsize); x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format); } @@ -4215,7 +4220,9 @@ { CHECK_STRING (value); data = SDATA (value); - nelements = SCHARS (value); + if (INT_MAX < SBYTES (value)) + error ("VALUE too long"); + nelements = SBYTES (value); } BLOCK_INPUT; === modified file 'src/xgselect.c' --- src/xgselect.c 2011-07-01 09:18:46 +0000 +++ src/xgselect.c 2011-08-05 02:15:35 +0000 @@ -29,7 +29,7 @@ #include <setjmp.h> static GPollFD *gfds; -static int gfds_size; +static ptrdiff_t gfds_size; int xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, @@ -54,10 +54,9 @@ do { if (n_gfds > gfds_size) { - while (n_gfds > gfds_size) - gfds_size *= 2; xfree (gfds); - gfds = xmalloc (sizeof (*gfds) * gfds_size); + gfds = xpalloc (0, &gfds_size, n_gfds - gfds_size, INT_MAX, + sizeof *gfds); } n_gfds = g_main_context_query (context, === modified file 'src/xrdb.c' --- src/xrdb.c 2011-07-10 08:20:10 +0000 +++ src/xrdb.c 2011-08-05 02:15:35 +0000 @@ -426,24 +426,22 @@ { XrmDatabase db; char *p; - char *path = 0, *home = 0; - const char *host; + char *path = 0; if ((p = getenv ("XENVIRONMENT")) == NULL) { - home = gethomedir (); - host = get_system_name (); - path = (char *) xmalloc (strlen (home) - + sizeof (".Xdefaults-") - + strlen (host)); - sprintf (path, "%s%s%s", home, ".Xdefaults-", host); + static char const xdefaults[] = ".Xdefaults-"; + char *home = gethomedir (); + char const *host = get_system_name (); + ptrdiff_t pathsize = strlen (home) + sizeof xdefaults + strlen (host); + path = (char *) xrealloc (home, pathsize); + strcat (strcat (path, xdefaults), host); p = path; } db = XrmGetFileDatabase (p); xfree (path); - xfree (home); return db; } === modified file 'src/xselect.c' --- src/xselect.c 2011-07-13 03:45:56 +0000 +++ src/xselect.c 2011-08-05 02:15:35 +0000 @@ -66,22 +66,15 @@ static void wait_for_property_change (struct prop_location *); static Lisp_Object x_get_foreign_selection (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -static void x_get_window_property (Display *, Window, Atom, - unsigned char **, int *, - Atom *, int *, unsigned long *, int); -static void receive_incremental_selection (Display *, Window, Atom, - Lisp_Object, unsigned, - unsigned char **, int *, - Atom *, int *, unsigned long *); static Lisp_Object x_get_window_property_as_lisp_data (Display *, Window, Atom, Lisp_Object, Atom); static Lisp_Object selection_data_to_lisp_data (Display *, const unsigned char *, - int, Atom, int); + ptrdiff_t, Atom, int); static void lisp_data_to_selection_data (Display *, Lisp_Object, unsigned char **, Atom *, - unsigned *, int *, int *); + ptrdiff_t *, int *, int *); static Lisp_Object clean_local_selection_data (Lisp_Object); /* Printing traces to stderr. */ @@ -114,15 +107,37 @@ static Lisp_Object Qforeign_selection; static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions; +/* Bytes needed to represent 'long' data. This is as per libX11; it + is not necessarily sizeof (long). */ +#define X_LONG_SIZE 4 + +/* Maximum unsigned 'short' and 'long' values suitable for libX11. */ +#define X_USHRT_MAX 0xffff +#define X_ULONG_MAX 0xffffffff + /* If this is a smaller number than the max-request-size of the display, emacs will use INCR selection transfer when the selection is larger than this. The max-request-size is usually around 64k, so if you want emacs to use incremental selection transfers when the selection is smaller than that, set this. I added this mostly for debugging the - incremental transfer stuff, but it might improve server performance. */ -#define MAX_SELECTION_QUANTUM 0xFFFFFF - -#define SELECTION_QUANTUM(dpy) ((XMaxRequestSize(dpy) << 2) - 100) + incremental transfer stuff, but it might improve server performance. + + This value cannot exceed INT_MAX / max (X_LONG_SIZE, sizeof (long)) + because it is multiplied by X_LONG_SIZE and by sizeof (long) in + subscript calculations. Similarly for PTRDIFF_MAX - 1 or SIZE_MAX + - 1 in place of INT_MAX. */ +#define MAX_SELECTION_QUANTUM \ + ((int) min (0xFFFFFF, (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) - 1) \ + / max (X_LONG_SIZE, sizeof (long))))) + +static int +selection_quantum (Display *display) +{ + long mrs = XMaxRequestSize (display); + return (mrs < MAX_SELECTION_QUANTUM / X_LONG_SIZE + 25 + ? (mrs - 25) * X_LONG_SIZE + : MAX_SELECTION_QUANTUM); +} #define LOCAL_SELECTION(selection_symbol,dpyinfo) \ assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist) @@ -477,7 +492,7 @@ struct selection_data { unsigned char *data; - unsigned int size; + ptrdiff_t size; int format; Atom type; int nofree; @@ -581,14 +596,11 @@ XSelectionEvent *reply = &(reply_base.xselection); Display *display = SELECTION_EVENT_DISPLAY (event); Window window = SELECTION_EVENT_REQUESTOR (event); - int bytes_remaining; - int max_bytes = SELECTION_QUANTUM (display); + ptrdiff_t bytes_remaining; + int max_bytes = selection_quantum (display); int count = SPECPDL_INDEX (); struct selection_data *cs; - if (max_bytes > MAX_SELECTION_QUANTUM) - max_bytes = MAX_SELECTION_QUANTUM; - reply->type = SelectionNotify; reply->display = display; reply->requestor = window; @@ -616,11 +628,12 @@ if (cs->property == None) continue; - bytes_remaining = cs->size * (cs->format / 8); + bytes_remaining = cs->size; + bytes_remaining *= cs->format >> 3; if (bytes_remaining <= max_bytes) { /* Send all the data at once, with minimal handshaking. */ - TRACE1 ("Sending all %d bytes", bytes_remaining); + TRACE1 ("Sending all %"pD"d bytes", bytes_remaining); XChangeProperty (display, window, cs->property, cs->type, cs->format, PropModeReplace, cs->data, cs->size); @@ -628,9 +641,9 @@ else { /* Send an INCR tag to initiate incremental transfer. */ - long value[1]; + unsigned long value[1]; - TRACE2 ("Start sending %d bytes incrementally (%s)", + TRACE2 ("Start sending %"pD"d bytes incrementally (%s)", bytes_remaining, XGetAtomName (display, cs->property)); cs->wait_object = expect_property_change (display, window, cs->property, @@ -638,7 +651,7 @@ /* XChangeProperty expects an array of long even if long is more than 32 bits. */ - value[0] = bytes_remaining; + value[0] = min (bytes_remaining, X_ULONG_MAX); XChangeProperty (display, window, cs->property, dpyinfo->Xatom_INCR, 32, PropModeReplace, (unsigned char *) value, 1); @@ -672,7 +685,8 @@ int had_errors = x_had_errors_p (display); UNBLOCK_INPUT; - bytes_remaining = cs->size * format_bytes; + bytes_remaining = cs->size; + bytes_remaining *= format_bytes; /* Wait for the requester to ack by deleting the property. This can run Lisp code (process handlers) or signal. */ @@ -810,7 +824,7 @@ non-None property. */ Window requestor = SELECTION_EVENT_REQUESTOR (event); Lisp_Object multprop; - int j, nselections; + ptrdiff_t j, nselections; if (property == None) goto DONE; multprop @@ -1269,19 +1283,28 @@ static void x_get_window_property (Display *display, Window window, Atom property, - unsigned char **data_ret, int *bytes_ret, + unsigned char **data_ret, ptrdiff_t *bytes_ret, Atom *actual_type_ret, int *actual_format_ret, unsigned long *actual_size_ret, int delete_p) { - int total_size; + ptrdiff_t total_size; unsigned long bytes_remaining; - int offset = 0; + ptrdiff_t offset = 0; + unsigned char *data = 0; unsigned char *tmp_data = 0; int result; - int buffer_size = SELECTION_QUANTUM (display); - - if (buffer_size > MAX_SELECTION_QUANTUM) - buffer_size = MAX_SELECTION_QUANTUM; + int buffer_size = selection_quantum (display); + + /* Wide enough to avoid overflow in expressions using it. */ + ptrdiff_t x_long_size = X_LONG_SIZE; + + /* Maximum value for TOTAL_SIZE. It cannot exceed PTRDIFF_MAX - 1 + and SIZE_MAX - 1, for an extra byte at the end. And it cannot + exceed LONG_MAX * X_LONG_SIZE, for XGetWindowProperty. */ + ptrdiff_t total_size_max = + ((min (PTRDIFF_MAX, SIZE_MAX) - 1) / x_long_size < LONG_MAX + ? min (PTRDIFF_MAX, SIZE_MAX) - 1 + : LONG_MAX * x_long_size); BLOCK_INPUT; @@ -1292,49 +1315,44 @@ actual_size_ret, &bytes_remaining, &tmp_data); if (result != Success) - { - UNBLOCK_INPUT; - *data_ret = 0; - *bytes_ret = 0; - return; - } + goto done; /* This was allocated by Xlib, so use XFree. */ XFree ((char *) tmp_data); if (*actual_type_ret == None || *actual_format_ret == 0) - { - UNBLOCK_INPUT; - return; - } + goto done; - total_size = bytes_remaining + 1; - *data_ret = (unsigned char *) xmalloc (total_size); + if (total_size_max < bytes_remaining) + goto size_overflow; + total_size = bytes_remaining; + data = malloc (total_size + 1); + if (! data) + goto memory_exhausted; /* Now read, until we've gotten it all. */ while (bytes_remaining) { -#ifdef TRACE_SELECTION - unsigned long last = bytes_remaining; -#endif + ptrdiff_t bytes_gotten; + int bytes_per_item; result = XGetWindowProperty (display, window, property, - (long)offset/4, (long)buffer_size/4, + offset / X_LONG_SIZE, + buffer_size / X_LONG_SIZE, False, AnyPropertyType, actual_type_ret, actual_format_ret, actual_size_ret, &bytes_remaining, &tmp_data); - TRACE2 ("Read %lu bytes from property %s", - last - bytes_remaining, - XGetAtomName (display, property)); - /* If this doesn't return Success at this point, it means that some clod deleted the selection while we were in the midst of reading it. Deal with that, I guess.... */ if (result != Success) break; + bytes_per_item = *actual_format_ret >> 3; + xassert (*actual_size_ret <= buffer_size / bytes_per_item); + /* The man page for XGetWindowProperty says: "If the returned format is 32, the returned data is represented as a long array and should be cast to that type to obtain the @@ -1348,32 +1366,61 @@ The bytes and offsets passed to XGetWindowProperty refers to the property and those are indeed in 32 bit quantities if format is 32. */ + bytes_gotten = *actual_size_ret; + bytes_gotten *= bytes_per_item; + + TRACE2 ("Read %"pD"d bytes from property %s", + bytes_gotten, XGetAtomName (display, property)); + + if (total_size - offset < bytes_gotten) + { + unsigned char *data1; + ptrdiff_t remaining_lim = total_size_max - offset - bytes_gotten; + if (remaining_lim < 0 || remaining_lim < bytes_remaining) + goto size_overflow; + total_size = offset + bytes_gotten + bytes_remaining; + data1 = realloc (data, total_size + 1); + if (! data1) + goto memory_exhausted; + data = data1; + } + if (32 < BITS_PER_LONG && *actual_format_ret == 32) { unsigned long i; - int *idata = (int *) ((*data_ret) + offset); + int *idata = (int *) (data + offset); long *ldata = (long *) tmp_data; for (i = 0; i < *actual_size_ret; ++i) - { - idata[i]= (int) ldata[i]; - offset += 4; - } + idata[i] = ldata[i]; } else - { - *actual_size_ret *= *actual_format_ret / 8; - memcpy ((*data_ret) + offset, tmp_data, *actual_size_ret); - offset += *actual_size_ret; - } + memcpy (data + offset, tmp_data, bytes_gotten); + + offset += bytes_gotten; /* This was allocated by Xlib, so use XFree. */ XFree ((char *) tmp_data); } XFlush (display); + data[offset] = '\0'; + + done: UNBLOCK_INPUT; + *data_ret = data; *bytes_ret = offset; + return; + + size_overflow: + free (data); + UNBLOCK_INPUT; + memory_full (SIZE_MAX); + + memory_exhausted: + free (data); + UNBLOCK_INPUT; + memory_full (total_size + 1); } \f /* Use xfree, not XFree, to free the data obtained with this function. */ @@ -1382,16 +1429,19 @@ receive_incremental_selection (Display *display, Window window, Atom property, Lisp_Object target_type, unsigned int min_size_bytes, - unsigned char **data_ret, int *size_bytes_ret, + unsigned char **data_ret, + ptrdiff_t *size_bytes_ret, Atom *type_ret, int *format_ret, unsigned long *size_ret) { - int offset = 0; + ptrdiff_t offset = 0; struct prop_location *wait_object; + if (min (PTRDIFF_MAX, SIZE_MAX) < min_size_bytes) + memory_full (SIZE_MAX); + *data_ret = (unsigned char *) xmalloc (min_size_bytes); *size_bytes_ret = min_size_bytes; - *data_ret = (unsigned char *) xmalloc (*size_bytes_ret); - TRACE1 ("Read %d bytes incrementally", min_size_bytes); + TRACE1 ("Read %u bytes incrementally", min_size_bytes); /* At this point, we have read an INCR property. Delete the property to ack it. @@ -1416,7 +1466,7 @@ while (1) { unsigned char *tmp_data; - int tmp_size_bytes; + ptrdiff_t tmp_size_bytes; TRACE0 (" Wait for property change"); wait_for_property_change (wait_object); @@ -1429,7 +1479,7 @@ &tmp_data, &tmp_size_bytes, type_ret, format_ret, size_ret, 1); - TRACE1 (" Read increment of %d bytes", tmp_size_bytes); + TRACE1 (" Read increment of %"pD"d bytes", tmp_size_bytes); if (tmp_size_bytes == 0) /* we're done */ { @@ -1452,11 +1502,10 @@ XFlush (display); UNBLOCK_INPUT; - if (*size_bytes_ret < offset + tmp_size_bytes) - { - *size_bytes_ret = offset + tmp_size_bytes; - *data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret); - } + if (*size_bytes_ret - offset < tmp_size_bytes) + *data_ret = xpalloc (*data_ret, size_bytes_ret, + tmp_size_bytes - (*size_bytes_ret - offset), + -1, 1); memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes); offset += tmp_size_bytes; @@ -1482,7 +1531,7 @@ int actual_format; unsigned long actual_size; unsigned char *data = 0; - int bytes = 0; + ptrdiff_t bytes = 0; Lisp_Object val; struct x_display_info *dpyinfo = x_display_info_for_display (display); @@ -1574,7 +1623,7 @@ static Lisp_Object selection_data_to_lisp_data (Display *display, const unsigned char *data, - int size, Atom type, int format) + ptrdiff_t size, Atom type, int format) { struct x_display_info *dpyinfo = x_display_info_for_display (display); @@ -1607,7 +1656,7 @@ /* Treat ATOM_PAIR type similar to list of atoms. */ || type == dpyinfo->Xatom_ATOM_PAIR) { - int i; + ptrdiff_t i; /* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8. But the callers of these function has made sure the data for format == 32 is an array of int. Thus, use int instead @@ -1634,28 +1683,29 @@ else if (format == 32 && size == sizeof (int)) return INTEGER_TO_CONS (((unsigned int *) data) [0]); else if (format == 16 && size == sizeof (short)) - return make_number ((int) (((unsigned short *) data) [0])); + return make_number (((unsigned short *) data) [0]); /* Convert any other kind of data to a vector of numbers, represented as above (as an integer, or a cons of two 16 bit integers.) */ else if (format == 16) { - int i; + ptrdiff_t i; Lisp_Object v; v = Fmake_vector (make_number (size / 2), make_number (0)); for (i = 0; i < size / 2; i++) { - int j = (int) ((unsigned short *) data) [i]; + EMACS_INT j = ((unsigned short *) data) [i]; Faset (v, make_number (i), make_number (j)); } return v; } else { - int i; - Lisp_Object v = Fmake_vector (make_number (size / 4), make_number (0)); - for (i = 0; i < size / 4; i++) + ptrdiff_t i; + Lisp_Object v = Fmake_vector (make_number (size / X_LONG_SIZE), + make_number (0)); + for (i = 0; i < size / X_LONG_SIZE; i++) { unsigned int j = ((unsigned int *) data) [i]; Faset (v, make_number (i), INTEGER_TO_CONS (j)); @@ -1670,7 +1720,7 @@ static void lisp_data_to_selection_data (Display *display, Lisp_Object obj, unsigned char **data_ret, Atom *type_ret, - unsigned int *size_ret, + ptrdiff_t *size_ret, int *format_ret, int *nofree_ret) { Lisp_Object type = Qnil; @@ -1707,22 +1757,20 @@ } else if (SYMBOLP (obj)) { - *format_ret = 32; - *size_ret = 1; *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1); + *format_ret = 32; + *size_ret = 1; (*data_ret) [sizeof (Atom)] = 0; (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj); if (NILP (type)) type = QATOM; } - else if (INTEGERP (obj) - && XINT (obj) < 0xFFFF - && XINT (obj) > -0xFFFF) + else if (RANGED_INTEGERP (0, obj, X_USHRT_MAX)) { + *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1); *format_ret = 16; *size_ret = 1; - *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1); (*data_ret) [sizeof (short)] = 0; - (*(short **) data_ret) [0] = (short) XINT (obj); + (*(unsigned short **) data_ret) [0] = XINT (obj); if (NILP (type)) type = QINTEGER; } else if (INTEGERP (obj) @@ -1731,11 +1779,11 @@ || (CONSP (XCDR (obj)) && INTEGERP (XCAR (XCDR (obj))))))) { - *format_ret = 32; - *size_ret = 1; *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); + *format_ret = 32; + *size_ret = 1; (*data_ret) [sizeof (long)] = 0; - (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); + (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, X_ULONG_MAX); if (NILP (type)) type = QINTEGER; } else if (VECTORP (obj)) @@ -1744,50 +1792,50 @@ a set of 16 or 32 bit INTEGERs; or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...] */ - int i; + ptrdiff_t i; + ptrdiff_t size = ASIZE (obj); if (SYMBOLP (XVECTOR (obj)->contents [0])) /* This vector is an ATOM set */ { if (NILP (type)) type = QATOM; - *size_ret = ASIZE (obj); - *format_ret = 32; - for (i = 0; i < *size_ret; i++) + for (i = 0; i < size; i++) if (!SYMBOLP (XVECTOR (obj)->contents [i])) signal_error ("All elements of selection vector must have same type", obj); - *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom)); - for (i = 0; i < *size_ret; i++) + *data_ret = xnmalloc (size, sizeof (Atom)); + *format_ret = 32; + *size_ret = size; + for (i = 0; i < size; i++) (*(Atom **) data_ret) [i] = symbol_to_x_atom (dpyinfo, XVECTOR (obj)->contents [i]); } else /* This vector is an INTEGER set, or something like it */ { - int data_size = 2; - *size_ret = ASIZE (obj); + int format = 16; + int data_size = sizeof (short); if (NILP (type)) type = QINTEGER; - *format_ret = 16; - for (i = 0; i < *size_ret; i++) - if (CONSP (XVECTOR (obj)->contents [i])) - *format_ret = 32; - else if (!INTEGERP (XVECTOR (obj)->contents [i])) - signal_error (/* Qselection_error */ - "Elements of selection vector must be integers or conses of integers", - obj); - - /* Use sizeof(long) even if it is more than 32 bits. See comment - in x_get_window_property and x_fill_property_data. */ - - if (*format_ret == 32) data_size = sizeof(long); - *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); - for (i = 0; i < *size_ret; i++) - if (*format_ret == 32) + for (i = 0; i < size; i++) + if (X_USHRT_MAX + < cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX)) + { + /* Use sizeof (long) even if it is more than 32 bits. + See comment in x_get_window_property and + x_fill_property_data. */ + data_size = sizeof (long); + format = 32; + } + *data_ret = xnmalloc (size, data_size); + *format_ret = format; + *size_ret = size; + for (i = 0; i < size; i++) + if (format == 32) (*((unsigned long **) data_ret)) [i] = - cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); + cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX); else (*((unsigned short **) data_ret)) [i] = - cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); + cons_to_unsigned (XVECTOR (obj)->contents[i], X_USHRT_MAX); } } else @@ -1817,8 +1865,8 @@ } if (VECTORP (obj)) { - int i; - int size = ASIZE (obj); + ptrdiff_t i; + ptrdiff_t size = ASIZE (obj); Lisp_Object copy; if (size == 1) return clean_local_selection_data (XVECTOR (obj)->contents [0]); @@ -2213,6 +2261,8 @@ else if (CONSP (o) && (! NUMBERP (XCAR (o)) || ! NUMBERP (XCDR (o)))) return -1; + if (size == INT_MAX) + return -1; size++; } @@ -2294,8 +2344,11 @@ x_property_data_to_lisp (struct frame *f, const unsigned char *data, Atom type, int format, long unsigned int size) { + ptrdiff_t format_bytes = format >> 3; + if (PTRDIFF_MAX / format_bytes < size) + memory_full (SIZE_MAX); return selection_data_to_lisp_data (FRAME_X_DISPLAY (f), - data, size*format/8, type, format); + data, size * format_bytes, type, format); } /* Get the mouse position in frame relative coordinates. */ @@ -2405,10 +2458,10 @@ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *dpyinfo->x_dnd_atoms / 2 < dpyinfo->x_dnd_atoms_size) memory_full (SIZE_MAX); + dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms, + (2 * sizeof *dpyinfo->x_dnd_atoms + * dpyinfo->x_dnd_atoms_size)); dpyinfo->x_dnd_atoms_size *= 2; - dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms, - sizeof (*dpyinfo->x_dnd_atoms) - * dpyinfo->x_dnd_atoms_size); } dpyinfo->x_dnd_atoms[dpyinfo->x_dnd_atoms_length++] = x_atom; @@ -2426,7 +2479,7 @@ unsigned long size = 160/event->format; int x, y; unsigned char *data = (unsigned char *) event->data.b; - int idata[5]; + unsigned int idata[5]; ptrdiff_t i; for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i) @@ -2444,7 +2497,7 @@ if (32 < BITS_PER_LONG && event->format == 32) { for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */ - idata[i] = (int) event->data.l[i]; + idata[i] = event->data.l[i]; data = (unsigned char *) idata; } === modified file 'src/xsmfns.c' --- src/xsmfns.c 2011-06-21 20:32:19 +0000 +++ src/xsmfns.c 2011-08-05 02:15:35 +0000 @@ -223,9 +223,11 @@ props[props_idx]->name = xstrdup (SmRestartCommand); props[props_idx]->type = xstrdup (SmLISTofARRAY8); /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */ + if (INT_MAX - 3 < initial_argc) + memory_full (SIZE_MAX); i = 3 + initial_argc; props[props_idx]->num_vals = i; - vp = (SmPropValue *) xmalloc (i * sizeof(*vp)); + vp = xnmalloc (i, sizeof *vp); props[props_idx]->vals = vp; props[props_idx]->vals[vp_idx].length = strlen (emacs_program); props[props_idx]->vals[vp_idx++].value = emacs_program; === modified file 'src/xterm.c' --- src/xterm.c 2011-08-04 11:06:22 +0000 +++ src/xterm.c 2011-08-05 02:19:34 +0000 @@ -1659,19 +1659,18 @@ if (dpyinfo->color_cells == NULL) { Screen *screen = dpyinfo->screen; + int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); int i; - dpyinfo->ncolor_cells - = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); - dpyinfo->color_cells - = (XColor *) xmalloc (dpyinfo->ncolor_cells - * sizeof *dpyinfo->color_cells); + dpyinfo->color_cells = xnmalloc (ncolor_cells, + sizeof *dpyinfo->color_cells); + dpyinfo->ncolor_cells = ncolor_cells; - for (i = 0; i < dpyinfo->ncolor_cells; ++i) + for (i = 0; i < ncolor_cells; ++i) dpyinfo->color_cells[i].pixel = i; XQueryColors (dpy, dpyinfo->cmap, - dpyinfo->color_cells, dpyinfo->ncolor_cells); + dpyinfo->color_cells, ncolor_cells); } *ncells = dpyinfo->ncolor_cells; @@ -4224,7 +4223,7 @@ x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ static struct window **scroll_bar_windows; -static size_t scroll_bar_windows_size; +static ptrdiff_t scroll_bar_windows_size; /* Send a client message with message type Xatom_Scrollbar for a @@ -4239,7 +4238,7 @@ XClientMessageEvent *ev = (XClientMessageEvent *) &event; struct window *w = XWINDOW (window); struct frame *f = XFRAME (w->frame); - size_t i; + ptrdiff_t i; BLOCK_INPUT; @@ -4260,16 +4259,15 @@ if (i == scroll_bar_windows_size) { - size_t new_size = max (10, 2 * scroll_bar_windows_size); - size_t nbytes = new_size * sizeof *scroll_bar_windows; - size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; - - if ((size_t) -1 / sizeof *scroll_bar_windows < new_size) - memory_full (SIZE_MAX); - scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, - nbytes); + ptrdiff_t old_nbytes = + scroll_bar_windows_size * sizeof *scroll_bar_windows; + ptrdiff_t nbytes; + enum { XClientMessageEvent_MAX = 0x7fffffff }; + scroll_bar_windows = + xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1, + XClientMessageEvent_MAX, sizeof *scroll_bar_windows); + nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes); - scroll_bar_windows_size = new_size; } scroll_bar_windows[i] = w; @@ -5847,11 +5845,12 @@ } inev; int count = 0; int do_help = 0; - int nbytes = 0; + ptrdiff_t nbytes = 0; struct frame *f = NULL; struct coding_system coding; XEvent event = *eventptr; Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; + USE_SAFE_ALLOCA; *finish = X_EVENT_NORMAL; @@ -6547,7 +6546,7 @@ } { /* Raw bytes, not keysym. */ - register int i; + ptrdiff_t i; int nchars, len; for (i = 0, nchars = 0; i < nbytes; i++) @@ -6560,7 +6559,6 @@ if (nchars < nbytes) { /* Decode the input data. */ - int require; /* The input should be decoded with `coding_system' which depends on which X*LookupString function @@ -6573,9 +6571,9 @@ gives us composition information. */ coding.common_flags &= ~CODING_ANNOTATION_MASK; - require = MAX_MULTIBYTE_LENGTH * nbytes; - coding.destination = alloca (require); - coding.dst_bytes = require; + SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH, + nbytes); + coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes; coding.mode |= CODING_MODE_LAST_BLOCK; decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil); nbytes = coding.produced; @@ -7034,6 +7032,7 @@ count++; } + SAFE_FREE (); *eventptr = event; return count; } @@ -9858,6 +9857,7 @@ struct x_display_info *dpyinfo; XrmDatabase xrdb; Mouse_HLInfo *hlinfo; + ptrdiff_t lim; BLOCK_INPUT; @@ -10076,12 +10076,15 @@ XSetAfterFunction (x_current_display, x_trace_wire); #endif /* ! 0 */ + lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@"; + if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name)) + memory_full (SIZE_MAX); dpyinfo->x_id_name = (char *) xmalloc (SBYTES (Vinvocation_name) + SBYTES (Vsystem_name) + 2); - sprintf (dpyinfo->x_id_name, "%s@%s", - SSDATA (Vinvocation_name), SSDATA (Vsystem_name)); + strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"), + SSDATA (Vsystem_name)); /* Figure out which modifier bits mean what. */ x_find_modifier_meanings (dpyinfo); # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWXkU8k0BAh7/gH/wAht7//// /+///7////5hFD48ADuDOnnt4vePcAEPTl7vdN5lA7DegLe57gAB333wAUDtFUqrse9e3dHcABbm 7n3qIi+0hkbPdtgMhJSgK9ooH3r5zWin2x57fRpdMSMQej609HnvO482rVO+u87zDq9Pg3ePYPiZ 0gAGfQ6oeb6rnI+A5g6DQg5C2Bau+XUCPij3y8gj3x3oAO+16HvW19dHTtgX3u9dej3mVFWbffVs Pt9bfdm7u7F2awg77Du9uNt67vd1fZqu9h1RLm3j77Hvu98PKhRJEpdfcu3BaZrVVBL68ehtPQq9 g1Qus+7rmkbWYqhePgPep7bfXczYDNaNm1r20RKPfffAe2zvC+6fJttBWmtpZSUDnfAI8vWmlqrR Y1pazRQvXeBd7wR2y0Zpo0tpKDWnH3wPj76jfY5UjsxrKqkqnLvA97pg9UusK0YlBRx6Dvr5KoN0 UACAopIEigFAVQPobYGpCJYW192bOB8eOSvqeVT0ypF2lkWHhUFHQDW5JCKFo1Rg4pSM4ClQ0uqw Vyx0JBKDS5QEgrdcycpZQB948Hbe73nvt74HlQAkVuI59edE7rnHYbwARvr3HkA+gZABJ71ASJqh lDAAHQUIgUAUSCgdGQBQpoAYSQdmFAKCVVJQEBAiJAVCooUAAAKlFQBSCEEBUgFBJXfPernHd92+ dA+7IRAqhBQDb57BpPj3D5EFKKPZgFKAKAUEgoSFUAiABCUEAIAhNAhpNMgJpNMNJqntIR5T0YSa PQIG0aRkDTQBEEIU01U/U2JT2TU9UZtU8poyDQAAAAAAaNA0xASqI0hpkaNU/VHqeUeoB6R6nqeo DQAA0AAAAAk0kQiCGhNA0TTRppPU9T0U8pPMUh+kjJiZPSDQDQeoB6giSIIAjQAJiaaAE0aaEyE0 aGpPCHopqNojQ0HqfqCSIACZJEimKemmSeUfqSDNTEZADQAAAAAB0D/tqRPHgPrj7PShRkRA4ovl EFbZjQSDaAFEAZBSEEPtFWogqyAppgEglEZFqmgIorig/COUf2lv9q/8f4NIQ4ZORF4awFVERRYg LBgkEGAiLCRYAsFIwT9VKLGMigjIsWCxRRRiIigsiogKAjERRRAVAVREVSCKiRiJAUWSIiCiLBSK QYkEQYqgjFFCKyIMkWKAkSRGIgisAQWMUjFZFRBRiIixQQWIKIKIgplsiIsSASDWirFgAKQmscyE ioqKLIpEYjICMUUgqhFARUVSRYLAUgLGIqOj8PZfNDummTTzd/3usK3+P/fThDY1Jv/bSprxP7zQ QjA/C1261x/VeYT98ESH7P/wh6Kge3VI2AbJDj1/Du8P5P8mR1P+DMoWr+3Zw/asRSDAxFhtL+79 0YqqV2DYWAaZIlI/65E6UPzbIb0Yh2uyazi8dngL/nu1JxHgo7sPkyJCiLh2cYqszybW3n4df8vD /f/i8U7/85eyrjlcG+1oQhtFQcZiEBgVQUkyqqr4Zz8IkvFmOtCy93j5KQk1WZcdzu0IIS/1kJoq l5KshJfHw+j067vn2O6d4u6Xfa4va7MKxtp8c1k63fSlrfG9pnm60Wdy0T+eXBPC3wT15Og7a7ui 36f+OJ6/QGEBkR9UaiJJJIgxhqooPAtBYDGKg/SlVATGh6WyRFYiAjBERRnzh7x9mX7NZmrpOO29 K8Upr60yQ0gf0H6tXFZYydNGyjN2GGCSj9csPEBTGHGrSuwpNlmyCaPj+UnYt0ZUtaW6VzO5Yq08 a5+36t/Z7dsewSCUBQgKQqdcqMiDEPSfZm/Z6uNTTRZ8iFOzxhYD3f/fvn9769zKwyQ5PTsckE+J /2YpxTB/yID5/X0z8NdDU62bI7R1Kekhnx/j54pbjZETz6Y2I/9Wu+5o2DphuufJyvvjpsj7bSXV cu3rZPyOpu2ss73ohYGLNHGqppjPusfQ/rUFYAsCK5r41NQ/rzE6ZqEgyW0z1auJMsCnjjQQH2Ep E44rpOyXtJ4R88PI9R17rE/lYqR+Zfoz6emXl5LN1NdhqUXzydOzXO6Q0TzL7AZG3nNZc3M2tcvK mzdyNEocsuxU5qs8KXUL3r4KQ8ZWGyyFXSJclqsnLmHVsdTBOUwg28LMnIuprlB5ACJ0APBRF+W6 z3MM9dnu+coKC8K8JPagaYcG7J7kOGOUkqoo6vwTEHjvnHHOThArTVoqatlQ4QNMXvs/z5qEggeD pFctMtZ9aBeaHXFKwrpiimJpCcMkWGkWcMv2d+/1b2zva9v8eYqNukU9ckIsICyBUkDSKYoxOmq5 SpLWhKwKzrWg096dYHgk64ou0xlF7LYGMDBP6UMPKmk6awrUlSdJ4cUrNuIQtpTvmctSdnlDhOmV kFWbZWKooGIVix/Raqpq2GmFYqxTxSsFFI/hYFdW1IWIH0/H6Jfn+PxTM+k+L7IOin541R+sbvTL stP1ilu0riluspgwtme8u7e7/AO3/oO14Vrf6mMj9Yb/yTP12XTk1+6pXGJ5+8ry3LWvIbxyvmyP 4+JWGt/4nZmfUE5ivocW58fqYn9APodr+A2v8QPsSeR0VNKD8lZfBDdoSMWdqewtldRndllb/uQb 8Bm7svTV12ZdLu1pUIOsW3fDd3XX/uGX+Wp+4LW1+F2x+mPyDr0pf0G+Ca/j8l3J6nguLI/cB4PB 3HHHzmoat7F08nKxm6hwRa0KkLjw9t07gpmd4i5zZ5aLF8nlVsw5rJ07inVtjhW/S+kjH06n1zZq +DJo96zk41l73UQZqmyMNZTPFPx+H3/1FT9aBuNj8fxf93+U8BxUQHqWSQiYmotjCLHGsJeGMSxs hi9P1w+2FfAmrZ8yxU96lP9v2fTCQ+jfIVcsVOfN36G6ee/l2/XemUKDpNbvWLWWpq5i7WjnzZmk REusrng4Yatr0/Nqu8SRUqSIqXBNQSCFKWNuSjcjGEhwVCXt1h2cTZ8eJWTvSk+drso1cvjhrPq1 dJxtyoYqNtG5nCV0r29h5w1/vYHz9lpfHzfU81/lYaX5W7Hj48vhR1yc8vnsnGq5sdm7eTdVXWST idDAYJ/GR8z+xy0YOl1bqLiv5o2csfZMiSDMuyRUhv8li6E/M1DRuwrJYIQKISBhkoCm/DCou2UZ 3ZtVU0hrClvOSppCXNYTE0lGS7cxaysttayUYgWU2UBYMmD8LyRJAtBElEP2D7uzv1/OMm/Ivg6N bfk634/PXm1FYootZUULRpUWRZY2pYsRrEaiI2i0YoNWxEgqN9aNtCra0o2ygxYvn4a6T9Dfbma7 enmb1r3pJA0h+5hWtW1SjRJCpUKytbbWSUpQttalayHuEoiMxrUrCSdeWzffx7Hjt64zjco7cH4b m7tjJi8t5t1E48KsTJDzby1xLh2E8jT2mb7ezhQaq70692nr3ML251z1q7cus0jOHVZ7snBTdYJt 8k3t3m2qNU22becKSE7dNmame5CqpLFtdNccd69pPZ6+0ul8PXWcxjHEdIN2+yMN+SFCxuGunWtc c5r1deo8lRQQR8rT4fPmk0t/S1wrCdU/DK3dnMhAA0R448cd5voOOWxpHCC4wpnsST0SKRTpnSGM IoTaFQhy8odJwkNpJjAqGmQMYQOmThmJpkhtgLOOLj6IKVxIYwxxnTAxxhpk4SG2VA2ysDswNptC SClZCdcu8rJJyhWcbuMXSbYThMQD2oVkBYHZqHLiAFSGIsi6vOEqAL3YGJwnHVOU7odkA2wOmcoH PehicRS8KyoxghpiGUcYOUUQtFC8QdA5QEnuoXPYr6/KzgwYvdvh5hZ3s2sfqLqrScy9fm2LgCCH 0/byICeWsuVTJTbyGNoKDAzhh62YhgmMLkz0pNQ2yQrJtiyGxlSVgs06VgLIno6VQtcA2xERmIJA kEZX5/o+cPl6fTaE8RMwfoMoLaQhuRImtoIa6u6Ss46ufqIu8sTN6Xpo4dPZ23k3t0wiSxWzNrGl V7Yqrc7xdkGhebtGoGPamLGVZMojjPS+sJO3hkizXbWXXVlCZem1RO1WWcDgzPOya5U55OppOqo3 tzdTrWijrd8thbj7MXHMmtjlQzLvtCa13ObivS8c3dokFsJpEX2TT2wzU7ieZcn8BgSY9I1jD3cB FGIEAxonPBULUuLuQsu6asLlNVuT2byuXGg5lVWISr5Aq6tZs4w7y90T3U96cumJ8BERl1WeHEd7 ZmWKvERuX5dQW4KHX267QyaFSh4jiHUr13fidRtbXeNRhE26l7gNVdzYiTt9Y2pOSgRRPQqSnGne cgSULGPLTxcpR18uLvneuZXGrxKqE63qDvUUcVJUNd4RbizOvOu4HWmbNOlk9Y6UMuzkE6KBkdMn cOVUum2kneHiIq2UbSwM6hcTXnko+SIgUSOyqFDx8JzasdKzl2ZTynxCIxezweJLKcaqKAooIhFR unw0oCIkO3h4LJo4oUF+evuA6Yu2hgGGBI4x9sxrNyJlXHNPNTa1EiFaPr691bt2oNZq1tbPpt2h 6n0HlE4ln8SQkCTvD/i/G0BYsS37sKMFUVGIwtgUFBVikFV9WZAxBQKlEiQYIMQFYjC2gjFZGRRB EGKxVjBVdWFFREVVjBigikRYRZiSqW1iyCrFRRBisUESMZFIoiCgiwYCxQEVUFIgwgpIMQQRREFB WMjFtlYopGCqS2FhMymQDY0ylj+TWIrFJjCrBBP7bRMs3MmUx+0D/Wwku9RQ+dCswoWMFKVQwC3W mExIBmRQyYKQRy0dx4HfPDuzP2yAp0aGxaxT/uRC8uwZQXqoKQrRqoiqqkQVrCiPlSiKqoqwWMYi RgxRYsUUVZMLYKKqqRBkKpQtbIqtqFlZbEtBrCqkIKALICqAiVKqMEGsoS2yFSiwXMMkxSq0rUVW DG2awmMwtsPT6z7v9vB9nh8ZP9LQUpx8e/y+qf3FxUzqTwlfn8HPwkfJuQgB9w0Py+w9tRzcqgdf POOiZbGGkpYTn46Jyicfs9lEoOb/bBHvTENFAY3/oPAppp1KY/UEHPrRi86f/FU8CpoTm6EFIs8f vT8HU/pi/keKmiQqf8jEBojIcfo5gn9R52sB/RyMIXUEuHcUDy7HQEc19uC85znhQaxT6ZGnEcRR yivoLJxGiQuT+7zUA48Uw7ewsDnjyU/3qv/LwIIMKomqUzRsJnqRGRTY/6OXTtw5JI2v7rX1njSd HD/itfo5CnQmPhusceki0bJaM7q3Kngiw9lYSJrENgIn+kQU+7TkrDjrxz8SZKd/f7PdWiwCpobs ef+Kf4p4LgPSVdk2CoKoCg4h3UMJIeRD0ELn/r3WnWBUyrXNMOi3Z6c8HSGOjQqeiDuyRj8LF/M8 i8yCMxckxp+R74om2JIemmhkax2TQ1WdrfKjtglog8+NW4rSPttzemVc7IcsO/rrFbX+CPsmXc9I JO4w3wHd8mOqkOnZRz+5a+4aDqwhoDoptOS5RwvR2hMI7oYhA2VTDqJQdO6n/YYPwSdfwYyqjnw8 nDU14J69jOdBw4DtqbqEAYFFGVDuQdICqkZN0Yj8zseAopLBLK+3uxCh9k6i3DMB5Q8lXfwFqLAD g1KdBggByp4fXXxTx3LxT9wutoh97kFox+MGPyKz/j8GsNOzEyylR+6FP8gJcvFEOwCv3ftfzXF2 iJgptNP4eFCQhvz+SfH3d0T1WTHBRBBRns+qmT4O+/lu8Cg4+tSSGFHMp/VAgCZMepjeC+eR8do/ lDnmga0mC1hrMC3fjidl8EvV7LRQZBZvdoaZVWadZKp4G8MVCG6jREy0mp7SwqhhWbor8fyKzx9X YUfJk3F/ZDu7Yy55/0nKTgv1mgaT8w+sv39XBrIurX0yS/sBj60pMKV77NdP/GPh9nq07UYuwVmM fkvgpVmjvB462iebM8nUV7+BPKuGoo6pJ5K5CrKpWQpUiL847w/dKB3Uqfj+nIx+SJ+asqY+JU+E z8yWifLJkOO3RWcVbZRcHUD8Gmo8jlj7e24X4tOrLBG0X5RMZvlyJ2q+HqVEef84AE+aT6krKigp KkrFgLIEUUBYRZAWQWFtFgDaSsCsiQkWKKLBGCixYKQVRYCgIiiIKQRJFWAsFBVIsYkFFiwUgsUi xYpBRZBYLICqxBkkGARBFgIxRZBQVGEUiyIwERYoKjBVgIigoKKpIsiMFFFAlaoyLJJBSACyCgCy EltVSLFFFkUWK2gUYsBSCyCMIKCMWCiiiiIqxViIiCkBViMUWRQWKxgqxGCqRZBQFRiiMAWSRQWE IjIIodT09VT/2OnqgYMv+Zi3AtBHiP80UD74SRQERBL4/D9D9P4n8YflD+j/NOtJNF7IDzKNJo2t F4xrL17N1u2L876pHVQ3uF92zt1qo6m06ppdl2ZsXOm+nM6qkM4wZqk82tLmaU3t32+BD93p2HMg 6DIgEgiSSNCFSCjGRWSKCkMD18J7v8xrST5GurFVFiqorN0dgdT/OojKg7GA03Xhhd9+EzpX7X6Q MR/gRNeTK1WZzIU5/gMkVXsMknZJaqzq6sLCbSaUfCwKLL59ATNwVEHOQHU3xrCIgxjo5Y2QmGjG JDTBBEkpWlVqLIlv0VNfBH1+qJ8uNwsFiJInS27zMX+3jI0ctm7J3wlY4lGp2Cj4EV8UOME0CFLd mHnwdkJIBmD5DiMu5U5lJiCYq9yRhAdKONkVqrUZfSPjiepnjG9TiiKIuULBgg2eONDLNujbXYos pTTTi4lrdQ5l1G0DY8Lm8Fpp5oPZ0ZNSoVWl6xWpVSKm+fX7WmxFPFMwFnhVAghyONbZzBojggOZ MWoojH1yJ1oWr5AxwRmQwFqo+BZESRxfwRIJsHVLQO2pMVpUWRm2x2LgQzaTvmC1hTCeeIqYnEBn pPCfHxskjCM5ac8tPe3piij48RhdoGV0oYQ2fQXTW9zlqC51jyHV9KyM6uGkSpqK368lQzN5+UYQ O8BL4MAJcvlmw2vCZ14uzePWM6wjSub+gj70jFF149pU7IRgPEAHUgi87MgZWVZwklSjgmZRZFwO n1x3HGP7H2d7UMMJXYEpR9ZI/stdohexCMRyVLeP1+dmR+b+Tq7IYycMB/gUInzuvWGvmvvLr3eJ I42bSjStbhlorT7U+p1tMWEczN68vWwDljpE5r0xpgIxPZ0xpJg4a1XqKtEzrG8hDoOX1S+zsvCj KQwc3utiia1ySR3ItB8m9sgZYCsgoqYGvExst43cRvjiHQtxOnAs3pN9vo+iFpQeFANuC2+N1ULw vRelmFSVWCGLkDT3IG1Egxeq2okxJBI4jNR1TzWKc1lgKZuQLxqpxIIjXmZQNVl5Y6VRw9y0hGpK ohcgNL6tM2dqk3VudVGNqS614wlaKHYjN74Y4xrp8OMkhmEBy98YJc35RqHipF0YyGQeAQz1FRhp 5uJqoj6OPH1ff58X2ddKpXgjgjtVDEDuVrt6cQQQ3j0Xh11ajS2yJjTsSEQkSgQWSWQlluXGFusm kIwjRFkLFGEGUJsIDwwKK5RhBwLsCFFDStcCYqdfP6wvfvHRGgRZB0GG35PQKIWGs8xjunn2LDhN o7LtOd8nU1By8vIg8gKwb1RXISQcU3gY5rQQCRuoOk+VgwcUWTSiSVLZ48CwbCQWlAVwUHHalUvi Apr1CzhEui7J62KMegxPpdnCMMXSEkZy0kxkrjEEQdMaCBpNIM6btaMSI4ahIMWtYmkLt9JlDiCZ O0uaEmm2KxYRJiiHmVIDBDIWq25mTRNpSqstgE3NDZJl0xlapxXYzlRf2AfQIgfsMQBVUPcFuCOH YS8s8TwYitqzvPyyUT6OfoX4IXeVUeW2UgEQV7XrpQIPkpopTKC6yR4MstOo8G2u3cxRRw+Is8R2 qTxfBQyODUTxkbMmCcMURxFECyLOmSOpSYJZm0FaHHpSlCrx6d4qyjREniBixhDFxfjtzwPFGiL6 2Fr6XMw48Y0LmjMtiSCSQ/LGriymQ1PDgN1zsAI771jngrwwOjHFcOg5+n971sUSRH0z4dIN88Mz FUJ77gto0CJkqOixEso7Z2TArc31Dd2HeafkYQxDCY5DCHEi3xOLCNhpHSLLPVLDI1qEbI5hDjJO 2x19tfl8oiY6zveYZVafJ3Yln2GVcOInM050qKVNNe+dO2/Y2MetBhsabLj3I8ZFJRPFRNoSVS6y y9sS9Mm9wMkH5s2f3B+MfqFZfxweaiA/DtwwXhzCiFFGIWBZgo72yWTyFgUoF2q5CSNCKRnlEyht TD6bccSRlmQamzFKcG9fyEC169T0c2fEK4gMQzUgFkkZ6cI0EEsiUis13kg3HjJG23vJ8tNWyemD qCxEyXiEBGSH1TSe2M5DLEycU1DzGGQ/RAm7qsPuCzvRSyDNPjxHGBhgURj7FIswSiu1o5qBOlHe QwgWeaDOlWEjHcpOnDVYqlEkYSfW5UhGuQqs6UdPDAsuj42Bk0uTj4wG1VXhiU3Kh9qFxUUGOpDu XEUeui+5BSpI/V/DH6fo/UffO/4t3/H+5kfy5aLN8D2dvstnKM8iL2/m7dqS9c7Q/OHP/W8j6Lka tcn/MS6EfV7AUBh11L+K7r3gerUEat5kagPNCFYBluG57cEY3h+BMkmhRmcuLx2sOS/abkILmqYY bUCYIiOZE1Zhfh5PlCUD/tD2k0vzakMg6NJVUoNT/VAtX9qz/hfHTOa/d51seCtoKaKLCc1SS++A mkKFsUpDa9FcXl8l+Z+gy/9LVm9BM/kdP/Q9RTkWoCgFII1Cz9dND+GpRS0QHFc9FsPGu/amIJ3l Axzt4EUof2uscZyu3cjQ7Nm62MtLMkarJ2d/PwMSnNfNojtDq+ivXLYJsGVmlA5WSvdo98jyUyGw 8aaq9EY/vVrKymic0yrK/hr2vloE0fJhTIVFVEMC3XDLw2XVrecrQXlSSnTvkOGOGV2tnFwc81aT cA82Cu/mXiXv4FcvfnvtUJ+88uPn2mLl8CUvv/AdGT8lYRmVk/IdAuVx3cP/5oxxPyKz/LipT1Q0 SRF0xZEJAJbRFkiXj/ZhqMSJGEikRRjFiARj3mzWXTidmokAk7wQOo79Bs9DHaaTSO5zARiowS2x BhDGqX1/nH9+QQuFCGy0GYYR/Ed/5icGvbRYYWWNMwITB+1eaitmkGKad/iMiSM4P+zaAweNGTEi GslU1jZ8TTblzQjOZuClSJXtbCKWjvSG22lkiIgnbwHBy2asVMe/I7zbw08NIGlP3L/OxyE2xwWE JIQUojTVu2aIwcdXZubtBcZQQQB1tp/C8DqSkGa5tTreKTM2Oh1g6QAnhmYX8zAPmOSKiREnBkkD KOqQUHaXmLcdETCT6ne+YkpNsqG2IuaKqimE7vCPjHDI8WhFEcZkNj5IQy/2f2f0DxQhOm/bunXm G3Vpxcmn9HuIQXmZ8RqII7s3YXJOYJNNYk0yVBE/FPsk1c5i4UgmGTIYZHMZ6dkyofuvRuqat5En Uv88H8bMDKJUEQ+P2D6Ij3RzUWgpM3aBghjOAqxS27+3xGidlaMsrp9Q8SAwQVOpPtUUbWmhn8Ix LjcSofz1YfvqfNQ2QoF/Uo+sUAIijWwzrXlCFA9ZDMsjABwlI+DEhmRNp3Gg5yun66wU+3MIqk0U mft4Oidu00smj/wHhzyuaYIdNxgOS1F3qRIHgpG79HQp7V5rL+0fAnCUldRTDKGUZkyJJE0N43dI 4ZJLyv3ZJJz9imZX8onbW/E9+23ZvjWk/Ua1gcqnqPbvlmIexzbgZEIFED2E9sogrJ9IgukPQnYM fdNYKk7qThcMD2GukhxBNj2nz0yho0mkTUwhvIp8O5AwglpIPPzHCKIqQoKSbLKMmbcWdTryMz6A 7cn+tn4iN0OI5DJ8ZsKvwhzEFEUB5z/AY2aLJM+stVn9NYmASEwUoKfy/DD0qD5Uoi8IGWIV6rpM +h90zEm8EDHuO8EimFVbqzyQho1maUkUidf0ZEPsjDOlVJxU9qdrx8SvTQlORMsmmPaBBl/KcDw3 wyOnUBzt6d5bRo2dChi7k8scT7i/gbiKSJ/n2E63ccyFeDcLpYt6MlMjZUqkESef1mA7ynhXtAKw SMhFasHRVHGD8z5EhHSkglDyT42T02x4EisnUOvE08pjjPB+DbEyOBFRHYaw3GMMX8yJ5HPS/p5K Q8Rpa/SpZcyt/efnh7xkFkCQDQercm22s9duRNJoxxMJLxJJHc81Zy4XIYfBQ+1UiJghGN8G9r35 NNXC2kFey+y/GOg4mZMsOlWS7H8HQaCRNggHi3QsRVRYKW+GTfKDpBiQTrnhIsOjBnZbDoh8BT0l k7D3AkUY0AkyHr7qFQiaikggjXeEBocm8NiDETpmklx6AIhuschdb2iMiSL1xHXiXbEg3nErpixh CCpx8nFyVvrLTlRtORChLwwYsTiSMhTsQoeNzI+1IQgMKKqeGzn+MNN95CpBBJKIKoEPdF4RRAn+ pKm6kic5rn2xu7N+fh+6fX6pPfK2R2Q0IokMk6hC5bUPsGNjvRdtE+BD1xmW88nJwGCiOmUQuXGe yCfLGFD1l4d7lA0JnQPR0JaEPrNT14HcQDsclktEpRERESCFqWorPDuTcSL1ajKzpQHkJBOEyRow VT7RR45eeZiVu7WPfU2RUyFjEUXQRvcsFyX/yHwVIP9e+AhdQ5RE9sI3EK5zXeCPrOhKUdVAhMv4 +yOnm4o/P+aqpnPrbydDLxknpOEcCJo46sf61nQnaEjGpfqXSwyIx0mR9KBEKpwEtITQVwg33Oxg 8iiMCjir6GD1rCKZVZHF4hhpah0/HIBTr/3U1hQZtDlIs0LC+lksDEbShTvCE1TkJ0AWqeKIKkVe Fj1aidG8zteXoLtWyBQsCT5dvRWyZPygjIqzhIUcd1MPVzjCaQyVNd22Tqngh0oETyQweJYEQoSF WUan6OphA6xcWx33nRj6H+k2D9f68bMhfnImJkwSgyij9fJlbwQvLBD8v63PRPE57TXgOokcvy+W MUMpLuXFbY2WSeR+8lFmgNKUYnOf4kkIVFRqfCqsFr0VCIyE1iEGkzsszg43sK6xnDWP9w+L3HKA s2hOPp90TWoxNfZcDUIDkEZmfx8WcVUE0yDPV6orMyoUPF33uABLsZ4NktUKo4jjX36t1UuOzlAz sQjvKlfu1nzVK5tNh/oeMEFF8SIxzEJT5VqwHDM0QiiKG42VpKI8YtF2GVh3dQ/HB7j6kKmooaKW xbb2L6aCr2v4EywqlZi9bkJFf5paou/oezUoCqoLAVVBQ0ZhKKhRBQyEZTj3ZDCwTdNCMSZqJS+m GQLEofIyJKj89UXD27FGhrQh0pJMOQVqcnFPVokWdUrEmotEfyBvvebD7ZeTP7Q0/8GLt/WaP4JI QrEvjnGCWYyr8UO855G91dhmZgfyJC0AIi+nUzcoTJMMnDPVTp6pB2ldHan2KzjID5/Av/DuHZGG mAqr0lMlnMIhrRYfrZN++yFSGkLEqR4zA4QKvFogbSis3MoxTCyGmSsmoHuvGg/MKjDAVgQAg2Is hTZqxzd+vkPiZtnOfE0n/OFi7+lFHU1Q1BrLo57jqAjgVzpQVa67j9I+pUj4kygU9aZ9V9ifks+S 6SQdWBUoi69y6IEA8jZ6JO8R+tlxP/V+V1xU9KhwH7aeP3fmKS93dKHRoIXGCB8IG4pEgN4C9DI9 Jar9FTsiTyMLN8jvHzA2QZ2OC25PBHrn+n12Iop5mWhUL6A6I7mA4Hicx5eN0mgMSEsAOxNM9Qe9 qcSshx6M+3R6IiH1WFYoIdg6v03nDlN23FtDt+N9EJRKkoqawmq5SS4QPjx9eh9XGcGJgOWrErfz 088msbKVGmZTO+XI21ZbKiK20E1n+oHI78j3wPVPP4U/NvWVF5+p4Jkd2vOuMMfmvzPuO2l9wvd5 OdxKCqUDlHBRJELeh8xSOKwexRU+VjAEpw2r2k1yv1DIGTIZlo9ibhVihxZWYYITAgfDYwzNtEC+ 6GgeBQanDxFRGaNJG7VLTRjzV8UUUVNNhgZzzR1SaVHvKD9ii6kIVpipWaIUmlSfBJx8iIwX973S lS/3HSSQhdG1W5dqs00s5AYEEWlheMG0LIMpLKXViiNxz/fEBwaBF8YI/KPzZt/r4PI/4P4ZsE6T 3pWtPNWz3sDpFI5hxrWzDYCdys5M4XjU/R8hoJrYcgfraa+B4fvX/KBT1zKVtyYJn71IDiowvV7e 5YIirAZ19yPng+NF8uEHunuDEGNSh4jGRIoUHBQamEcWhH1PsMD3n7kUREPekABMWayutAXPIZNB FFJRhadj5rxWBJMjX0MUCc0GM+G/CPMUIfLZJDO/KbsXvhv5TU6rPCPfArwww78IBW4drRHCEhUV UT/DTvSp3PcaG3qtj5n7TPGc1H0P8NE8hU4WJI8AhUKKrvOs4JOL1YJkST5d+B2nIIcdUPvpmcQ6 ySoqH7YUolJkijrUZKrIOUDP5MzLDI1HSd7pGm6JmQNUJEJE6rE5OSWdQaQMRyoa1UWKW4PcaC54 EgzVkf2Wf4xn7rf9pf/UQLiP6aX9gH97+1+r4f4vj/M+NLCGJCmv7lKzs4NbpWv3rx5COiR2X+2d 3Ao5trqXESaUNzR6ukekichPCrNgXkyhJTTx9tVglUGF2GTi57uVYXZcDLOzjek5bs6ewk3Vq22+ K3ZW8XOouuysQ2u+6RAiHAsCoYC2NAY9FpxIosmSuTKqRBVROViQUiKiZUYjQLA0wqOOjkicgo5U rUlBBGCZQoTIB8TyU+PyWiiKmUrWqhURCoKLUVaKiIrS1tqiq1qJbWtLairczBEVVVVRURVRG5kr AtEtBkGS0UqFoFRke7UqI6kV9PePDtH+x0xpB6a/XD9CwivP87vszfohD5/3bEzL+232Wv9/6d5R 5xvll93pa9/THXpWONOz5diO0rdfWxpVumTdF7rvH/dlr11s+Xtsr86Zf30v48W628JaWgs1F6eV MorbY7Xffl5Y0tP3bR2yMd/GPkvlbWel+LpCatrq3bxaaz62deLW4n5d+1auyT4rOHkvFGJ7T86f DiK9n9zu/PSPmvHel44HF+D5M637xPPRbbbggYx522+edrvJE9avqT1OXUdaZ81Hdad1EVwLWe5f lX4rqO+OO9ajiOX75F7qF6rh+Z4547g87Yxw/T8X3XG4s7D61zfVw0R1rleHwwt63Pa2LjrdXaGl yEtIvoY0Va5vppP4p/z0PH3/T7/0/+0PCDJU/QgggJl/Rjz9OI9Plz5en1U9fp9dtvn6mh5EaQqv y+X11tb29+XT6fD4c6/XXLb1yurDp88MLezxw8DwEX3/0tQyFkGogf+sAEP/MCASAqj/ijBC8UBD j/vVt9P76GqKfYk7v8gEECLIwP3j/qraMJ5sxkgY/rwqun+PedsWSQJEy1zKKPdf1wqB53+agB1N Iu2OiflVEiSAWIKnFAP5c1KpVslKttalpLVRa2ylpWbZFkkuWQpaQkLUfbgZlCAaSBMcZMYaYGjS Nkt/lOc/1mw9yBMOEaUqNIFRQbS2kApaQpaQLaTpMMRRsJS2AW2ElrY1aUqNC1LaNtpbSlWhS2SF LQtoW0LbDuDANMhNapJSqqrYfvEDMstbBKtk6TMoUtk2qIIZbF0klHGEFAE1cQwyhDGTFyy1bLaG so5QlqKLRq2WqlBYCWktslqLY1rbbYBicIVkmkkTSNtoEqCyAloFYlWl3QuWFLbbJLaWqtkLaHAg dnZbJJs2qotrS21VYxVpaqqqKCiqKKNllZlFGb9iBp9/6H3OrRinQ1OkVh0HjB/9EbFf6iSH8FnU njW3+EJyP9nt+Mf51xpl+z8b6bUl8V6Hvjec4dK/iXi8FVieea+I/WLFftD+ntFoMuL2a+oiX+c3 HsX45/YkQWvVfJ8X1Ve2Tlf5s52SCsnBKerQiGzRwuJS4zm81ibDIYUP1rFYc9/0rDxkved9CQS6 QeEI6eLTjE8ZTpCM4d4P++XbznEVPOLzroucMrT6UzlS3hL9dIWoOZce9/MzKA0XI5djVvcvgoWC /bi5pJlM8qegkFVeujFZteckU36iicUqfsY1qvISaoa48IA4wcb9XsztDFGnLox/NHaG5pjf+JfI NyLnl5L6FiU/gZFFNv7/vaG0z/syRCzzocZhu5XDZCNWPfpt1xNGuDTy1nISjWHL78DfPFL0QO3b 20CUGZdMvdCT4fbwnzG2/FMTssXt49Zqp7v617XrwuS2Gs+zyX8MstySxzvJPDwghDO7e/epiE08 Oj9V/ri3v4+7IOrHe0P16VhBBiajMvWr3gGZ5Rc9f4JoxtCP7Wd21vnjmf7/R9SspQ/FXh/0lKHo sdVzGDo32jcCxE/YFowO20QM/Dq86rvluRqZeyz9zL9HvtWFdbi5mS/ePffOhOSmbRRqxDb7UlT4 R2zHKN3IP9neU3MjSU3uXvVXqoSBicxqaWfg4UU5L/VDquoHCZNUBlz+yV+Mzu8Cx/Qqoo7ixoIe 8qq35k4w5vbPN7iE5dLxQciBRVD8/mGPFwipHV9DnpYyppxlxWUxxkNt3fJji6mGNNFcxJk7L3kD B52FJDceg6uNv3F8sky+XFC8oOf51NCly1daTSEhZijOClmdVXyU8FJLmpHU2d0WHdnk/Hs8THE0 VttJaJObDQhhfiSksr+o/TP3QTIIK6XepnjoKMcXb+S0flCVC17fQf2+9V0SY8Wrz8SKTX1svGLX yNSr/7vlX48JKWQorY94fIvz/m9arfRrP2rL1aGpiLP4Ec/wlHH2NJL8S+/ekqq/PqSNJ6c18Esh mv1mGJi5NNndeVN79HkELK2PdW8t8TjWsXRnT0OsqyrpQeNGTyNpSh1UkSap1ymfKZH9gH7WQP9A AM/gxP7kaWW3+KLjUrVVWot/lSpjVVFqXRZVVFM3/kwzdlRVNrlMRRRTGpVRVuBcRspipiVLhSqz EchcTMhcTEqXKVBtlu2ATDEUUXWWqqYxalYsUUWK5PgMnmMBVIoCwRIoT6xhWQIjCGIE7IcaNGEN CIloJpiGERcCGBAU0wQkBP3kH9kPAeKcu/q6MsmDO/q5ffnZnor07OsLHjLZk9mdfafPHXH50ssy SnksP3u/1SQzVx5q/po8SsR/hj7fiR+dGfz8bZLFZdbERmT9Hg0Dox2VB33czuvm+/7/3fmcaywu mj9UynlSOhBn9ycpSMYqXX7DzUG8FZLfGfHZf6qHuevu6X/m3iX60Duqe5UWCGa8gv4fBKv1Odqd 5S1Xs/4HkPIFIniLI3NPFPA2KupkqUFWnrcZCUHgoqcz096a269UBGFAgA0GofzwA7VLEkkkBk1k fdKfzl6Vf0JuGUhSpxuEFI5NGDp9Y+ft6xtTRP3JBBzX+D5TSOvnMlH+Q8JkvHOWIcDhsqWPJWoK evEih5k8Wh5VBueJTPr4PlnEPOyfG40Puf1uevDIE9GBOrp4dTU98i4SoqQRzmOaeAdSBxxwLOdk /usfstrui5dxRq2YtSqz8Z127YqlfPFK6g003KHCVBgXR0n8ArzN2fty5+K/lm2DaHdMIX7uGe2/ GjiQVOKCSLxk7eNvCdA6EPJIUSPU6V/nOUn18O9oHHy+cExTmaTWukuqzM8WQorHr1HgeF+opnFF GE7p0TKjJGSP4mw3umkzuHQ/fJJ08efOyYnebsfQXkPYXpNvJj3pZ1WcEgz+PTPP7HRwrXyAqjKw sEUcNGF022+csHvJqon/goF4B5ayzaLzSjsuV6Ia+Q3WepDM4Hf+3SZEO41vG95oezWGZxa5MAuw jk45DrbPSGh+gfKIp9fyoVPvirr/jqscp2H76A/x+oYJAgflEkdk+KAKYf2gyhSQaRo/jd/8WR+I cgvOQIRUR5wRYBQwVgkAgQABEkEghCIkkRAQQ+0KCShO8nwQwC7xVljQYiRBgIyEBUeuCCN7UEhK YlIKIRlpcbNCivuBWADo45QviI8PZynGlVQNkMUQxEMOOI0JMEc0b4/VHEOBijogOhHTgGWaXiOK MuCHMKYI6NTs5zj8PGFPtCAjLN+1UXc+ym6w+KddAfNzl5JuH9p+jfhuUQ/IAgPoZjlyIFpwzUV3 Gd2V8oK5XNRLp+wb+JX1ciPRviscAwR2mCcSPmBZW85wXpR6RMxD4UA5iuoTsAwR1qpq0GvFHGkc C5dHAFeIFdZZHXI7Mba7GYt7RHmBtWHeCuwHaJndBVCkcEYDrN46UbIwk1I5ZKhhuA2G5L294K4m 0C6OautG1slGXDSoX2nWeo1I7xXJI0Sr3QQEsJAuIh4efPZ2FFFPQ2aBwwdGaQfJzDDPdmIxDDsX MGUH+5FDPntRQRUF7KyDWtGkj9UytBk84kvjBHzVvEXWoyLdmyz/T4aNnYU8XyMqLrDDBmB+JZ+f De6ao3vgUAhuhAweYEgvpecyfzmDau2iFDJnLqAUu0fo+VMyaSxFqz8P2L5Zmy5+AYqVDa6W5Sv1 uatkSpDVufs1/fxRH1EaYgDiZQY++h+4R/A+UQfy3y059/80eORK/HOLAgOQSF4LMPSkhuipJIt1 ZqUpHxjJ4M1l6PxhluzXx1tCNVW7DuyjHdt2iFLrjKeY7d26t3N/LHHSvAcKuiFDDGKFIWOcGV1g zRYr4wzoVxA1y611lMfVpq2XjD+pY+7mnhn+9S/Ux/wFgerc9SDqMilabJGCqkfcZGqREpKrjZN5 Ox/TZgdPQZ1c6Znj4+faZP8xxx/VNlTs6jH4Kbish09j4/WL8vB5x+Z7orSE3IOr0WBSEIfOjEFJ /R6SIvJ2rScqTaKupH7s0NE1TxDc4U954w8SJNJB5HvaKfIkSRZJ+NipCyPgmQskmdCX3whkSB6D HAlQPyxH1+0BodIR3NgaUjNgh3EoREF2W5n6y+1E1e98xm+ty7M8L448Gdrup4kiXHKrrRjgvHc9 kmBfgq/XW9QL4Zlvin0dTbMyg0J4wNu6wlqbljVaXjJ56ucJCwLwJgQDYRFYXBMFQwGygRCIIYXA LBMDQkTAkFA4LYEAKCViAoBwMg4rhIJhQCQHgAEb3eGmc97jW1g2bazdxdrnbOCzKwOwt7M7O3ho uUJFnJ/5jZJAf1B4Cgs/vECSA/5/4n21Mjnp3KldKPCSGChEmEwPFN5jznGdGeT75CxGTQdsWLEh SESHLFiAFiJcLhqchNTjjTa29+5yRXg16ymHnuaiogksOp0Om1gqbAkxaqSmJajBmv9+vTgBqPnq U3WcCNnW7dDQgqBwLuBDcH5oh6j7EABGQP8rIQ/sVU/h/ZY5YqRuNrP+Rkggm39PPP2Qd3+t39Oj vH7jd/D2/j449vf9vwj8sT38m431v68/YbH3EaQqv8fjzW1vu/DLr9f1d+mvjXLb/UreXpL079n8 /RX9IZqvVSfw1eb/n+XX0a8bR15frfkktpbbaW0tpbS2hbQtpbZC2wtpLbJbbaW0tpbS2ltLaW22 wtpbS2ltLaW0tpbS2y2ltltltLaW0tstpbS2ltLaW0tpbS2ltLaW0tpbS2ltLazMiIzMAgzMgjxl 6Ntx7tLxlbftGN6tdnrGkpc7PT1ivqy1rKEs+1+lIdaRzVVZtTu/qp6r6q3r4OeuzZ+WNu3G8fDe tlZdmay2Wv3p7ndd4tXsgeSfDbrEh+Moiw0WHVFiXd/H5fZlvIqUoElLGxBFBaigQ16hW1QFEt9f uM8LNJXNqJq+nBkjZBEm66unstbSpmXbExeh4dc7olysIlZKt9Y3q23pVOe7ElmbN7zI+AiBAEZY mPcd0GXXaCAcMNocIGmVUDp7oVM4sXaQ0jpiuMF0xcoOemkMZogNoIFRA0wNs4SFZKhDTJ0M63Zj DhA1zYdmFYdPPXWSVhCHNsk0yQ5cTE6QOWbawNMNdr3Qh0hOz0ky07ICwnZgaZNIHZgGmHSQ704t cAnKLCSbEU6RYcMJtCcJDlFIcoQ7pIs6SHLFgHCE7pNs09mSVgaQixeGbZA7IoHdztnN0GmQ5QDE kGtkDpmnhgSp04wDpnS9u+d2BWVJN65wk0wO6Q1jYcIj0h3TbDTJyMr0nZxjaHCE7oTXJznSQFgC hyk6Yd8oVJymJ2Qr2QnKcpCpjCaZ0i8p1qzlgpAGv4VFlQQUJQsNhbzK3I1etvQgOXaxiMnLCLKI JKWWs7js5Df8L4af9DQrlzGiWCc/6z/y9ns6PlVfW5r9xmZuhekeMXIlvthNQmEWieBJklAGCUYQ IUhxo72Vcdmd4IKWn8vEJzlBzSM/RUTgY+3BMOYiOAYtwAhkRGwD9xCVyUa3YghSGpQyhTJwBYDn 2fWapJbSSGKGzEmiIIp8pmxqbkJFaCUZx0VNRMokgKlyaEAIsRngvsmRWoh9mj+ZiZUYElQqqFv7 yEFhI1GfnKELeDuyjiCq0nrOEXQ2uDuRlwoUcbYXEujEQUC1I1vUIEwImCWARGuCN3WvFzvMvTzO QiJSBxIjVLC6TcZmN8hSKOggjoIjnfGijYQIf1/pqNINipdC2eGZYDwr/DJEse4VW4wSOFMeBwoU eRA+9hHAzOhUizEQeWdnBYK0GT09jbNVxkKlLaNuWLqxQQCoMAEfT0hkxWyEdBqQLMVgSITniGZq GxS5OznIsiUh9BZuUyVIERJmQtRMAoCFwk/OfC+Spi50gWOJ1QtUfJVPUjw4snVCpNEz4scOSMyx x24P8C+sAmhRQrbLXPKsTBfVRiNkkxaT/ZofH29aGCoF9oUPhzwe4x5k0eISamKq7pI2rlyRBmiA snhcUbfno3ApJLCbUqpJ3gXIkTQcMOWFWw6DNV2p61rQV5UiO1DhaeaaoqQI5jE8HtbjwRDJDfNT TAhpzJmi5qUGntFBfvBTogSSCkfCNgC0NkTEYEvJDGCVj0nK8lOsjs3BuaHJVjmmxZy5KhHETWwz 668YpGIuh5ZWhuZN+qKP1T1EG4EQ66REUMFAAAGYEKuDReKFKpy/hDSMv77q4i6ZJIo2PTxnQsmz 6ZUInRoX1RCwhcIlqEfh7U0SbuvPCywVQpYvg90VOHkzhb330K7PYDO84td05J5exbHrxh2cWm8T Pk6frMq6EHzGoOwkRLWdZaejEdSTxHArUaZbPBy3bCXisR9MGZWGMRyawTfJYsSYgZo4quW+RwRN lvdGTZ8jWezRTYUFB16H4IEfdLhDLzcERAKuwhj5nsORDR8SWEDfRzk5wyEBgcjzxYaERmeFgA5R GQRBtjMrIaDG1kAA1lqERSjbq7K8ThU9pNxliLrhA+ipGDXTF+koEWMrg6JoPbIk5fJqkIvUWJE0 PnCYuxAWhoalBRo6iQHIjxOH8E5YvSkbmTvDHKvetHgxGrzjXVs3xbd+25CeqE8bg8gEBs4O5eth yDIVGcmFkLzHSRoyUqUGeI/yJkaGj7JHDBHLNI7jkdj0JoRseJC84tKXWd9wRbMHLsrySUEJ0KFK +T4hACN4xGty8D+KFGKFK53uTeKFYF7E/DtKLnXpyA9pklMYgb6OihAYY0UOsSKkTOz8f0Ty08zE CFBkhCsCQJghFNiitucAyiY4UlQD+IFa7kOI2zzLjnik96D4tYYIFihIpuVIG9SY8iMBh4isRJFY FQcY900NiZGhInGTiyNoFRzHMA3hsHCRUeBIkWcYieFCo8Kkhk5qmcHhoibQqwu/0kGDdDdCCe39 lC8MbwaiTNN4QFIamDft20DgU2KmDLGjEy4bm4ThkRkLX76oKh7HjGrmBiS6xBazmdyXhLvemy5U qQPdjavvOhtqOUHHctAUIEDUgXRTTU2FoeoFZG41PjOza1HMyZvkZVHzL72jgxh3UVFb2bguEyg1 SMTLMcmRMzBzpocFlKDG1aGDchpHA5GhAEl33xtGgSWS9CcyhepgkzWq97ThIuTeZEhqZnLDDkpG 6QYYZ3LllSpvvaZWxoaDRIhsMmW8sbGqSDbemfS0TCvSIjX9f9SHoR7kYjxIhzgYAen3I4+Haj4m 1Xn0A+aPQr3I3RDQr4+shgjzI4Cnu7eYxVB82YFUE7dyOlFh18awnWknhTxjAIxnDoou7r6Dj5yY oZMRi2NCBKTISEzIQknzbTwhRpwi/krU3s52+m8kyb7fDLWmAOBgcYJ5HaMwO3aLAQZJXVk5TlOG aeur3TvqyCzCzGgwL1CsawSzAREURQNVLE1THsxxymkA4SaGGPLpJ0yVDE7ghEkJJwF/nr95/GB/ SyESxfd43k2SVBAG2lPVIkow3gtoO5l9i6/Lw8y8VZaEmjj2ZNeQ7dF+9vVNZa7jdy+XewvvJt7u 3AiI8YtEKPGB6DhBI21AZLTI2zfsWa7Gux3dnMXmCcF9jdykhIsOeCvbpyV203sPzHyf4V+X5D5/ c4knMHhRx148BmXt+1tqVvEOHZtgaxKSbtEQhff2Nn8z99s7lasr/vpeXDrB8YQ327szH/8OnAN9 UNReECCQcBnW2pMGguYCbNqHK3ULBFCghcAIwEQQnQKVqFz7jPlSPr98k2mWcAYFJUBig6+NQIO2 d6RynStYpV6rm2b6gV121z243RzC+g/tq8EhcHkNRcMUdwdfhAmgi/OuiGwiEKAp1qeJmTiLxyQg VzYdQd3DtncZYkdtFH6hqsTHci01c4APCk3CYYI2wI8xsMTHAEhN+ZzceOjOTHJHpIiKLBygHAga bVlMMs9ewxbyacVUC24lxc4g9+Or1tLU4b1AREx+JfPkyOhBKleo5E6H2AiJ3g9kjWwE8jfnbBsM S6ARDYGyYUj5qrs9LOMNFpH4SQhRMCG/x/kPejl7UQokmdMojgaohIIAreKoF9YliXyMMMYbBFUH QTjYlvgsPRERC7lQxJ0l4KurHhTTta9+edo0lKPMxfmrt+tqIXy20CSQeno6FgpY1SXskTpCBLpL 9EKKFllba81Faq5kZGVYEzs1RhQQqOEgazuaOkTBb9eUgoxatYxElQXyX2CIniCInaHUzOVU5UN6 HHROmmVVGDV+kIAqzKHz8YD2vd5MzcFVqRiIiB1pJUOU+oqNZywG5P+dvvPSx9lNMNI8QtdCJDV4 GJummBTZk4YyWtBlbKE61XM42Qu8OH7VOdqKmSoE9XrVhWbdRNiA0M2yIjCW+ffBiKquYJIEc7xt XfQo/v36/5TrHNuX9hi/4p+OxdvNmWq8LNfdtRznOsNrEt8HbLx1vmN0OMXjT8weObF6i42uCeq7 nrriO77u17677ccxz1fXVc8WrtyzzQvtc1fPPWiOTT66rWVy4545btcKv228423V4x13yXmoXBpb 0Y5fOGzeb1Orrl+uNwq3viDgfOpyeBmUudzx3zEVnZ56zngxClM6fbYvTzV5xlO+3ihJVrOBU5Mg LTlCuxix+1Y9PtDHPnsEDVxLuMaZ41NS+Wl/ruhVQsaJQvdW24fYMx5L6qhNH4CgwkibG9VSReSm +MpuxQJJBIuUJGCU4sAph1FBz4XuKYkKNGqw6FuwiCIsRHpAsRdUPszcCAgXQmCnEQwJwIcewpkL 7EaNSMNxF2S5b5l2YeRIQFJCWmnzGZCes74GCeZMxCQwdU0hOX9eYxOk/uxgwelp8HLN0uOSK3/Q ORNJdd2q3zciBeT5KZpGE4Q2RB2BkwUJOsmkkgRDIFFJGcv8xjCItB1QZmgQYTnGaSE4qDutjXap +0EJaHPCMgoYhghG5KbYByw4KjjkS2LHXwIRMGyLFOCQSTJJcxzveTXgVq0o0UjA5J6gV7gVwN5i VUyGFYp1yR+vE+hyRtoS5ODlI1QTc1VOCEHSvmGSTGNBJCywYCZQ9iZE8BEBQJE5iOqDmqF25RWQ qXIIwCrCO5DtUi712fRo0Mam2kLc7cPXqNRjZwQCe1vyplSGkdJHpOZWaF6ECViSsFIHpVJUK1/p QrJIia8l+zt6ZzbY3BVSsZHOiCSeq77kMGxCcjUyLFZnFCEeYcmfmQSAs3Dvj9jjtRB+Z+rw+r8H jHhQo4gGHyfIfSQmhUH/Bi3ow7Ro72sOZYk2ZtUsdkZu4UQO9qwxOwyKJ6gmtOj3ieXYutiedR/z YF+Gr91IU4qkTjEth+U+ysovoosvf78GPhKZdTDFHcrTlSkyowpbUojGxvYUecy+CxXRblVIUp7T 0/tSZi+wKuDoPJOkXIGYvS8WFzho01WlVLxWRGk0cZd26Q5zkvummaJpiUs5ILDhFpeGIFmihNVg ZtcAwmFT6cllTRHM7xi9rbQOFJRfklniZMUkKZLKBZBNCAFfocF9Z+98JB1OOSZDDINN43WPWKJg 0psOWZEocmxQjoQhXXlV1pkUqq8kjnsOkENdRvTMBL8C+mgQhaFG/k4H1MUYLVAZ8mj+EFwJzv0f XT7PFUKunLXHxYcjx9H4l5FRBvMOyEG8EYhdlZnagdpGhKDVyUCjEUSYfbqPOK6RK15qhCwqikID XKYHMP1OS0pBYMuReEoUJm6GII6NQmSg7koBYaohmRMnUh1hW9NghmYroCjbG50QTzAxwZmu7Zuj rMaVmlzk8PHIMdviUYFrQKshMhSQntBAkkEUUwZWqXwELgaY0jiaLDZRctkw0nGq4XNEaGwQ5Ifm AvABdECJPhsGVRLk+5oIiWO5GmqlVqT1oDZQJUCDBqg34rRSZgo+Ns1j8GAksjVK4cnUGqTIG3VI WNh264sFobOQIw/BHizdC2RCJcpj7macgQIxd2nFogJLwoMHxgYYhBJCE5/cZo2KHKXBjRaZuTnm SQu/e/Z3kLwbCyCBQcKG+HzNKEQ5z9USZDY++hOBEqEr2Nrve4JGQ2eFTOCDVL3odJ7H2GHNyJE3 ByBY0cgMnuzNuCd+DBIXI00z358PQgelzUxzNR5XvGRdiMbkTp4sPbhvwrE+EW0dJHDODBdkgz2O YcmF9RK2mSqFTBEgbyT3c5yRkhDEho1CD+HClN9oFzmDx5oxA0HJETBQ+rGMJtqm+ZYweULrd9V+ MYFIlTYwpsOoZHJgY4DM5S5nmSFz4BiZ0g+9yerrjbUaEDah/d/EbaK0OZGGMRL0sR+cIhqsjBic yxchnq4yFzUQwMzoR8Qfn8AHj6xfXu+XLvRyR14+N0eUF1KOKPBHm39PH38nm/Paj8mhTT0InSPS qIBkogX255doiw8lnGLS83m3uWdCCqLQwORc/XIbdJORacGvKOJwaTZEhZZAMwgfIczm4Jr41Xtc sUjKfpZoSKPDDZEXNbzpQYAeIDeQs7WNkUQ0oZi6t7oQwgcuY4HSPDEyGYhkSRAtIUe9tyB7FAEk agdk0hDTA/EfwT9zKgrGHbv3668fB8fHmseX0hrTuLcjREuNRUae9HKsOr3EtIVhNWD4ZROVod6+ fivVSc+z2TRONGUu6xwqxQcK5tjFl6gor0Q5fDC6N7u0QuqYHvZqv2xbkWsiJVzbmTqVxAVPpg5d RPsmRMCfYfc01VMXa9KYaMLxaLIOI5qbRVVI9+ZV8B7anZmTTtmo3bovEQPkwtnprSjxBvNN3BVI YQIhAENdpsUmwPFivbGfT4mMqOF4mnl6uYCl4XHXOtZxu6O8JX+judHeB+vlRPdCAEOj4YBJSoGP kwuf3wLIQJARuqyqFP4jCv8dC2ySDjGFU7YIKKBQ/AHsEkOAsluVGtRzBFAkkG+mKFozNeoU5q5+ koK+BnFUm6Py9IjDQUmsyvQeZE9Nr+Xk7ZYGy0FBJPJhwbAfeTrCO6ZE8jAwQzHJ1NtodJE6425t sKe/SUuIrscwaCkJEaybmNCMMiSsz9OqWIqVB1JEDwYoxeKFbhEjwQ+GRtizlgb58hOc/aw0enJB 0iBqQLz2k9Xzhhn03r00J7iIVHGQRjboVyDoTmEhTxU+U8Qz7gy7dCkOze+QNNJC+ykKyg6JApiA WZqYRSB+NNbxBm2QIS+W3QvZoRlOuiSKlHQ+uGoYJDuE1AmhQ2XYSWHucOotQqGtkIDjAxX+3CbR NJPM5jFd+Yu8Y7SvNXQSMgNi1FmK4qESjY3FkOU9GhiGV7O9ELJs9Kg9KWKw8k8izbGHCGVbIgls t4QVWKMMM2HLj6IHT0nRosxYwTOSkzL7GIW9malWsKIV5ZPB5l5XgU0tmYOR88c3lEsxvMrsVK90 E+4QPogmVdFZjUDfQitZWnIhvJIQgcxm+8EeK0QS1BVtbMugkjt4dMHbtiytmDAc55P8G0Tj+KHa L3A7Qd0aa0CxCLNGMQqP0Exk73kbXdqIX4IGTg8Ulg+FiNbMJ+Zsdl0U24GM6IyoK5TccSz5PUkF j0rFS1dIEDQzIlDKcYDkhehCRnsG5sc84IkhuDUK5vIUsWPkBkIidSsBr622ddyLshEdYDSbNaMp VyHsyZS+5WSD6EYnB3ICGcZvsgnTKztWs7oUTB+KhGsw1EO7AY0TkSHpR2HaBeRmck0a8geKwZwb KQR4U07y8+MiQkK56QiZNmpr8RIWLlnC0bA+zhH8hrB8kaPQxaiuog6I5HwelZxm1auzsiMUKOPy +iM2HMrfh6FD320jrYmTIFt5m5NPppkum1GfJRiAzdpUlWz1cqi1TBviGBnIWY0GHv7htwSwYKId IcU4UPDj2gbclKoQKMgANUCC6EYgUUXncuX4JBekEfQwOlhCfkSCok5IsUKKH0Cw5Kyy4FFRbg3W QQZSKZLEYUIEyoyiN6eURJCiekD6scwcNWMfZKgz8JfLQyROkpF9EGRjHKjuknbfgqoiu+h9P0r3 vfeZhhj5TWoWTrmZBglA1u3BCQRZVT7sj6G4YEDpO/ZN3ZQhklGQ2xnGLG7EVtgvNxjQzWCDBwiQ GUxyVjNyFbOTVCZqNoQjp9xGrI2owSxyPbeKTiNlThuTtBP+upmdBmobECRmlU54JBr5+B4oJXrs hflVVaKaYjCI76miu7xYTIBGlKkBTg7NXO4pi2Qlte9RLrKs3sNu5pmNImNGBwdwhJVYN0EvCy2E LE3Cpc0IwSahTIlGKaOP3mzsRUzYwQdrUPkTJYsYGCx+aYKjSNmj0/vJK/euCRXg9L36aWEnvh/G 6eOoWjBo//gzBM4YIOJVIVHeLH2SioIlfcBISVBPGShpC7jE92XTB93cZcP6lvaiSGKF5QksMWIc IOTYdm/E4ZOfPwarEqpwdRzctYwTFCkBw1tsS1q2gxQhrQyYVziP2yLkXNNyox4Q1aRDndasmNts 95KMKlOF95qlhgVDEMKuMwoK7qgAngBHCJe9QosBEEQkglB0iknpDmBZ5XUHYOpC6xgxTzxSNZGU KL38uZI0NuvBnHBa8jRSHifgtCOB0DSGwKiPrE26HPOxYgahsdYXswewJ2+/OUuvZ+fjG4JKgAhD HxJj+DrKO1PDwb8i2UKXRoQ8OsHHmHhyiJoWOwzF8it+ClCJlM7oJg4NTJpFw1gdxhiBcrfq0SOQ IlS9N5MFjBch4Sm54eFipU03I7cCzMETUruZ7SMyTFZ2JSUhRzTmo2MVIMqqhOvC5ipzdCZaXkzy p4TLWqUPC0iBSp00bIkrn8hFdkTOixQ2vCFdBgdzoxsYqUGHgOdJRO3k5Yqe+2ltb9/nNkqbOnh4 XLHnWCHqjA2cJaHKSGHPK7KMUhY0OdNn86FLK0bM/vgl3gtHmfTGD6P7MzRwj7QjQqKbEzk2I1sE mSqkzl9tY2sZE6UkUcVJURi+D8BBEoVhAW60j8L7GehM4m5EyHMy+Qo73I3Ph6ZkZ9PwbN6c5nPw cc2WHNkDIlI3hqLgHRuVTP8BPaB2I6cjw0I8+OPz+eSPR60fV+1FwF9wtVC/p+YQvUL94lQYPyZG ojblifv19dYlOBInCNppMJNgrQL/HrrpXoER4wAZz3g9ZlVvgaldwulGVObRIkmlDNcuzPSGY2kL Ssge2AoCpWeQnjeWgYqysOkKCmq0yyoSD+4m3L7VbpnCrayolYGRQ3F1sddnJy4a7L2evZ60Z7uw S+czLScwguugWhePe46ZvXIy8uxLPWKgIaDOQsY3bpdTLe72zeSgJyt6+sdydVQYomXbm9ulVd8A Jk75BY+nLpcc70wYsWAwED32D7V8Ke8P1zMcj548TRrcULIkpA6FF0KKQG4+U1Tj9Pob0SRo+OCz 2q2pheHEmfcTXGhwXVAih7ySWGQmR3DqjMZc4S76GbzGLoTxGCQy3D+WixIds2OwfD/tJzKvMlzT sNPByhTTDt6cDkTUqZyQSN4VOxCVIvZLTgsKjtdyosL/V7+h9nhs2fZFo3HB8XyexGD3hj0p9xxq CeTdB2i70j67xbk7ytKkHn8QTmhOhNeglfY44wqRtFmiImkkSgEEhFgGvBQYgc8BV3FtNRt6lXpm xAczLKYSGEhdGQCW9DhVl9mDaen3TmiFlCxG4OHKsiiDmshy4oExQVhHxj5+J9siQlwuOl8NlCxA dypAwfjzpnkIYjBtEU3tB8JmJnBIYaEEgM7EYcRCij/h+DuQRxtnxUgWQVQm+DZW7QURJBOcgP3s 4Uk7FB3QmInmiRJkySXGOF76nfGqr7HcQsv9a9kaLeQuyht2GkZjN4/kQdNMw3n2uzF2RmCdiWhz DTcB1jDOJZYD32lIgzICBrJg/QElIMnvdFA0XIjYPSJic7Xg02PDbEWs05OlKRH5CpVCkJFVVFfw OqxHBj5MdAftaDrRo3FUVAyAUuRZNDQ6OiZk6umg6E6wjI9Yv4MS+nqNMjshGDs/39xLDCRhnZAT 7MMVUSyg5Y5MzoVSwoV4JWNRzQ2Bds2+GNYGqZJjH+LzL8jbeUJKNMkni1mjsaEKVLmEkvxUwoDJ yj3piE60QsdJn4tUiXgTjQbo0ULh2ZFTk64hKsBEh8QJanM5bJmqnhEUxRCe7w8A/BkIwprJJt/C ZQch3NXPI1ZNrUgZ2G+tDD8NOkNh10dsou+TYF1esZVGgwgCQCbfKVQfCwgSeRc6QJJDDSsYSGcp ob+Xy4HJXmdLZohk46vkRp0bWSqRH5c5VasmqiZ7xKKMkmiqtuI5cb136/2ZKgxZqmD+SS9H8K62 fD01MrEohfjBPT82Ay8hBIZ3OsiDAgEN2VkUuWaVh5JM3mNsPSQnycZOe11wqDBfxlJUhVgWCHBH Y2KGoFyRSwI79UOGMHYoTJWJTJMTJmVhy+oK8JzlXBbm5oOcGg9CsHVBk0P1IgTXGISV5TEYENjr 2TEdswJCo95TxOdhkOPCSE6QNLRGV5aiUjFCqfR5Avk0rCFSfyRMoSPlcjmiU/hQcqVaTIUOGAND R+FJhKbK0aGxGxqNNJqMQFLvDKhsWoQ3IzItNyBQ3TJ5gqTIHwutbogZkAqabTCQgZ2TpIUIvHON u1ZUaE3pPdJXqISmdWlJjE5nZMcQi9pjq5apuPa5gXQLls1QSYWGLphdnccq04m5UmRmquTwOQtk YMyVVjnlWqyUZcI5DXipxvJ1oGFiQIGpXcygcDHApEXegvYWBvcmGFL4Ry06LxVLswaqsVYe2EhB 8QqWc3jE6UqAWMEyxd2ZsHw81LGtQ8GOIHLdAogSsFixy7QKV3wQnIgHrlw+yKlhBA7UnO1Bi5gz hxmZGhaPNX2gZkSEjhTUFMi44HDkMrHzQTcC9dHVgDYODWhUkMac7kw8wVkfRk1w6w80KBEidr+n N/GPw+vSRb0ixeRC5PdN7Qv6kJ/kZHE1TM5Tli18nh6GSBQyZL2YYg5aUyOT4UqVyMxJHNEDRQrU kSMoQvbvGbhjLbO/IUsXNrFxliXLyLkR4FMi7kfDxWI4DdywwULEjo2sWLESxWQgF5mlDTLMlKEo aTwaD4NCQPkFKPYuUiUyuXLDjWLTUyO5GRi554SkPUxc0VPnuDtyuxzeSJMiZP6DhUsambOeT4Ms aKlK+WPTiiYh4XqXPaAx3hScuGGrnJOdd2jKVLlSVMGPgjZIqRIGzBzoXJy8Yxs4eEs4/ejBkpk2 Q3g2H6To5MkZLCZEuMYOnLQ1AT08EE7Bqgm2iCB6IO0Hh70dwoX9yN9PWA0DziHw6MVU4/gKYobA enpR3J7wetHuDWA96PQD7kfNH7kehHSjgDyiWfSid8N3Tj4brX46329GOE0VhnVysbaQaS/g9FPK 9EALw9wLvqe+oZdCnM1s7VyguDOiiARGDaGG1wdAz6n522avGOEQII7yILL9j0XbizG8t8hh1KZC Ve9I5AYy2J9gpKktrfZ66bFzyrqaQOG+JW6Ja6ZvGkCtm3peblvL5FDc7aZXZ2SKEh9IsPrVzjY5 31zwuVeUOqfV6/bmyYKna9Kn0+D1DzUe2cGu0s8HaqZewJgjCraNDHOqnRxS7OWMqCmmDjAFA5b6 9uXca/OGI2dCd7g4gqhRBVElhTManKghwpvqVsSoaW0qgXJ0+U1W9ogya+/UAiP1/d9zP0N+nNF5 Yiz7dCjvXV7atOjvbppxslKSopRZv1EjUpTeMLmPJESbpimdQjA/nJmxjWd2OGz2+ClDkdAEEME0 d9yRh7hCDDiQKNXDwzopI1rcrDWC14mjLIE0EGqrFYKPJ69l9uZvhc9CuoalpvRzdCEbmTd8nsbx zd2gr95HSjK6F47aK5HNylSOZSuV9MaqOKWwphCT2k5qNAupMmcQ11a+BOZlNds0giV3hnshMgSS BxjsqllBoRNBxjMuZMe1Q37HQylMuVsUUVY4NF6HUR3KsIdPIZSJdb5IUCqRop1HJRgQJtSUXnIC BBgaDBbrzaqEWHpBVICktn8Z6lg/H1B2sVOFfJD4bhrhBCofeyCqNB2g+yb2PV5HuKQuVPqQnGpM kKZYlozJwsDQoUJOZmB5kztYlKhYzXFBy+LadMQVcjbVIWINB21XVyDgpUuS47lRAeAERRYZ1cto afQeKGfFCqlU1iA7Y2aLnnkSprm6UAeholk+XHx5OFpjmjQ56eOMwMM54/GOEhCTjCEmNHHR01cx F5IghQKjBFjw6Figp0P4IXN6PGLE1EjA4e9ISqVIlBkIMAvON8ZNfcLHd5zBkPFho4w5SDPcpAcY OUQo5CdybF0Jg+/aTizubYvXmI+NFhm8QJJBPRC13U6DzGDZ25YiqglV0VXh+5CDEYMx3H0Rq1W6 eO8aij0VFxe8JPdzFKn3AEknJkkITNOPCRscH4I2Qx16nUiMLmc4FKZkiRjjLpLotIDL0q7MsFxB 1eIOvV+28VtjneKABoW0MPbqI1fWdaSRHW2rodCBZjUo8WNCsjFitLrjZlmclTM0WJVS0yFyg5f4 ESONnCoxstKozH4x03jsY6sajdTZnhNopnUjF6joNkZYfXE4rjLBMuLyPHOcBmz55wPcxvYzhUfc iShuxtTKl7aliWs8MDzNlMGDwpoRY0IjnVE6jGvHEJEc7cUpToZkCRxxyWLhdIC9pl+A8KyQzllb Qf0rgp2y6Yh5RyEFVZvcE1vxMn96PuczyZrdjXDiqE/mz8F7dgXHgRDBU7Ygb9ec6FXOkDsozn6Z 8BomuntTbFs5aHRMSrIuUInTo45maVMFTkmWJmhVhhSshIFjE9iBpg3p3VVUKWZIN+pZ1Rp9FJ5a 7egeYEnmoqq5GxOJNsHFHVFl0MxSCUNDdsnLx+jOG45vtS42JnBvkKWwS8OEiJ6e1p2JwvyBuMQ4 LJAyNQ051IETcocwG3QTABvKTATj6Epf4H+ATQUqj+D7y4iiA6SwYZzYtAwIcRS9JMzUJGicItIi zoXDZ+IRX3RS8lCzoTkmwo984uuoReZmTFHk5HjM6RYWcaGpfE7FiJKAxc6VuRhM14UInJNoElvA DgkqJAgPCM/KjL0zGRfhc0DWMchYuVHNuTPo+ipuIxY6embEdmT3RZUNauNBweJQ4VMg9QzH2Iim Z10YgQ1hQiTcGqb4go4xobjmmpIcsGCZQiOpK4XIo0wkbmZU20fGCBEuw8jZTQtvrYiV2c2gOKQF LGhobZGcjQYmwXOHB4Dk7DZBNKpAeDZY6bPPHMFrnJxKGylo0kSsVr0MnDvNnbmjxxp4xwoeGzSq RLlUsQMhzsyCP3F1WxAUbUM7EqKY3huxQYqfPPKmhqGvlQyRoTDnScfnbFSVtsaLxkR+GScYa5F7 8LjM53JA4cxgiRLkCx082S8MYytDh4TO9yGhm0eZOHdUONAveptCav8D7wYqqiKK+FIBPkrCfZCd w9sKfSDpePcu82I/IQGw+ry9KPaGyI5Gejo3w3cJtyePpqbu5UKFVeAqkhAduoltoNkHR1Wmd4pt 1K0l8KC13eI287bDVvvQHIcyZHJF7j23or2q1PJPrGOx7KxIkoXNbSmcXqM0495+y64sbapzdI9e 34xWTfOpNY6sYzypnJmatvOg6J03TVB6OlOqOkNvk1wMic1gjL3TbrL4YM2JC2hVXsRMjHVObx4K pdVlVMKnsEDKCw74ah5xXu08Yh83g8pQeJ9O3SbBVmZ0e6ZrZI2U3nWzIuNIuRWEJ47adZ2jN4Uz Qb+QEhIwkmQtPIa0jQQAJBEnDiIFI+wdGzoxbKYZqfrTHnYVzWXQIkqTWKHNBh0mxdj7ZH8m4EfB 0Hy+cStViYIjyAAJDfqqSc3IcchS04MMb0xBC7HzNZMXqRL0ow7Mw5io7YbKFSaihYIoWs68DEo8 UUxnuSJXO1IFRJEkSe3iMoahpkUiwWQUBv0gYBjAWLzn0ePzbhwwWCwWCgsFBQFgsFgsFgoKCwWC wWCwWCgsFIsFgsFgoLBYLBYLBYLBUkSRJEkCRGRAhBPHZwDjMg1ljmQU2Gj8C3Ql1++aIlu9Vv2q 1GyZSXgubKsmUXEOkKtuwBZfwKPYeofvkanJrW/URjV9ngB4CpsjWBL456rV6PKRchV6kKWSrjlL Cl6oJwPdhjQnY+VpwvlCyl6hg4KpgsFWGvM0uSzKGYxwMNJ5HXIsdToLIWaE+igms9eYFKY8rokV MOD3ey2mqkFtbrpYAREfQ8eeaFznHkakgDBHdIJxWUxoS3LjvFpPU2M9yJmXUmO+ZUlpiNNhRs8W CV8yc4oZCGwzwZe1GvwppsFDI2iTOSA5gg7DkRiZ4MPV3IQNmdyRmnht4D61OEnoOA7OyBsiaWJD r4GntAk2iIgvgOO+w7j3CMCtaROeR9baKNtkxggIAkntsUlorBsTMjhEKkXDpNix6RDLuXuVqMhN PR19EjUPFPASNw8+DUcvY4OcbkKG8OeN3Wa7O2B051JwvBAThYz6F62EKFR1HaUg6GR2+JZSZYkU 3OE04mS1OeOC1Tpngr6yg2IlyRHmcOnRoKaGU4nSNDUboMXLQIQHqbGoYFmdYin2+HQyLVnqM7dd m3zoD0jlA3NYYo51OJlisakJTqcsOStUrzV9Xg4lMzMLbzAjI0XJNylgY58Nk5NEmbmRUFeLI2Y6 kGOvWhE30NjY40G3NqHxQJPqGs2OyWjBy67UeCDkVHSoIQJaBXr6UvSp7hxEUOCblo2QRzWETFHO XMoky9SyNsKgjilJk8EuToKZFJWn3hgWy/P7X5oLtuZClxYHUY01JGTEj2P5/no/LqF9/ZFtt93b UXchGPNIX4ifBWu2AoUKG0b3TGIixjqdjkpRjCIHJnWKpYzozckiIngjwF2W2qfsn0KGqqnlJ9Cm HNhmvU+NHB7y1nD9qFc6E7l+qDwu5s/ahBKlT7g868Zqt4Sd+vNjJyYNm9TExjhYB9prdoiSPgcK IQ2c25hYBGjc4oZIDhmG6Hl7MXS7DtuYcEYPge/uTJhAzkurEmIFvktlFA4SLEylthMlE0RYqbGs U+VsiU9bIJQ+1JfQvUquw3K02diUtZbPIms6pBBLPGBxptqPmk0Equ/Pj20lopSZmYHht1Nj1CaM oqBWZ9hTp0rT2+9lDMz59MsmXPrcrS7Rr5/c1ZbvY0N8c8w3KaGhwOPYyFJnQoUHJDG1By0yZwZy xqxaOgpKIpc5wPIseSCbZ3JBo7sgNo9PCREjQkORIG9VLFCJQ9UjOfCZ4TNFyJcnoie+d2ccoVie mShUmf1JCsq2Qiu5Nxqijj3LsQcyIDGBQyc0MzBMyuzEmCcCI54XxQrX0mQhUwZJk5pKRqJtitpn hkfZYxoqFyoZHIE6jVPziXuV8OZKnsFk5E+kJuVLE/Tw0Y5tq0ZyRv2pQ2enTpCxw+t8JeaRjTjb HLkpN/N3Vp056/Rxj1z0pEgRH/UCyT4RKl9jeGyBNo6InCZ+iBJIPCZMoiZ5omFTJc4SD68PLBOB Ac/ehWQv6Uezejxo+w3m74Zo2uK9gPiC6uQNXq+HKh6jkR37hNyCqET1g9/u7PMPUnXObsnX29hR tL4fbH0MWc/WCmvAM4dZOn1tAHUh/eQq5D8ZinWNrxVK2RmyN4+9WDJFgDaYJgeNJW0Ufezas4ta nUjRGahRCzGJPpV5NxZus3nviuwXbkVlRxrq4y7Q484lS9iuO3nTR6lp7Ok3UTuucQ5OsW3JrLxp VQw8clCsloiRY1bgZlNHBXdlu4udkiBEMUJiRVAXQkPWDBVreyed6txO+3A96ZMqI1c6lYgr4+JZ iVChou2ueaqseyZFyfZVRgvwYkjTJeJ+T6lbYXvev1NjV66AY+PxJMAe0cbrejP5so5bbDPxAcpm HhA6BFcIA7IEYAAO44NpZAB/TqlEJz3xC7WiZYliNPTBw0rEosPwKHQvUjgdiAQo0IcHPu+6Bzs5 I3twunsTKTQzKjO+71tBBA3JmmMFRpikvplK18oCmNipM4PYhEmyDldRRTFbVeRkW8IPGeVGavQI 1elDvMM2pcXjHBARBnQgQ8rwoe99ThvTNKUTG/Cu/SLwv6eOXUaTQmmYIz02TO1Bvr6gVegb8356 FsyvwPGg6QvK9hnC64LwcC/ALJUMpn787ZGZkwpwZprwPmbE/SJM6Evc6CdkEvxzYXlVe+h7vEQv hWPcRE3B9/jS0Pbd62CIO6hGLlqlmoGdjYlhNzMBRyFIUAbalF4MI9pDEZzWMRnYtF7QKVNyk0mf I9fztfiFTRX8zZwgV6AoAjyKEJ0HGpfkVmmfoqowqDzoGCpenDZMStS3HFyB7gwLcMxWGnIYQFTS ha6VjyXGsckSaJcaf1GHo35tLezhQktOU0VlsueQo0pstEZJuUoQ+QEZGyim5XXPYcmQ1FLyHzJl P0AX9QKIK0Q2lVsND15xiQjGG2NtOMZyx+kCUeKJAKWqOQmyEuIXg/mx0KS2FvFOxE6kYKikt4eE asfnAi0kKgw9CbuOP67wNnIL0YiihBh4ExpyOow48vB72WnGSlDQtE0SZE7EzQah6FB5sbf9I68v 2miOWNr1BBheqfwa5iLgFhKGDZCLTuXVbed58RV8nZetGkSMEISOHHUVNEEYEbA5F4kc7nArx8iR EoRjoWLJPBnCTTgLtJJ7Exp9tNsdArkQGJzjsakmFJnb7quW65BxGZ5r09v5uYsWz3h+Dj5u1eF1 jYBqL6BdIH0khP7PteWls05dvvhc2SINM4cIgyqbm2E/D7+jMyOiZKgMOWzGhNMVPzQtlfLmnPx6 SOBpP5gz7nDM3hxq2b0hGsTLKsafGjX08zG93X74PkUm26uLApk25pF10jQYdxSFHHGOw2RK5oYK ek6+HDRIuipkuux8DPv37c+ipVMfDR7LG/REn2QR587eHV1LulFfNhw/pUgZ7MBQUauBgmo00xeK R8kstEIkSCl8le3kibkDBZErcO0JFSdLPDoORMy8OOXMGSpUadtETisHkwwUQCfDj7/gBPOBK81V t5L9cRRUdUjGJ6eSZrGRaiiRpe98xyNFgvGzrwNTglMW2aUHDtrS4U0K7GxUX4odB5HIZpcLo50L nyDD8t80CTIgf0YgPw9LyaBUgWMj77yX8QSWTjIiOkCAi9GqpFyJkkSb8ZPz/PYYJTzwnLJGiWTz I4jk6DLU6wmOaGB6GirExRi0BrcMYKJGebDSGPTrED4XIqxs6XKmjvDR25gcjYkFajXIk313Mxwz /KZckWqOVzg5RwiOhd8NGOMRKlCyc7RW70kVfwLETHhcqRqVHKx2xnoRMOQlnZxzQWzkyFhzIjmM 5FgmKmRoORJMZ1MvvyJCFcEjFCRWx2RoPHOaMHhM8KcoSNEDRVMjRGRIoMwYOFCUSURix4RMhI1Y y2RzQ/JBozQu983pjLtwyaNlDzdCYxqsswNHg3zvTRQkWow54TkS2XNxCMCA4+YZCkTTFyGtIsQH v7/qESZyIdASvx+R1+iIHKjwR7uVA1JBOpQ0+j1mlHQDyI2R2ImaCe/fsgkxDqfJBNPcHmqDbd4b acy8n3ZVkQm1JBcor/yQ6sVfEH25LaOb3DRInGuDFMVwuNanJy6FCR3OYnvOSN8rqgWO9OG63p2x wqvZYywcLpzvHz3NWSRV9nJe8PYs3NZuZu+muC18R01xlEjGqZudc1YwOZkKaZFO6LGmjg2cTosV hItpHJurFWpvQMEi3V4HUNU0pplbSyMW6t7rsrLylyQ9xhEAUztvw49Xh1ZjwmL9tyu0XMrL6RLm xNtbybxQQKBFAZZRxsdzTqR1XFXSDSBCihmjjcTSA4WFha6hQ3NWdsLadBn4eoyy8FZiE3w68bLa emZ0doFqvW6I/ucWAikke/uM3tQEXMq8ERNz2f4DyVU5JaqgnJOBqecUKmcjK1wlyKfFouykWXZj kYixiIiBwKaj0U1HnXCzCSyOG4OOhkSyLZBAvQ2NJm5KI/Sool+Bi49zd9Bz4Iie4RDh4WyetMQb Zp8kIRVpkpPWARo1ZSpVnCAo2xqbjpaJe9HIldHS095U7UfePl4SJVaKpGvhmhxW3YAzdjwKXJ0I 5Qr2g0w+pDn3p1Ser3UpSEJG2h/BxKTCQb2SvEQkO2RkhKBXwzSoUYgqk6e/GGOanyt+eePal4eP PU29ipqFUxLFkAKBGUQLCsVB8ihwZ5sZWokqXIcNdNITIlTtBIcbjPQqzlEbnBYoOAvo9ByRqgXL +PAPEjAwISTpjJSCtH6gnEISPCNJHw4ciEWoROYKJrxP5xWXMza1Tv19dcb3o6ityKzcO13nFKos 8MQ5jzZZpIcEaOgbkrQKiGpXcYId/kjeSz/EU7rAXy4bVbogLUaL50iVGYecihPApKF+2DM69Shm MKdTWxmqmeZUgxduJ3BRxdkMnMMM8Iq7RiMq8b4vAMqlS3UU3doSQSMiBO856FLmGFKilD5nhZ/n lEb22+G1JQ26YQ9D40CZE2TlntpKaFzpYgYCRj4SOc4T0VM66e/Krh29zT/MfPTF1Be5cvAywxdE IozjhMZpN1NgYJb15HbBCzY9K9tzfSejwu94FyxXHg3hQd/JZsN6QNlxSGIHGPDJGHVY2cIdHMUu Nwr8KHSRgPoIJYw9rKPPHCzqEZNDXR3SzD0fONq34uVlVdtBjU+F2LsS4bxYsvLEr2OwLlFbezyZ wnolP5pykrLI23C7qLxDY1xlo8K0PJDbfQMtV6bMV2RLF4nzFRyGyR0IlP5z4j2cdDlPBPTCHCyS qLwRMBkcpUul3MCxPN24zB6fzOlecv429lOed4VuRuYJfkZYkQhhVhOI/RyaYY2dJbMH1KlJbLnD LScsWoeZN0J0Po5+iFIeh69e59o8+0O0s8cy5U27A3MsDYkEOI5Dhwpr2jryazndhYl58nTpLU0z LHJchaF6EIbvUhKZjzs52W4DtjBXdz7+YOnhew5LJQ5IqSLHpVOiHLTxthQ4s75zZNnZlfkf84xF KWMzQIz6Hkzx7dsylzVuCcCVK7ToZG5PMqDFjG2uZHni1jpoYc6dsVHkZMkCKpU210K4xZCeLIp+ sElFJIEXVyp7QjE4Ez+XCpcWyBTqs9jciZ37ubCjZETQ0KQJnJdhToMUL2fATUbFyZeQ+rjDsbYs eGjASJzPBl8ODzGNDK5XJAic5g0MSNY/bErskdOL1C3OcS3hglGbvOciPCZwxjBQyTIkzZqVC8yx 657gj4bJliBYtU2MRLm1oloMQIbLtgyKbrtdVNHHmb8LwJkcjRxZz3PTBsabm/DpHo5Qcv0NB56c PJFztxAsUNeaT7XXkYFaYwSOhQUSGwEYp+jM7VZoM8TJQJT0FVgY9apPJ2xUtvzp55EgitUwZE7E 4HJPMntpM+1BHhPHFoaVyyHfXAxY+/fgZuTHmQiYsdwOdU9kTRgYvM8Kj3lgwKhE+yxn4YcgQPHJ GgllAkkGyRY1+Zv6VcROZH15IhbP3o6fV7Q3eSOxHWqm0iOxHZy+ykckdqOhHzR9PZznoR69HYri jzow5kO9HaAcbtRoDX4r01p16t+4thIYEOHv8eeeHjRtD9QybTLZthXN2STpU3pu1mnFwPtMP7sz yye7oZN66mcsrB7xu7uT5WRECAN9lnBIPb4ZfdiYpsoFu8uqVN+cTwQ2Z0FzoYiBBuVxZzbG8ldm ru1eeHWMeqxr2pqpRZvgcoy+UybqqL6QRuFTNULtqdQCE0trDlbhWdfVqmlmU66xTyTxEsdx5r1O qkdl03fTKfit5e6iZwy6C1yxT0aKilMLRCBEcAhnApBQWL2PjWV+bZjy4q975REIAjgAbcInF2fu WurJHZ2xY6ILxLjYMTLssPMOe+HbvzOumglMsHxIHA6matS0pw93qQNSGLJOZiED4fCUKREHyXVE RwABnG8GkSHQsc5tRo1z1/WPom9snTqdbKkz3szQZzQyLlS5x9t81CYuXG0YJm6QvGS8CuKSbMOp qwmWFCxIe9pOyeWtNd4uV99xs5c0xQdiu3goalYmV7Iv8e2H13Tv45HkcNBsnC8ePyCkXKmDwl5B SGDZrJclcuOWhyYWPzQv7Evi13x6Hpz331wZlSVdRrS6MhtORrI1AIFKgJAQcCAD52yzoQuoDFDL HJHdfcWoz0o7CwCIy+GoTKQJnT2cM3MxKtQybivhsYvqrS6xojIaESQ5K5KXCw45Qx5VcPCpKhov rYcg0PDdBoS2+IJ4DjSae6VdV80hNs3oz3D22HcaZoIlzYU5ycrsa2cqWTa1e3aljfeZubaE3dzg mQyz5SWleIjFyhEnk5OR9qCcwSmfCvLmk52kGODvW1oNKRapNdGiSLPPpbnS5MmuphrGTS5MEiAS VbM8hrnRtpsSw4Otihc1JhJdYePLRHeUAZk0NjdMRIHFwuMfDpqRT7+7zJn7UK4X/gN1IohjjbrI fM+9lAuOPNk8awrJXciW2V18ClWOwyYsqcHlsTlmZ4hXKx2duuw48xjqsSxSUFFmXLAMKFw69ako hMvXJzIkGUTd9EXMcpTc7GQxGVgg/UxuXOToaKaDhwMW/ca+jmJZePD1FhpEgoodQoVrKrKCqqLq hLhwo9o0+0rD3j50rXstB+e52JbNhc1nzZQ8wbMnmJDcKyhStoSbJkqfVDG3LFzfh7fTl6HXTVoV FkUJGDSIXM57edckM99YMQq77RdRV5IjupCcprrFoCnBEjSSVibGpaMZ2W/YTCgKzsWNiDZKhOps Ta8BSJ2zIFTRzBwMwQjQI4HYoCRsUs6dNrYfa7biiYBhQpAdW54wW8JFJwJLihBH1GLjlzQ6cGCc lCo7u4uppmc7MvLbOtYqcNhYpkpzJtqsSGYbTa2SMGj7IFTRkoQiV+zhdUHJjYLGjR7z6EidOdIv Pg0jwzRjBsg2VGIKKKNPWdau0dTYbEMBg8JzkbJW6dJcJW+jhfxmOlhyNjZMtUlqQqSlejyHaNxc Co+DjcvAobmg5WQ9DGhZUzlGwJL9whKAGv6ASXMpaKkj4fjXV8werY1gpKwRiKalMKxSI8ypxzYW JmblwkUOCswsUyZsbLuUkWYYbR9Lxy9rPcKzpMiZLQNylEWyRUYYhskaMyLyKXHHNioUTxmQNXJE SaOXMrmlzQsWctYctAoWHMFBzMqZEjFWPm5MiRRxhRmyKlCBpqQcjeZoQnKIwUo2jyRM28HhVa4O VmZNGjd7GCmFGbjFHmMVHPbzjUUgRUxuUKUtIZWTI1NCpQuahwxaRqHCJag5EseNEf0+IUc0JFCg fpGBIYuYRzxQSO28DoTIUM4cK/TnXWPRx7aEOCJMnyRGODr12MzGDg2FMxzaxoTGqplHYzqViVFp sZ2NhxGYa69wGxHnBy4vGs0bA5o5KPioaUdPXs1I+BScQVtTeKciO16AOvxpGKpq+vFzMDYA9RdP HGcFhJ4wd9Iy6QjPurnWDOOyqqgq1j8wcVmDV5D70di7yXpatS22I1EtNQ5pnaO0a5rhOA+0UQ1k grKaG7bmc0LKB8imfaUcb8Do09ugj3H16uOkrOnsmj1Vs3dcHc6WcHHrNi+TSGjh0Pdp0e2crEK7 iZLFzlSWDoDm4m94ORIojOaC6VmraDx9l7U5znYYRqrB9nt1itpGlk17malObltH19PLmbJSFvpr JAsQ4YPw8Tn5PxW9njVrfrh+Kl8f4bAqoWkOCqhQQnBbAICZI4I4I1FFUMEcEbo3pGi6S/YbnsU9 ibuNE/nx3MZqyD5GgzXUv5VmhpduGby+7izyUTPIghvsjgZI0ipeIMiMyvkWujsgjUVCBoJph6Nd I2hpNjTUBygAL9vyEUIMMJHNZJ5OFc5MrRIsYwxiaFjnkDA5NcIHho/ehZl+xC1itSpkY+cNT33x ITMExIU4tQ4zQdmYrRpQv57Wl8emicSniEkkDQ8M2sEwJGzFq51nEYZp2MH3+JPG5CBSvlxseGB+ WQmQri2ZIl+bP4PQ0zPK89Qv/dMxU0tmO5oZkNM845GxPZoymOe3bHQ0zwvEclND8pMaSdO5F4Uh D5z7oAG+lI3KZhRIT3I1ewb8Fx3ODjIoaXyYy0GMpsRNMyxShPV8xShwhQbJcklFhOU7Vrag9XB9 LyGZPErPWhpxKf3EE0LWYuhcMFMlj0eIkvR2ibO08SFahoG/XglQlElMow69OmxI4oq7GerbkMOu wZijsDogi2yTibHd7j4UAFlPJB9ipGg7NOhBGtJ0fN0eZuFytUBbvckqqgkMhTvghQ0y0waNdnaJ 2+70HGNlyF6BThEmFqeESmC5QhHhM+8cq3j0H3ElvMFJiMUUtL2rSuR6WcoeFi5968UTHc64QwZN nDFeGSNz0yff3g+GziFw1eR7TkJseDfR2hvPDpB8FBi5aFCS1dmkai2Frhmal4A6jUk9KMOLLk5p UkcO5e5W44w3D6Ms0ZkMkEVIHinW5g3QiSAgwuDzNkZRQvphBgSDyRwgWh27YsLlsKiAWd4Ucjez R6b0sTtTRmoWPpyNt5ei2Y9iaaRwlxUtDszZU3w9Y54SJfVaExxhzJ4YDBAzA0b+FD3kv4ftQrzr s7FrfcLahVvlo0zamhykaPcuMS4YYe8BsS5F3IUKzdZuXCBZ8i5mLYzIk8jOUifPNNBSxIcYxlUZ iRkcim6CfJOxLdd7PWC8bLy95UXhtYLKFZPWb2KOTKSY5iakrnUar1LHPMqjxKOULml8JjTOeRiX 7P68elC9HkcgaHImRqwMbIn86F/Rkh78f8AJLyTaNrJ9tEydNn2zFzIJlMjCCVKPZ5dCA5YxwWuM ds8oE+HFN+NUdaJmDg7nCv0eC4XqqF6lSZMMUJmDAVoRcqSLGCdrwKLI+B2NHSexhw5yczJsOULD 2KxLlP7WksHRgeR6ORv4Gi5kiMRNlj1qGLaLFWwc8hono4DFzw9ui93JKiqWFlJZvQYYb9eiQbPh A7AnWpI3uju9/31H+jZajGRtoQMjTrjk5JEzodCpwPaM8xShIqZwPo3Ie5ErPvCMIVm1iuc0n9z5 NkLdeXZ4bmYueDlSZIkXLhmxw0Z4UHIly2YjFIGShAyCcqMTOF3Nihc/cC0hfyyhfSP5Aah/bQA/ CcYB7keHsRy0d2nD3BsA2PUjzI22bw9nUjqP5Ar2fDRZROOvV36KPbiUv7fJspVqshEF6CCn5EUX 99kR+lgxhY10AtEQTGMREITxj9H5PzfYv0S5/F+iL/NMyqc/i/MMNKjmbentxYE911S8DEFYqKYa Znhes8Eq4K42wFS4KwBwBXSFICrgBBDSCukFY6ihFuCt1LpYDMFaRECwK0qgkBXMFcgaxUEDQAIm WgFYCtzJy7OjfxxD+cbdZRUQqecPLO9jCVhR9Lv8YtFFFdTRbqlnk9fSXrEiintV1nB0+Gf+EICr 7f6c8NVqLxlD8k59rRTSet/Vnlk39lnZP3O38ymurQutngp9qgZLOPZ2qsM37xp8uXxX7/x2nLp/ 8z0gaL6Z2EmHVxyYmIB67ZiBRSSSi6+euKlO2WCP0KqOTyvB0cI9yA3KvPIt1IJcgnd8O4ogfj2y wY0PQZFU7rrlpnBIQ5cw8XMlgqSi26jv45SXPKZhYuyXY9zK5AUmSb/iuynS2rkl1VLqRWHjdwn1 8fbXU8FOyNYpGxJ9cuIBD0VAEkbNlPsr6cg6zl8HX7JbQBetHvBnxI/rvE/KTfRYefEYCi351fCh heCGIYuaZT+xYMr+X5nXivk9lBhudTkORBGl9y1q145wll5yXS9T7dIxWAfTArJ5M1FD5KOqaix9 WA+BC759PH6oBJQMvCX3wx3YFVCaqKqxs48Fud5vmollAuuamn4MR0zcnk3Ct45+N/nKv9ZR6qbK l5W8+Lx8OkL+LeNLXlVawhNSbMP1Y9l2q2ipvnR/kp98/B9OGIf08kXVUKjfew2+DjOBETUpL9B/ tUET+lQ9afzSYyLBYCJBcQArFkkJ/OREZAVggftExIOJJFxgWI2iyAFYSH/jSiO4kP3/2wuDDSBU MEMMYXToTGAsIgmhhpkxDZm80MgbymDp2kDSEx0JJiBKxYCDAGERkBMYq8SuoFZtUkQJJEkUWEZB gIxYxIiLJIsJFAYDBYjGCiJFkGRIMixFjEQURUUUFSCQUZEQEhIyRh7IWQKFBjLAoUFtllEhJQQR GMVURUEGMpCwsEREskpS/TJUVRRRRQUFFkFgpFkVRRRRRRRVgoooooooosUWLFFFFiiiiiiiiiii iiiiiirJFAgsI5GImQlljGIiqiIIKkSMYxioioIIIKggiIjGIjGIiMCQioiIqIqQSDGIIQhCEIQh AgcmKn7l9Ko/4qqleNksA/0AwPtAP2QTIFYCL8yx+0Dmror/4ufvIHjsOQQVA1AfmBdPM836gw5V fgf+ySJ/0NdVX8C3+EvDBQ/gn+ZZuf3Yf1RD4/5h/0Fv/UCxGIH//bahAwAIqn/uv/Y1mmAZEEzt /NDQfi0u9ONhxCXf+18ruNAApdd/w++ZP+USo2g2nfDUz0RDtN7PgiGaiEiAgiRCDBFFZJFIJAkF IEFggcWUP8HoKRzD6bcT/xDDqEgthHMAwyMWB/+VcU/3EIxTFeg0BLmWVUQowawKczMr24JiGSUA Y6xxRCgcA9/LvsJ7BF20NatrYQUrJKRAUULEFAoI0QGwmwn+LpA/ihxFQhrg4tB/XM6Nw48eb4go XeO3lidKlhTsOUAe8MAu9mZw2gnv99KglslLSFtL8Vsly20hWspaSiKpUaNKiCUZOYH2f4fm8r+h h9SeuBg3qQHiSzR48vDwscugDWGryVTNzcC6g2eATsAwHiA8InMkCctBCHLHQIaaijTDldgOxQdQ 4HQhBTEbN0ua4Lx+RicmOZwtTB0pGsblHKXGkTKSFImnQIgcgmamrBsKZa7gFw1bREOVfqaNfQUd E9ddh1CYPeLjzM/upFDq2Dmnf2gcQcbdMHEUQRT4hYWIYd/E9ZQkDZNoCCMQ+otYkRgskYiKdHIy SHMgSnS21Y/dgZOGT/6UI8IKnD1EcjaHiaNRYAe4AsROtZbtIQMjr33EbB/9X3wU0A+hwDkBQ0nZ xnPw1g5g8aWhDpdq7DASnEAu0B4nKkQYslEO1qqkUCHogKEICY0G1gTnoxt5eVNyKdeFrQfqFNJF hPVrAOQNoPELgHQcbEOY5j16BudIc4NKgmrvPbqDwiV7ebmo7vuxMD00IFQUzPdycY3fIO9213Bw bNgN/L6FHGFx7Toc24pZ8FHSrgam4BgrtegDZWbYMBAp7B0nRbQHbJCTvooZBnfQ8sfFRflqFONE PRxckFVDJ0kV0VSEJr9IxA4AwAuGI2BwS3KDyDqFsYgODDESOvALrog9Y9q0dwbvR2e0h2KRA2gW IMDZ+Jx55RYzW0AiRVIZCMB2CBhTlix/70mejTiZEHNMShFdKxEMQgr0Xdw21nGQkM1P9MRXvihC B4zj/bteZA88PESwgRNinp6twZhi96BkDoQMOU8ADMMA5x1joPCDMwugHlgcfHTXdR1aldM6fUFI SD1wMIAYhRtw/qKGwKeZKMTgNJREerOmxyEIKBzmeNwNwKxN/F/c+nSuk5tYhpoqUwanbxD8I2w+ cgHkHUYqnYIiQoGgkDrd+TS1oAwx6gYZRGrhWNucLqDbESmR+jOjJo8ZZPvPI3ED0PShWVpaS2kD 8WG493ZsNZehJGEDd0ra5XF7NmmvbK2yrUcsvupCxEkGEnEdZ1ttAQlh8tp6ANyOGYEBNAoGYgyI GaV3BC2IOLjf3WWxYwSfpAtigcgOg4PSCEZY/ruz4urtsnnPZetSPKDFDgVJCUjUHKFOgpOWKWZy nI8ahno46Ot8uGhQdIhwbiMdViwDfMyDvPASAMMDAMDDATUBC7ltaRljSVAojbi3Nw0Zh3PbYkoF Du0gGejetGJ1kYwIxXVcOQGnavLV0JEZFJACMQNzpQNOm+009sEnTRRVB0QkMP+F0vrTPfjsMm9i IXIdqrseOhJiESGJ0gnpgdFs15jXYOI9lJL9zjcKZQrINZZWSsbZbQLXd3JtSZ8j+SuCgjz/U7ZN jDihRBYSTfmTnJH3GyszvdSZwB1kTBhGKCB+hQOKQiEQgS4crYsOrVWS3oSRHEZB7K0C3cDaxutm QhSLM86QvBwP+1HOIHSPIoOhaOl2Kgn3ZHuZyH/0t5/rhh/T/lDImBiU1j/1t02q/0tzR+U+Pnf/ 4lr9kC0P3fmfx+/b/h/lJ/XAqEfy7bOB6MD8L9c/2mP+uPrt0azM0hh8SUD91H0h7/wtFPnvBwPP 9D7z9E/mfv2cdh/sPCvnWil/gCT1wYG2psT8z4lixHN+WbrMBuCGhVNdhHgQU1K6J7MtPGrjUWY+ T9VwwO5TjIkAEKkKnGTCBWSVcsJWEKSpHCQCkLwDGBcwXiY5gN0oHVsI7kAgUXELupYqTWYtsk0P JJEIb6N+jMkNeYB+1bH+Rv1qG7DmfoDWElFEMDidKennI+LF6qfiLzgFj5HQWD+ZcwchjXzchD/A YqZLZI6IdhIf7jVCeB4GCv8vD4dg/3JNYnDsiKTZh1PIPgXqHjTYhh00ylh2n3vhMG2YwqKQXgNo 6JmhhYzLInBATmcHLpaaYLkJEjsrKbG5/aWNFjQblpsRs/s3aXcOAmCXaCUNI7Uwf7W7ZjpLmwuc D2SmTqlRE1lKCGAIdp3ChZzIeYwXNWSBnVFMCIpBidIu8GqxAqLIJTCYSHTH+FmlZZT5YGBjC8Kn FCkqLITPhKRMCKwoA7LSisFAkBYEBNHDJFSAoheKC0KnEGjgphVSKhENjERxiIskx9XZcx9QF8jX G+G6Nw1iNDZs5tG0khLArFANiojBQ1BqpTJl6hhkBpIwMSRMsOhj/QHNrJCBtXFcTigAeA6fFYZh upzZmQ5NBYxBhskjgziCwBsLgBAgGP60JH5pgEhfLuqaCHyXydUVOSmiSm3jCY6bUPSM98SHjtbG xHyD2h3mtMUkmIGoyX3kczg8DAhqIWYcLSQ3mGjidwGJsQzA3LpTQxjqNy0bBs6GZyMIMlP4kUCf oVAoCRLULHQaglFSaz6Z9eYsrT0F55mtPB1bxPCXcp5CqgpOTR34gGTgDUhej1+Xq6q2beYwsSlD tOiGGCWK8TGUyI4GcktJknU/D1VIElQOjgRCS6iQ5TnjO7szp3dDuIysIWbHi7+SF8APCcQ1gFlD I6X2HD1qgyw5pFgGCiR6g0EhYAiV+IY4nZyEFBh2Yg6bKhdbWZLQN8TIiWWUwPBR0HAVANkj4KME 4JgVAqISF9iNfR7Z1bdZjsRUpJrQeFNIdiUYDryVkeWkYauqyqfDp4hPWqrRJNasjYgbgSclcaUW 6Sl0ipyjIosE6O12ItBAYaDgLRd9qIKFpSE2kyJG6QyXLKC6qq2oXZjMGeCojxuljkGnRL2taxDC 6Ogc24rcywyoq9URNY/9d43N2u2tpwY2aeBYXMIXDNDVyKrpCIEIis30iVAGMFQ2wawJKIQzLRkx kwEFhICCCKTXh6ijbKLUXwceYRNFNZMEdVLZKhJRQ6DNckBsx4gNqkA3jSmA3HS6HXgQhL8Bzvd0 DhxSNqNoZKVhGMHQHy223uZJ7Pk0KuHYOMXApTfGzg053Mhcc3IhIBGyBkUUmgaWxB+p8TSay3Jo GVOVSjpZU/NUgoElR7fs/jjAYp/67/2c2h+yEP90a1t+/XjgHBi8JIJYIO4jzCCoEDLQ6JrN8zGG IuGX+j/x2kTJj/7T8zlTQMjzw4ZE3/fQpYuWIDFXKnXI9jBcIm4T/3EiI2uGIhkVIBWzU1nw3RrP XRcYr+SSQImT3a5G1jAb1YmhVMlNDLw0khCypmDZZzW36UO8Hc/64ZPPDcsbDKGlS5Xnmxsa8FuT IYhmcGm7QLaETLLWRNaGeaiYwO58GNjEiFKETY55Iu/TP86FYnUuXJmu5IU3NxzIrJI5OWNSDkaO OFi35oX7l7rwoY+EoNnYZMzMjw0YgcLmQ5PhNrBcwFTJaITrY6CYhE3c0GsGHueV0XKuewsECw4v xoYK4uBcCxqUqAbHY3gIaqKbEzBclUObJDETQbNxHW0lkKXdfPpoeEn8MaxYyYJxOVNk2OOOV3vp g8tc8IFTwpqhDLUNixUnwgnvfBjAqLsMWK6aakCZ3JVIjZawMBE5gSwO5YmOYw3Bc24IGLYLmOCY 58kE1r2WRtX8JT9jgoTO/ZYhAxamyx+sRbSFlCmEXNZ2MiZM32KWMyJIiTLnCkio5qUOC1SkDZot 6aHN1GJjbLnvvLMkq3JkYHhIvPAZbsjRUOmySuY4VIEyBRYMuYu5WnQmSMu/mvj80kOhf7D5OCBW /BMudjY0nsP06cn9kydS5Wz69BjOR0KUOtBxzIUsZJqZGR0/v+3lImXNDXmORLeGhEbupsUNhb1F iOX5InIxwKPJzjnwmFC5+gL1JcUMDKucFX/X2Zs+BrZ2Jz9iP4cpy8H7EG5ABhFEx9qh/S3EdBzm 07Fb6idiRpc1IczInB23Ox1oktDqGCqpMUwlxS2ZA4OgMezn4FMWMkUkaDGFClzpOIotvAoRHA7z PmCaCkngI64CYKJX+jocAhq31ADqKgDmwyNsbbclDw6n3iAJ0JHUgOfcIw1+Zof8qkiJHZkgUPEA cGAYTIUOfZowSubMETZYl/k+l/vMixexBL8uF5FyiC7EDhZNxEIJHMrUpGOs/nAG+Hp0Mry4KV6t 87kPWBUxjuYOq0MhrDnjFTg3iuxxOlChNg03Tux1N5Vxtsw8Y9IU29EE1kRNh5jmwuhLMU44J8zF KGgaJjVK97wsSsWicC/DHPh0t9FjAeHalCZ/E4ScNRjfYa720nUnoLo+B2A9HJRm99A0REIoBEjF AoARKCi7EKII/wSKHrR4uz2NwJR7obC5aNiCyOl6UeJWAHYjcNRBD3w688TcV2E9772r0VRbcxbU hwYZNlkoJOOMDIaOJhDZqkNlJJkCSfrNnHw+s8EWHBJk7/J+CcYAhVqMRK2JFrFtEtqDbLRBFo1B WkClWjCr8uZuEKajH+rMFkwlm9jcuWankn9UiY3cBxfZe8JNzdaJMCn/KEthmIr+NORm2bqkJ4j5 AHt7vhzCfp9lnBycYL/zgUdYuP4PEfa5XiwlBUSMAkWBFYgoxIwYkWEXYCvxfmD1aWIwkXYRjE4r NixXaDbkMNAK40QPrEOYjaCIczCh5DSbLHV6QuI6x4jWlkYQBBuFgS6bMNWgTuTWPEj7+/a8cDyi YwajCxKwO74qMEjJMBggww9Us2f6YSPCLyS4CZnqVyFDtoKBgPGFBQsFjAIQJIgQBOVEyb2IocD2 R6ES+9XFfTANWj/lSUoChpC4bp1Ef8rHWhsB5pJVQkxFG/tFBv1s2Vdw9bFzY4Q0LIhyxNpgjcYg BincC29nVqNaxaCFOhzIO0/OkDgf14rFjWjy82hD+4ihrR4+Q5Dj4Q8BmxUeLi2GwyYYGuiuug1A XQJG7Axg1ELsb0xDeyxYoUDgiD+tKFiQCw1BE46sukboaCwy2BYpYC+d7ONbQOZYWBXJVwyzlEE6 ISBSowEhKoCmCkihR4Og2DhpdCAbW7OqYv4/0BA7A0KcaGJynxas9QmiFFhB2D8Udv4kVAYkifso QP04TA9wHBuxKJGfFDGRIyUzcBYU/AQuUP8c0bnuNMqT7fbi+35mZ1WdPQP3lxhCEBYzIoorfXrI /JCh+ZofmUPUXMgTIc4bGGNHd3JXIZjYhgG/xYMlslP6Qky2ni4yjCUYa096bPCN+kCo2CGDJ1zA 2TwySPGuwsyhU0GJoSzS4shZGPoCJjSetvz4bC2KUY2qHJqbC56ijGRkXGaxSlTBNFHODmJi/Coe QN4nYzg6ESJ2fTGTyeIud7KYTkxoY6bGT5oTIkjR0iw5k0RIyckGHPrp545K+TVF8LXMarQhuOoT P2yKkDfVeIm/IxqTMjnYiTNKEWPC0CZckYic8wJiyIQ3HKa/uyJQM704NRTMoZHJRsk3LDm6TOCT C/CYSHOGJGRYkaEC2RdZ1MFjMccsRJkLsaFdCA46b6EhpAZKGCreDDEGNTkQMnz3RSOuuOV0YNkR jXSw1yMCpQsWG2XH2UMwPC+BjowywX3CXRihyNgY2WMYKXIkTtvC4xe9zyfkjtLzJO+2o5LYciZm hLUiaEzQ0Ry4sxirEhaEFLAUJF/AnY8GMTLXMt1ojc72sctWr8I7N6OENROGZGnnDnSxQyWCR5ox ix0qZOeRJGjJOhwicN+EihO53e9DvUgdHPMm/3ZBfof2k6S01iZYzmfnh4djVj4dLWoelNDrR0+G jZQkSLmhYy5EvAYsXNF8oGCRWpAhyfRFFkazWZY8C2u2BoNZvy7FehHWj2JBYwE3vNyZFjMzODhP bhyhqg5qS60FIi1PEgc2Ki0RonI07tmxNygYM6GBSZcgLqnT+XyNqFyZYczMEE74NtSpHQqiJtE2 bfCzFRbEchbk6wsbHPirR4cLjmokeFukSm8HSIoFzw6duTiTkTHIDwB0iXGPRAiTHMxMGVtiWWg4 8TMU8kEeKef3eZqYLFTBonEpXLOzSY6Ei0yReZCYyX5mwxgMw/WqfQ/HUeF7rA3K7cZkN2smx0PN E/ygDfqFBtldUZUqVr2xaKeoIszsbmvgTDtG3jI6Eu+dcyIpkS5IqZXYqWlhyBYuOde5C+JyMjvD RxdgfqECj8/mtQn/WqhBn2qnxehO16j8fW5QJdX0VosUQkln5Nizgj6wOJH+aDTAPbzu2Iv6wWEB gVRIAdDBXFzNDbaW8Nnb7fiCfZHsUdOmAcYcGDUI2EKe/TfVDV6gV4i3N6z1ct3XSJj50GlGjlEN v1ZmySZv7DPZ9UmtGJrTl0vvKGJrXjAHhUPQ3vsaETiAZKDIaGWT7J+eMpj2Y1otA/PSgJRVEvfl BG4FUX+/1zt8dw5Twcz/v8U+8UAT4afejZHM+cAuRftoX4I/MQJ+kPTX7uQvq/sPlcQXTUEVBbBl ohcYtjE+BcyuoqZhRPhpRYsfzDZyxwD9Zs59Xs9B7pmQdhAIoyBEkSBCMRIqQ9aUiIMQQSMQFYxA FBRgJGMRIDEERFiAkPd7Nk+qCAh6oiqZne4Z8WYXDYXJBCDE07Sg2NwSkIRW4AB6fn2HbVuq7xBl u+W0sXpYbW29uEedvZjgXwDYIXVEYKiJScVYPyVO7kKwOFgQ6OTqWQBPs2P0n8nP3nH2kA+8cidg 8f1ESB8y95H4nlgl2+/W5f9GA0MEKapoPWBUjEhkcmOcGSX8kKrzKdIDxe2pcyZPTk+HtH7xmesC B5F8RM4gGjvhYiWJkzzd1sqekkTyFTR0YbBxIK90VpY1Y3s3a30heToXsRi4xSkzZTpDBkeRf03M cyW6TOkmu5UnKy3qw8jujZksOU6UJMbkQ9yVnqBGnCkag5yZuhUpsOF9miFSmilSBsi5pijbg40S DKccWDJ4RP7qNlLbIOZPNIWhrmxsnh3oalLjGpMmYFJDmLwKZPYsVTbUnIco5UY+CF4VKhW3PHOW Lmz5GpM9xZmXposUGfL+Fq1PSdBzuyRMoe6KYLlzt0J4bHmxzmypgMmJlTBqFjEaikyg64HHM4E5 lDbLBAciQ0tIX+EFERemTHmLUnhjGuEDpciQMFTGKhew0RjYuOykqkS5kPEqbGQfKU9qGo5makBT 6fUgXcXIsZBQsQtKUDUoXmdKj1N3KmZI2hgxFRzCjvdJFmWRkylhjAxUwEC+2UDoWsMERnJBgjgO HiSKFRyRcXA5EUy7K+KK9r1cr2IUResj9X13SzGECRkiISFL0NTB4bCxM+xwMDHQ7CRJ9zkoCqVg UKTcmdzsTMTNHzjgUWpA7mkih9gIm/uE8wWEsA28QpCFNQ9zGlNGZmchxFzX1nEGgPAYz7jyySll FkYlpSLP12rEQJhBtCqpWiqu/50L6Q+4IGZZffpGk70M6Ew+sGe+IckthYChB0ddn3GtgMCIkIHO pxdZ2lc52FdodxgZFzo7bddirnUZdx75nuU3+rBUmfUVFIaGeZo5pIiVYZmNYIaupW4THg0yxsSG KMakSJVrERyWDUqZFz3jFAgZEiI5MsLpBVbQkW/UIIsxixqeB5KHKd0VGAdVPVKeE9DgsMK/QY1O gw7EeBQU1ikxxehyWKkiJOZKfUoZEBTpIkR6kiORncr1kgSAamUSDCBCPVKSSjYdO435HFOnEUy1 nr+ngmbhEiVI/tiRUKBzIkTLGCIMTgcDv6wZIKWufCx9SOjFVUYXBgZfyAuIWvyPFI/UbET33Ta/ aIP6BUKHgkZSUAUDlZDNz6d4nJ1iOcFTUaCHc5rAitCQ9DdKWzMrmWvA2GjSaO7z6OwIRMaIw77R Toge7sBWvESMQwyDFOpMWhjpEXeItgueLTISMSHqg/GDJcGi5QD5H9lJgpkGYQKGFE9Z3NwUd9MJ kYbnEZRrTWiWH+J/KN+Kj5wtMdwiNNECEDkC6eIOvj7M0+OCeq5cghIiSCATySkaDFACNUEIB0jV RtDrVbiCoGt1EHp9uJsbuEeTllfj7KMGPN0NQhxKHs+NueB1UO+ybVB7Sg8z1CWeX1UzT1DDsnB+ +6CJ2n5OS0srTt6+eJ9XAHO+Y3eS+kQZbuEPQJs9wzCJPFDyBWFnj1tl3BvCBTGmNAfOOIkePv35 3heVxUVilU/6dtn03eUmLLwzqhDg4Um4F41DtscugGuSKV7pAr+zVVRPNfmTSiRPwF+/uh9fmDtR Nh/T2yyJXsBiC7DcDELC9BFpiP/4EFQJyo+78/r8DkVxpWoyEYAIkSIQVgQ6O4spMNSQL3DxKQQR UVAKklByMiHiE+8JPxIC4/genSJ36xpjCHdqdCM2/kj8xAeAnuD6ZSBuE9PX168GZmZYl/Yeh/Ub 4eOBFKP4e81rXy2achb9eFBgm6hROLTjUxeHQzAdZZmYZFe8oiaHGJ1IcFMAXkGSaDLTow4NGJBj MOLKaCiRhTRSpGEh0zgzi8Q0MkGBxENyWhYqoQIMOgjCsMwwxUqWP5P1/pv+zhfhiat2iW4W/j+3 qex9TPJCvrta26MrNDFghqg4Nn30MwfTB2GhNZZozjNhoSlFwLSTS8jpAUVRVAUAve6s0zI4/ZvJ RXu+x+wHJfkfZsfJ9n4YpmX7jRgyT0QwaKyDeh7FipY1SxGxMsbNYwRPuJAnSwefP1fsQura8P73 v2CSwZOcSXA+/EbtOERo67Nu5vxyXOec6HBI0M8iQYUjByFSB+xC1ixLB5KTH9+4SCxoPR5npjYe HlrEN889KmjdG5AtIyXJmZXsMeYKjm/dzIkzxJbgR3XZvZE8HIkOOHwgsljhEa5+iF/YAWj4Z+G+ rwwOM0zfbGzyBs4QNWKFAqUofb11JNIiZtKuhALP19UIFPKwEGDwscwFSp9RLDnTNlENly5w2QIT qcJmjMSxnQwOeH0VIky0TVS5w2WXtTJ4UwVP6kLpo8wREz1Ibk6nPLHBQ4TnVKAsTQjNRzMiDqyV pVSqhIcyHMixEaO2xA+ReJE5JPQ2OiOUY3XRAjQoqnJGihLC7+wEICGplChDpogdJsSkemypGRIl 92NjDawSsYlss5o8KECxApccrQ0aOFiJmrGYH6kL9aSQI0dPsvX8fdzAfJeErFSEjZscKSOFBuFb 7se+ebhs1IsYyWwRMkwj6TIt8Ikzh9gkpEKGp56YKSukSQSM4Ou46OU3iZmhKJBaEciY5ag5UwaO F7GtGR3PfbSLZKJZ0MRIIyYHJDnDZ5n8YT2nysET3P2ZcsuNita4nWEISTtDwUvyf+9eLFzHMCqG gGiEKDMLC1akLJ82UqlqJKbCe6BoIaNy8bkpo9gVJoqQRGigg4QfanVeAgQXrfnESJ1GoUO9LFfA 8fBMhnwWPAoRTxwbFCJc0o/iVMiIjpo46TiK70davqOXz9frKnvkhAcCDzkL2ovJ9KaLTGJk9dWQ hAn0jiATxBHEgWDtEueZ5HmbnY9BevkeBE8hTxPLBNhvInNXKkhyTHu9aEC9BUkV9Lcmb7DGqXg6 nroQrlMmRMi+RNxyUytA6XJlB5L0uZKyLjsWJEo6IrJiZ7I1fwP5j/mQxtlq1qcJ5OmIjkTei/z2 h8CwpgODBwSvLKb8GWohaIrjmYaF8EKKX2BhsjaII/gzfX8mB3ZCcGRE9PdGyJxjkv48JH3oZeli QleZwqdv/m5j/jiQwfdqsW5jLmvOUGGJimwiIm+Rl+7zTk9Q7hwKEjhrdzxc7TxxyOfof+U5z/7q fmnsOI9WevX1nKHnkfrC1qKenSLmMPUNjrKlMGwfToHRoRxPb8TU3IOahznX6Id3dDwInvPMdRiR 9Pc3tIInf4+QxOJ2zL0MFihIVQ8Nx2Gg2JcvicR7RT7hXP2ZD0ou2K1EWZd/ciqOhQQOk7X00dYT 9KzXpmccmEUIwHT3mdw79ICWA7U9aRKduCUFi5CjND8CjvR+A9aD9Hk2I8iJ8UaEfiPr5gNiDrjP kffShxs4jjIUZInOK0OomcEYZ0nbALXEXRtR8QOa33TKre+ql7ydYr4D57h7nWjRt+gB9EfYYwxO og084j2HUFkNAViCunbPh8bcUlwwUB0iCoHEgfHEDxR61cEFUMVPNGCbeVHiPp+AHhzHN4/iB+qg 6gfP+l5YoftzX+UdOfqKF9QNdWj1SH4pjC9M9P6j3fjh1t7THloV5ymiQpvY4HaezvkjFGVhDgSe RvOC+TvBnkydM7edu+MmCTwYHKQ2wrITQm9D2E50eHmMPATZROs3ikWGgZnIKKTFiEP6f8ENZWVM w2S2GSSWcyJc9JIuSoVmQwcoNBaUHNVMGfCYusNCh0m2lOJlJCFocabUi/COBkZCdlWRk4qF/sqK 8yO7OlgrpVWSZBa0tz9w6XM2Ns6wsrSgoxBtDQGE8FA/1hu0negX8LZ8AoK7LVkJczrEIan+pHLU clbEMm4uaEQG4ZtKJnHgeU3GPNAhuDONGJqUoMopsw4VnJmG4aZQUAmDmy6eNqWJjGBmFIiiIhdE cXaBRhyzEL0GR5dCXsvzVv0nn4cE+a6iF91KcUTjvQbd6V0Um7KxCwXyoJAsRLkxurEGsBThuGJZ P4ooVFTH0x8MEAULFrossPCaNTZ2Z2RZlp4UzNpIVMff2zWqycMETEw79wrxO8ym5M+by2e/mcTV OY78TaMtCximySJMIoOPYkRV0iSCSSzYgO+wCGUTgJViiggqo4iqVxBqkVikTzrzSOmz1HJrsdpe L19u54E9cmp63IYplMtrigYFC2CFrSbjuPG92ExpaKaMQpMmHJSogi+87H6jk7mR+rq8hylCB8D1 /TfxCYiwKDEvQxgoeo5GYp7CjH4/y3pAUlQuGVxSxkUKETDD1GKU5cppIhFdSYtns0zDmTa7QXKR X9X1+H27d/4/L2rnPL4+HT665w+X6pddeNssvLD+M4dfHt64+vX5/Dafh6MvZfD5wf3HQoe/kXxF L+3s5yWX291AfsYGsYK9oTPAZC4xQewsQ0wOP3RiffYkXcpUzDA4UsVF9DUyZqOqOPIZRaDZZaP6 BJYIMSKPw4S64/CZEsw05ntTEjw8M+jjjnnsx3JF9zYqVhqREzNJjzLTG2Jz342huVJzY1FCAz7m DW+7E/RC5w886fLE7ZIHhAiOYPhrg2kKrMpHyFDtiFTjgmKUMzQiVkVMs8rFSMzQuOKYT24+De7v r47a+7vL3R+HfX7X0tBtO3SGjd249epZvXboUve0fZolPOnh47fVn4y09MsQvDv6R5277dlz2x1X 4Rv21jvaE8obEpTy4+r6vP38c7eHu89vWt9p8Tt0V6Ubifm/1e+989MoeLa1xWVqP5+Wnujni/Pk 9vf5aDqvSXectntOW2dl9Ok4Vlo3G/u7d+M8RtXTg19dOace2uj+nwPTq2XCv5rjHh23yvOdu1/O fj08ujda+Pb2ljK/pjwb2+jU62pzzJ8Q58NYQ9fQ8xsdxT3HQkOYOnWRAl8T16l6goepcuUD5fL4 1MiEKGkRqmgOMepXI1taRal7lz3+qCZhEwQTM7ckMGIkgsUoQInI5qX4LnuQSygnJgoWqKpadNQ5 mKq7wNZ6TmQNIqX2bIZIcL7cyXGKUIGelq3yLpgeTkSJk/UhS6RMhsjcsEzRtiR3dzJ0o3Xuaql5 EsRMEyuBrnTpmcmpW1gqcmLWVYSHfQyMgq+kA0O2MrtvY5IwbSWxOMixc2N00zKhcI0CZE0pE4cW xLShUkRJBbQ0IEYjjfhjPO8s5KMrnkjN3IlCw0qHz52KweDjkM/Wzp6c5srMmUKETUcsSIMOe74H kqfUoeih8lCIoCrGI4Rwg9M7aoXwGKiOKojyBhEZBDuisGBCoAskiMFiqxQERkVGCwjEVGKxVIsV iyKLCQWKsIoojBSwhEKkG8AgZZkMzG4efKUMM2k4i6FPk6xaM2ISBlDKWSNxLuwsZsdiZA6zB0g4 HpowC7SZ4mkckKVEbCXXJ2nqDSOYmt0tlxYAEItfDgQB1oRNZSmpDA1ibAMzjPiBguKJrIiydQSq qDq6yEiSVFSyIrBuICySNIgpMuQUBKQAkcIofPDkjt8IVhjQJFRldLJTLSHDIqCgnViyUlVV8+u2 ruq8+MToRIJ7oeB4EinqWcfwJ1FPE86ceeRnlYul/oFA/tFXr5KOAgS0IIFBTcwGmxrQ03Uj2A6w hEANsSjmgePaoUF4QDe12pyWHTt11M+xM2GK+B1OgpcoROjFahgTQtYdlJlzoZE8yq+miCWT58J5 B7hQVFBQ2vY41ODI9vZkOnSQxNaDHDkeBi+xgxjlELHTppsgu7QYmRy7EucgPoB4zT2qq7w0HbkB CAYInd0q2nXALnMVYIpFDAC9Iph1JPJ2/R8dHy6WxH2LRZbZFFyp+1ihFh1FhD9Bj7poCYLMDy1+ 4hWo4HC44mZKqcyOJpRR7Kg+bLBhgtpGPzURW2PvCkKHEnGg7H3fYPu+1CTLyW6eJIj1mmhkIHwI FzBIcqeZlg+ARNu2Ry6rppBRzhI8SgidSfQrAJogqBVi/qdA6nJ8Ph0nPnXLyoZmjlPiO3genYfU hRzh4gOoR+AgqBEFUOQH9pJR3buLtlWKOHITG9c9d87TQcvOaCE0ZmnOZ9uWZmQ6t/4yRiySLIgE N5iWPCxkshbgUYPgwy1AbJsigkIV0CSQPgaRN8hSguUMwREgvyj9kZeXp1+72y6fXUy+f14l1h8p PXz731+znm7LHn7e0e7afM0f7/tv9uf06enr2T17fD3wBET0EERjv4+KKGqCfeIc3PQUwTFIDseB cfUczygfT7vDQUknvoZGMhOQ5FPeOZZluhIyQuOuppvU325i2NRxGk0GvYCZbwa9K2SynkztUB3K B/QfIAyWAJYlkEo2CWJSJYlIliUIliUiWCFASwQsiWJSJQjIUIlIwpASyJLASgMlIJRpBLEpEsSk SxKRLEpEsSkSxLBLEpEo2CUjCwEsSkSxKRLEpEsSkSxKRLEsEsSwSxKRKDKRLEpEoMpEoMpEsSkS xLBLEpEoMsiWJSJYlIliUiWJSJYlgliUiWJSJYlIliUiWJSJYlIliUiWJSJYlIliUiWJSJRsEoAi tIEKQSAJSsKFiNf+gIGDkq4rEDJGxAV7kf6fJB4jDWp8VsJ0qYMk6cAOwDzR9mg9nr6dt+bo8sPR 35ez1em3j5dev1ezX6Tc7EqwsvPr0te31+Ofbw+v59tfOuW32K3n9ku9wREU+ytpq30P5aDJ/HpX ajctPzFVhLhxV0GqEOMrpTY2XYERPXydOX8otRvaDTq0DSEHsVxazwfGdJM1GhQrvNtw8rKBaxc/ rBJSASX0Hi6Dn7AHQfrBAeR5v98ouFw9oHoTb/SIHcCL7HW/n+/UH7ifpExE9X1OPshYLkRTBPo/ Rj+W0DIE+Kw+B6ylCLCwCf4wWRUHYAWB1KdkxWAGw8pgaSaEBYBkFGTouok0MDRKkxCsEYfsBLll SChUCflOx8j59soDWG544PJKGiEoGUT+bZt+YV6NsvcLV9rBQVKdgVFKMGx5TSHXf848Qo8piGY8 2HoJSUQMHjq8bSFyO1sarIQFeAtjJblxLERUYMUiOJi2uCKaDQMjIoYuB6ahCoxxVQShA/MxCcld 80aApPsj9hASoHMc7+1zqHtN3ZA5B4gTgXR8vrcecSIaILo6D3EJpPU8h6UUwMRL43o9F79lt7oH IBMnLRhZC92EC2BYJQWW4yCLkngGBF5FuqFsRXqBwoGt8dFRGkSSRYBCA5ctAr8Ub6jMpbkTF1hK EkCBEjYfa6UAuGq7FAAx9Q77P97HAgDAANEBU2c1unt9t07QyeHKRhR4FHBstFVWsgG0ICsYIKgQ 3grG1CtHHbwwxSRJJmVXZQBYyfODgc52JiVH9XrDEMvYbTG1Ka6LAZwNfMUGuRmxppb4WaHRrNJe jg55mx8hnwmB4oZ2LNm3lOUne1ZNDRUsuHOptNJFUiKmh3KgbsdSMLwDOENG3ALoXIiQdOAK7wxb I70rjMQpoc1d6AHSsQoHxVSGGvfs1FIUZArymODAjcwsvGuRBoiQYRIEIxYuogUQSJySMKFLjsUi YI2LTAmH9fOJZMgkQCJBYrGMCSCkVNZMc9QFm6wiEsnPjaMopdAHeQQ1MOn3HvIUcTfTY6rkYxqr goDkB/kQgMIAQRNxDS3KOgN7CEIdCMTQfygSd3u1uCxuOW2l6DSwYjIQQVerMvEPQqXSwbs0kCAJ 9kYC+wTpR74Cv6o+YcDT49pa0bIMSDCAwCACgwssoiwBkgjIkkGMQRS0AoKkCH5iKR7J/zI6bDng sigQbhcLFS0AsxktEyPt7v1/U8+K+q35Wyz0GO0D3sISMLMW0tVrB+HM0YMd8UMj9PYdgo2R/Mfz ZJxp+cyR/DwP5afwGJFewdhzwJpA+/GRsRO/1nSNKTMkl6oGSHhbe9O2rvGHsceRz73fOTv0qwKu mUCJkSB/SJvTcib8EeDgYUWeuxgqbbZGxWwjR8IFxifbmtFDYw5I5DNMkcWHZFi5GNHMRLHhQqTC hwjpsYkXPdZrUrQpWURtjMSCB3tdmQ8MkFg5A4RqXHPCemczOuTe8+Avwj++hfOeLrHhGMKnw4Rh H0iRIGyxMepkkaPSOQwWCa+EMnCheIYKkisjJoybOlnNETwoMfPlY/sSVjJYx0yaLL06UIHDwjUa caG6myJ0uMDmiblr7sYHM8rQ/nQt/NnA5usGNSbmHOyCfagmTnap0tEqQLFxHwLuRJmz8EJBQZzo XGtDpEiQKCkugxcoXFIFjEDMjQ0V46sVuSIkSpAciRIGr0M4JJ8FAkR9KF8IEkg/yslqjeFCZcY4 rGlaYxS05EjRAWiRdigYHLfsSrA6UNHWRqxMkWn5kqjk1yFJTJFIFTM0JaB8ymDiP7sFC5mc32ge PjZmnU3NShM30CxkxRSRTWNhxc2HHLFyijIMTnX/lH3J2prLGsOgYOHkUQLgYoqAKOCAIndC52Km jBoa8RN+DqQODg8SkIaYZ4hrNeOoeU94nlyidzzFydyPqD0cfrFO2qmhm7m5vqRJbB5G4qE4h+sC Nux3kw5A7WOxUKUiSDxNpG5WZ4laWJFxyRQefi5E2MhyhEoUHKljcufcgk2HMiJqnx+qxuV3HKlj Tcsb09vapteJQ3QqYJFxaClyhQokDYqHBrWS5o8NG0emsDmGVeFiBGxVH9qvOD/c5kNO5kpbFCRX RI9LPEY1XYKJckYCJQkelYlosKp6bEiZ4gH8+gb7mZgpGekn1GKGxtE1JFittMXpwsGTJYZF7sXm epAgLZ0excufrP7FDHSgYLvbIfDaBJIPbGiA5uOeWfXXyGhkwH9bpADgwfcm/pb79N0PuJEKeHDJ EmdVSgqGyxYqekZvAcykgSP6UwkCsVIGfV1YKCBfabzbG8FA4g8NBLX8tarw9fMA4KaDRQeT/YqI 9pR81RGlRGk436sbFoF5xgnxovBX6RBDX+7tMtvgjn71AA0071fHUPOe71tHEWq0qrW42mwXC4Ek nmjpF9XJo9ZHJWH6MCc1VFaiIhuDgDxWL3y9lXf5sCjnpACBXiCtijvMgwpDVEcC6JA4HIQpJUyE OFyAVKOOGjsGnHKZAYZ1VehHH+GukcRePgh1qu5E7S5GJoKP7z2I0PqdO43kKNzCe9VNfH6Udh3G BxAgc4K3ers1C1XtR0oeqgfl1vxIPPF0yMe8iGcLkF6UgCUIuJUgoc0DGGzMpbwMQRcBXiGxBJBi nYwQLZnHXmKdIfj1xHUjxYIvHN4EO+4D+HsR6twHCGcF4EDNSBwIn0IBZGBBiGIU0jrR+QO07E53 zjM3lZFNGgyAjAhIWpIihYFLAKMSMBQRJD4JCCwWiAQFYEUiLCKopFaICLQFsERIwPawSCiiFkuT kGBUJMLI6Q096shJGP8KoLi3W1hpAr1PsKwNy7D3ie3P0kolGnPVKmY+HQ/8wQOAgqB8i9yEHvoA PocgBpNIcgGhVx9n0R8cYQ+7r6cL/j90xIgfRsV4C6wKYWst/hs0WP6AeSOxUXepYDOJkYHoNbve wPpS7g6yG9Dd3ozxNXs0o+/DaHXFPJ2dTCYQgRaDCDQQN5RsMRI/QzY0YESxdHMUbNn5h9wQKJUp uHfDQ9LF+IvwR+oHL4z7Mn7Ppwn1DGMRQIzSTBJBQFNggRGlAwwCxREdmkNSmpB0aBNgRIbibslN eulupkgscN5PRFIUAbgrRRVVBoSgdKIe5HSj8/AHvE7P3W6l6YOkH07FriN5Y3NDYGAQLFqQslIU FolhQQJYOguofgcC3BjQBP7TEiESArFQDNiitvL62FQsa4GkNBrLJ6rBSXRfrFd6FnedWzBTUxkD /WAwiyAkgyQiASFCpzfGgFzeHACx7YEIxFgwNevQezDCjkolyn8As8RNRvIQZ/gUEItKsAkFvUGL iB7aQ9Hj9cTmMxNoWLUFnJucKiEjGSSQTJH3ETYj5I/bj05L+Osr8nNQ2YbMYPhkYjIj5A/BGz4q RkSKxIsOCj+yRMUcfNH8P19fP2cAecXduBc+pGB5qoK8anAYEhLD/3tkEVv6gV7Va4ZB+fx5wV++ fgJ7Pij+QDrRuD9yOzRw/JH7+JB39yf7P+amhF+vEhqz9OGkNAx6xAxZWSr96GtzLjZYwJDjUwsd Imd8wVzRuGPT/eZB7s/JH4sE4+L3XqDoAjVT8lFYfg7QmH2hJGm0REiCqx1sfzr4W+325T7joDiN p98DP3UdbC5FH3gpy8hwBW6gPHoOOiiMZIScvtP4z7QNiIcetsHcb7reBY7KOsaBXv2O2IRkfghV WMRUUYotpY1KsEpVopfly5RViWlTG2yoNqlFVFIRkKkqkPQMP3/455xGIqjAiIgalNlPZlO0nu2o ce/xfcJc8QoA04or/gQBeV7UfA80Q+vZtR2/7nKiP1CIEAgzccQfCOxURwiijpgKjUU4jyfS3iJr MNJybF5EJ6U6AgPREpf2H94waD3FzAimE/0YXIfnpsE/yhqImzBOJfzfyFjRPT8k3AfpBpRXPx2Q maSQki+JxCNIfNENIV2wSAIz1nNQSKJIvskh+kUKqmxEl0hhU4Nm6UNlK2QpRNr5myD5+zEM2Rjn Q/ysUMgkNB6PQAInoGrp2vcx+X8TQYESL4gZfQjCKRgIdJpUiMIxiBDkKBDHm/gj2+jm6LW8qYUW tRh6sL4VybCMOUuL+pV+kfIxYwMyVEoo5QmW/EWVxKTUVUxYLUSYlJ8o3DLXpbVV0spCMWJMimqI oRYUwIhjQ5jBHA/VHrEDgHMQTnE7U5lPp0ND4MXMSDlknTamKZgMh8E/SwUw73LSs+1P3jJn/1Qq btWSbVk9gkxn/WQOgJQEPgUIVIiSDCEVHYwVOd2AfFMLu10qtI2LGVvARebnBt/EFbgrwBX5FzF8 VP1BoFXogQDvBWlCArIqI0JSIUCsBChgUQEkQD3ieJvUng/jDAH1KYd+fcj6X8Cf+dKXR/mawPJN /dwhBkIRCISEBIQYRkAgQhj0m10GoNCKAzpCAJET7KBFSlTYQCRSjSrEeVsak7PUY4cZ3ywfKVDC g4wbNS0WBA8MQLZ3SiMIXCHLghvOZ5EA4GY5ho0URHMBahYMosQlp6oHBJ9EjuB27QoxQgJ0AbBP 9WKms1SmG5BJYloEzaBXaDkNk4MdEPdtO1HtyEvvExLc5kdSPWjyHpclHjJaJ7kLIpxo0NG5N4HK L9IICyKbYCI/wgIIUJEBgkGBDSAfZ9wSehTuf2nzZcuq5mXPIDZd73ctb+SPUj4I9WpHb/ej9wgO kNX7D2o71D+3m40b34w9Nq96mztV1fxhuR6KFdunSHN+GHR+l6twwtB1fsqwvEkrV3BAjSVJtCDI Jz8UPrREiewFolq9KOxMcN4B8G6Pu/sOpNHsR/j1dhsGfWnlA9KOkA28qH81YnqhwV5tCPURDp9K HkjPUJxo5dJARfEjBID7LJVSexMAbhcy8BccEd5jpLo9aO4R0CLtdYUnpI4kjA1kGz2PP+/q5Pc/ xYGw1qHDRv4ju4FW47WkgZKG62E3hcg+jSa93zPdRZGfs/vY0EqU8hKLEKJUoPtDIxGub0I7O3cj 5UjkIIl9/NDqT8fIDkfaK0nSj4gfDq8sfLk8lH3HmbuL1JVVxuwDSj6/Lm94GKjvVPSj5NlHsR2c /r3nmG5HzyOPP5ngXvekQKfj2bJcva00igX0ABIEdxgxJBsL3wRlAcl7SAdxguudG+TNTInUmFdl lltDDPrJkIhrg8JN86ZhbmZcMJQwMAzMtuCJJxPlmwO0O6EiyfUfZEVVVYxV6PIAknunHwg7XMki RiKBaAqNMUIkHm5BdwK9ahXNpBXYr0qpdGwK8Pdkj8EbgSTrt6z3++u3+eGzAYiICELJqIUnvKRi UjIaGUYT1s+ClaJwZTY5ZrVoELDiIKgekTvPJ6kPeQ6gvdg/H21vPuTTjc5h1gU7bAo6i4xJCST1 CEIPGhlvDxRh2wQXRokUgwgLsCE1ciPIj4BdhsgFKiMEkAhEOAUZtktBhG5AG6oj6NEwlrhmQpUR iwpWTDpCjYS6IZffoIDtbdxT9E8kj6An7ZB5T3E79+60qCD5o2o/xao7KusN4VSooYhmWUYiiIkn 9QUEE/ch80VLsrppt7ilOUXhIUWYnwR3c5G3vp6yathtmJ/K1dXxPbpueon5Hu2ieBuK/vWDbj2H KaCRR5S41x82DiERxCAh6DnB+oNgzH7w/AIFNhzAiVUlNBKidub1AcXR9EfwRwb+sIAnDlDKEMH+ 4Cww/VA9AkmWQjI4ECq+tgLCQYIK4sVZFWlgBkoe3MFei7TZGhfijvDAd4hxEHHlAFbWaUSoA+s/ SFaOTHu2Ai6vLSeyJ+8LhUYZIxfYWKHjRE7zel4XhUFFdqwNTtDkuAX/FHJ7A7QgYGqOZ22tppoY wKpq3UVYvUV6XU2yICusuoZlxG/NS/1T3I92kTr4sT4foIDtV+v5Cmz4fPV376OX2lZGGNrO5aPg D/rIyBAAOM6OdPxStYZQqXs2ohKJKQ1DYGTSuikpoghPD3IKKLBg3IhklFA0GS2T24ZlgplNWbp7 i4fKdfzAftAc/yB6PqbQPyUeoDo3nFx0Q5iB0ma2GwFx3oQPmQCMiPtfNgxD1eco/5JirWt/zgQI oMgKyA+1uBfNkCTuAulxbrQXSFf21/v87/KHyPHmCEYyRVGCOJBgyFLZ2Pfj6SH0z7tj56yGc1si UmfRJMNTQw3DqXEn7Gkp3DHRGoRkO/t4gyMSGwRSlKCR5AsCtKGvZ3Kfw52wRkxJ7nAgCTI8OR+5 0P9eQotJsCkNvYBvDtOZ3IWf29SmI9BwY0EzqTEmCQrJWQRFEMYEyKysk+8wh8IFhVHAYiR10ZHV niYBxQ5IpUBA9sSe40UpoyGDFK1zKKoILMpmEsC4h10edL7JlnpSjCGMKnb0A6lCmspo/UFex5W5 OIFcDiXIw/hjhY5u1HMFckfZrQwLgMcRoyrOcJwK+1rkhCM5aKkigKCsZFUG7zE/M3VpOGCWkyMa bSSSaFE4yyeQeoIGSBzMXYH+gQU5wV9KPcJ3fNH481k7UehTn36rKgcX089/LDLmtLD9LUXOiHio ch4HiXE1iqE5BdroMsAD92oKUuTgviCvIUkHPWoIGswbDwWKISBkwS5A1o6TZ+vtR9yOOYEikgGc WfZVKB9Teg1Ih9wH3alNbOvAKDh2/bjBzwNHdrNZjK0zGrsVBuyQfVCh22GzKFLT47m3g2GxRYcM K7MuW4wzE1NyhSiBul3DJZHKXWqJZo0TTqSwTRgOEAQ17LJjtgSa3o1MkuAuFJDUQpSQ1TJMEQoJ ZchhmjC6J/7H6zgkkUiMiMAmQZ1QRF5ycKYqqc5Myjdhag5UYzWYasrNBPckANoKApoMuSQ4CX3C Ek29mIi3R/DY+Nkezh+SsR7lDxDcm6DticUGElKiNfLj47iYJFHbTQXCCgWxGnAuNFuvGkhZxSwN I4KRApoLO9HidLjCFGCNhgr83t7DSQOeBaWVEYBqKH4enNshhOsJCoUsjUTbsQmZiSMgRbMN8CAr ccTExPv1ZKDxYfOFQ9dv6Sy9SEO5J4V6LaoGMsA/ilZJDBgFSCNdW5EwAhCz7iUlhhGQwSmWSzQB hImBZAwpRrLMGYH0QiI2LCL3I0WHoLo8QRGIPnApEjAuUur5KdS4EBzigXXlhxxxfUjmCt8MKs5i huD7KeX4P4hn2VpsmnrzQwrDpsYEx/GYMYn4IaNtW2ULED9pIef3pJiE9aRSIgLAWQikGDBURiCw iisICkgDrIBRJBTlVIMFWIxUA7DaeLVEymBnE7BRyCiwvUlI+cEDq94K5HUdampKMQhB9UYEdzBD cYPHwKaIVUlBIl1NwJP3psSXP+9iXHQbuUAxQ2XCnJSkxa/lpSyYE5pCjmYEEsJSZxEhBU6yA+uK NiByBEveEo+ev2rmPvQVQ6AcXaK7gregXE6wDcTXc+VOe9PRAmIMYGmCgfhAImJwOIc43Lre45Wb iJ+eOL+R+ZDFQz+UwbmBCxljNz+HwJ3XkKwInghUQEYQU8kljGOiJWKEVGFEArJBZINBCVYKREkE QgIACGhJEYRVkWApFbOEFUiRNkNywFYDZgqLEwaR9yOoFLEEiQioaDRQIbhCZgYQiEJBKUrIAkWx JVJFFiqCZJEO9D+1KQb7GlPvErxh66qTkY85oTU6AdE1kBFI0BQT6CGrA6Qe9HcZPQjQY/A003lr UeBBjCTBAIgDAK+/osk2MWAIau/+UhRtICWY+j0EKUmRTf7Gels3n88DWDhcZEkXapRo6ANIfqB7 N/ko8aPlIgqhxn3o7h0dCOCOB08qO8HEOUOIeN5UTkigbdgjyA/REroBc+x3PkvbZu/vEMgAGg2U ttrRgULIIwkYQZP8wgAfaJzDBWD+n71+K0QGEYJABiEEDMVwQOs+3JnjMR8T70dT2kggkiqEA+fz oLMUYvarwE5W59ZINoSKQ/T6GlHrNpzqLBRfDsR6UEMUeHA8h/cC9Sh0d6d7oPEV1KMAWuB9oSPV 1VzEef8vt6SF37oYRe3kPFBfBf5p0MiClleRZQNULR5BDuPajQgl2CCQWBgHt1SRhEYwCBwOGF0F uwUhDqMMLnqNsJBRhEVmIintIoZxAUNIRATSQA5mKl2nMMgGQP72ywFfQ+Ip6Y6nI1BTuNRqgiwc 4peI8isXAibFPMPd+gczsUdIgYiwDX4bShvAhE9pBS3G0Cpw3iUHODh2vp5BOTVKMmkJajalZFgk H8iCFoIGBFFKgOAURhFnyAOUFw1uG2CFgostlcgyQETFQ3DOa6xJckSmmUrY+qrz+7cp3g/9dCoh lbUAHQ9/SUhKWJS9NWcg3bmbqFgKxACArtSArQKFH7ZI8BZpgIlMCsCGxpGgpCHVwAF2kUtpP84K ejToeZ8vM4HWwYe7HjAzUtSH5I6lPio8S4m93k6Gh4NGzAgBCFlHE2aXq24heGieuxxkOIIwIe0l ekoLQtPqjozNtAUhBG6GZPKOgdNKBO2u8wAmmRYBP1sJU5jJxjTboMsIwM+p1Qkd8CiACd8Vojbk LiQgAkyQyImlSNmFKCMhJMgwZQkoUAxmBJ6tT9QYBocEKqFKUSIxDeFBgVfkPPv/IokJOZ7PE3nY Wx458sM8DUeE92jxtNh+jqw8WYzjZiNtXvYxOYMu+cme3qYemgufX7PA0B57PkrLJh5As3bI1oqo IQpQpas1gFRGQZTzOSgr4A8nejrR+yOT5+o8Q6eJHp3cxbfvn7kLsD/fxIBqdGw8/BaTYegyTgwy G5DASJkabDSFwuPKdZ4nsRt54oY26keMK4KJwFoO12fyBWyojvpVBNxY3BE9m+gsQ9aPsR4ALtFN SggdKJ1o2AK8J+XlVtrg8wIcjoMbozmeCs3cgShFMFc1TejQI+SQQOiHEFzRw9+oGfb8UcjPwPk7 vMDgb0eCd46GqTdJ5jjkNqAupkhvOZ80dpjx7E1udlczuO4oxnvowF2tJtjZjywNIgkPh8aOBNPE Adc7JhPIDFDY8dOwJEIe94HvotYaNFjXFOwnJRx0W3QPQAamn2nzIWe0ejbBWFkFHkh99+8JI6UU IYDVOfo/PmM4yIyDIvejEKB5ehHwzDv5WhMokyDlNgOw2nW1GB/x/xQfx/SUfO+H/Fzy/d5abXWK smWqjNNZUowqYJCaEME0ilsqMKljEH6EiZYbdCRw/6LjMpV4oVFEQrKiqm//4w5SeNptm7GnOVGt ERFgpMcVOkPH/Dgxh50owWIw4ZVVYnLJOkDLZJAWPz9Z+AP8EfgffgDze0gQOs/vIZo5CeP3w+89 L8yfI+1kd6Ns1w/MT8OP3gb0FUPYcEdf3evZ+2zcKwxvX7oZ6EfzxyH+nUAc37vnsOhOcDBHeJRz nERgQ+SMTn5QeVHtTEQNH67fv5l0QfzhOfPxZ8RMEflfUZRgUStgpESIyT9mTHjINS5AwRUkgxNF lAZKJCoKLBiAIqIMSMGQSKCIgxgSsqAgQP8SFYyDBIDyFOMFrxctDgRFiM0UYnyJNYZkwIemN3Bp I0xoQCsnxRrFQ6EdmP9rgAc5ZFeRHRcFy14I4I9fBVOGWG92BZqWToYN228poQllwLtNxoGoRg3Y 2W7TGC2I3Qa4EwVs3AKCClligd9N26AiVwMBeVRYvOCtk6DA/YvRJdc3cPEoZhxw5FQXgjFDMLKH 7Y223YBCEjESJ9hINWRVGuArZXU5Rk9LYIsyH+xmD9A6gwMJYzGZKZTJaJ0ONkMBgxwyDh2q+1tw fp8K+E/CYtU0GUo4y2yg1JYfKHsPQ7KqobYFFYsViKiQSgfknx/404+ePvPXwTwD8igWY23dHMDe C9wPzg9Ow2S37jU5z/Q8QKC3UlUH7MCpDdR+8uSfXAwYgbPTkvohdTCj6DuRKLoR5goOTYCsEioj ECACJzBgFxhwjwGWA6eex3SEHMPA3PK39TW2xoNHfZ/Y1oBV4whzEVzOSfvBXMFboiBqR1KgBtdq r7NbYG4xFLlehvAuwlkMitItx3wUcCIvGoRbgpzaXTGCajBAKaxR0FkMwHATRcsAPQAybAkBIYJJ DQCIKIIMGbZSpIpZKdPgJfUPeQbiJlEKQXSK0gXA23Ft/cwSiQYAB6CCwiFQOtSkCgfA2G4t1n+k dPPNBXKFmL2dP9mBC7/KBmONwwJcptGi7yp2wkI6KWvKGFh2czPx6wDpPlyKFdnYC0pYjaSED75I SBQBlLaxFE02ZA7T9+axsBA3EkA2cfGFCfxOJQkmyqNLKytAYhSBFAlBRGhIDiWBX12pvKCCuagn 38HiebnOefZyHDC+HLRa/W/in21n23dBvDoR5cT8TnITniCA+yXxwCgkAGMBiSEUZjJQKxiSqAQK UI/QOApjnkdempn9vb+vzMyMl7K1Gpch/xGL/neuVbTJ7z+P0gS1DmKPCxGSk6PvPo7oVz4aLl1Y 6KfsDKJXdnIRO+FfuhpwikKZd26tQpHOoyaIUvHXFiNavv+A6I8C09gLKBvZ/kJsakYYiBirwVns EUMVgiSZXKoPFIBhqaYGHYvZk+1Jr+l4uBznNmFj3GJhE2MP0upRIFrRKlpkCjIhJTIklNOrYbhy WnbFcexsUIqwfXhqQ9fAaTsaYmoUENWJERexudoKKzwcqt1TF4vFMJtNmhz0bOcKwKixePSEbDLm rA9yrkPgoxgwMzK4QCT6YD5IwFpW04RQkIbIIPZcwRIN35l0HiL4hoWZw+IJbvatsrxo8CRwqzxx wwxSltfQhwPy6Ej47btxJfiFSNcpVPx2wGGSOCLGAkBbzdVjus6lMVR+VU4UTKSd05nSaAsjSbg1 hKJyUS+AgjKmhh8zOU46C/N6nRiI4YMclzmKZUVNOoERhYvCc08TuEybu6TMaSbmVZ1o1woMSCjJ 8gvYNo8CkbkmPZN8yb16gyA63rUVbq7akpsoYRCaDcb2KqjjdjvaeJI5iCoHHzyaUcOGIZgddkeC qfn5g+Yps6EMkefm4PJNmVcNnLa95YwvX1hUvrf1nNV2oBtIM/TX3+XifiOJ5RPuRQMEel0uIakY hZ1DZw7DUYYOYZQlJcoIdNIGrVizdqls4VMQlFSqvY1UP4eT2zcgJAogffGiqoqqIWB2I+wCwb+1 HUHcjs0cB/AH6Jbu0/Y/IhRsE+HwmUC5wlifSYgQIwsHSD813AruRoeA37vPGNTv/8kuWkbjZqLI DIgsM/EsdkLjb71IdHUwncGEN51Owoxx05VxWJ+m4yijKB7hAUPLGVVawfV9sFYIJswgiQQT7KeJ gF93smYMQ52hPRuHEcDe7hOe3iGkPUISxFqTSU0ERIlOu35lmhps2GwJTfC1XCzp1ID7e/yiCDAn nDGCyIwihFICiIRZFiMIosWKLBYIxYxiIpIKRQWIwFkRgpAVVFARWKIxYqwWRRQUWSLBESDkIo/v gnyR0J8tgUeUB70dKO5NewkNrxIhkexRZzl0GmIxhJJB7Oig5s4GhRAdJadCOvoRQ4GayMPr0Snh efja1ilGAjNIpty2RD3Uom3TDH7WfnQP1s3zfTm6BWLrnMUExovYUSFv4d7hyIACJNjAAt/oymm5 fBIa1MyFjIVRJYqs7DXpnSAcIL+urvA7P6GcMkwt8NneYbySS83vlWL+DvKiICLHd8bcYgggBJ+E rQ7oYwY5BvflN3Rx39mLocil/xiBaJGRhCAMIEkiRYH8Uqf5GV7sJRFJBZIVgLP2wfuQ9P3dh4Oe WsT0iD2xJEJEkCQJAkBSLBQWKSLIoCigoKCgoLFBYsigoKCgoLFigoKCgoKCxQWCgoKCgsUFBQUF BQUFBQUFBRYSRJFCg+qPMdnuMvnodIHmh6XYQ7PyXPkh+XsB8y/dg658q77M9ogEgi1QwhGPfSFD 44FWJAmCKbbF2Njy5ALHxMheVURsc8LAGgd3JSJmjVAAwCIDYKrZjrPLbQWvPZA3K5oLw0dGrtmB gY81OIzIkLhTgM1xvbzQphmFmBfC/0TcKPIdfr3V6hNh0dGw4TMrSCuxS1ryVTTJCqehhYjicUBd uT1BuYp+ChmnE4Img1jYyHIb/MARIuhDNfAqmwR0Xvrwo0hRiES33WoIO1jWVOGBQxIQC1I0N9+d 158igiGWOhtQwi+yBRESDAjFSQ5TlRwhC7/qHEFdWvMJauqk3jNxzUq+SsdSUqPAhyVcg9/6I2Oh N6niIeSPDVSOGdt7n4/CUnSJ/0MHpv8/JWq4tU27I9ctVtTUD5lGG7DlsXmOQeQEWYT6etKfl95d 1GFyqkEmxK6tYUmKhNhncLuu2Uw8LDg0V1BFcizuW9t9sB9R2y6ElncBM1WGZSGCTGbxxFBGYO2d oKOR0SJqIOqQJhE/vDOxYIupj7pQFdMAhxRehXDhnkLENkMwYtAIgEfLpH+CtEYBTJnPdsMCiSnf ngyG3ys3l8C1IKYdusJpO6BrC6hopMyDaA8GUl1MEwkKwI7oGyCTx3Jrep4zo7sABDZxCzgsUpS+ M7HUdULe84NGCKPLbLNGSxIsZFeTkzDHyZyyaQXskzVJDhlYTvSOYgRYGGIGb3UhdJwTJWGKjPkf PNDQt4cwEydGEwDXew4NGutFO9JvJeGSsWdQpzMYOCBs31Jm+LxwYTxDVkoqV5kCJIcKFEZNLWi4 xIwQnYiMxAgiNQBNppTY2ZgZVXkzIN2qRUS7NQ8TZkIDBt0Pb32MbqvCKjai6CszoFIFs7IwYFd1 BWXWZG3ADEnqvEB4MREPDYmk4TwBXBSgyWBCEAUOISpnnkMa4Gbt9ym2rYsCAVwhQrrV3qsMhhoL dgdDCKmHGdibXKwAiKCRHumAixIAPEzU1NDvibh6h3AnKcTYdpgdhCSaQolQ2kPLVDSSod8sxiwW bZN5QXaFfEs4nXY2eNpaUstFo2lpElBBBE5pknAJO7IcYVNBpNH3XR/l9QPvBt60ZrE9/BJh9hPv B+7LT+XN+iNA6EeOkceLXyzbMatg3lFucviCtxBYBs9w8SPvZpw+SEswMk1EhxRTdLo3NF+BggYF 0JDQyBomUO8TkZiBZYyQhHZgGzZgb4DclkGMnFiUMHA0pcwYjmlLkqI5NwpURtiQVMAQex6CfhFp HSY2E9x7qcCF6U8YhTFEz1IaTuywNiVytQGCQSGIiH+UAeNGCB9EeMQx05zUCaEeNHPaXOYiwIoP GwiAa6qEprsRvkCtnRrGhIETSdp47A7TRoYBZqWGKjEZBgdnwiAxahhdIkTUGuBLFgIj2sRagNA6 9ep0tiBimlmnmC5RnJZVgK3LuhZ6Hh2n3Iv6ilAxWcwh7pM0bEo1yQhgoGQuxY8SLujtghTAVr4m kzPbA4/pcUUdwKyixpQNK8g9C8aHKryIZPYj0H1RhFmJS8RALEQ0FNwgNpIVcLCzBGpAYhjJURC4 UMBRiR2A9nZSbDlKG96UqqQAqLKoR90R1xHUh/zhNa613mAXiPPqKHRB+/8NlsAOY02eIeJhJsFX bghSr3d1t4K/Xj0kI8KCg/NCF9pIvSwfqX9YCSdRUjIOKbRKVLTlLNIIZKhlCQP6RMI+h6sM2WTh uFQcccMdzIB3mgDl2ahKSd5TRoIalsG0SECxVuMHTtezY6x0Bm6Kla6BPh/E5GuSlT9XgGK9srXD j13QCgrBHfj1xP7sRMI2In50dcxgq1F6CAUdVBjCRQuSEFvegsXKEwjzKENgUq/2J/qG0hA8TFTA PsQpN8h0OIQ/DqVBStgIpj4xHJgSblNprt7T3EKcWe5NB4DrCBoUIFCQLhgdgXqdTEwRVHIuam4W IADvQCKVGzhSgmA3FcSQnhRXe0KlFnxsOHAiJqgbYmTNlNFbW3kbk0zhIIDDfsK0o6m7mRkdJQK/ chkduI7UcF8AOUKTa7E36lsGk0NgXEcgfsjkXdiTN+pBVGKCxSKMYG58oj7golaMVIPvR4y5/L/c s76MEVU9oqIBAVX0t0DA+KqbQXmn70d55hknQb1HrB0fkJ+KtWR/b8E6uMEDeBqQdSmRF+AdoYB9 k2rYUc0CPmGQ8ogqBfsUE8DxN8BuQXhraodlbo2vyozcJd2kiNKbEV8ExpEMWIIYRTWjETJMwKDe BD+CPiC6bakdhpOUHmR5eoOcECw8uoQXYLTYEDgxVdBhzg5WY4HBlwgFEQf9DBBdj0HOWMDVwYJ+ +eA7Rdyh4hCEPLW4aA/I/KmM/KgbMQ+4D+Zh+L11TasZANIDAbxJG8FbMcj3BbLUGdrh1IxG7ByA HAMmrh0HB+45MNzqyLocz+lnPxoF0ouTyE9nQns2J2kiRgYUHWmDT9Yr3g+j1kYBI5oXDPCQ9IUS JCgKVNo1tbVdw5hsdCpDBcwh4qEMjiPBOfYBQDoR0JvBgF0ehOU6DdQUR0I+aPPjp0+oDz1AHnv1 YAOCOGnW/E2nIHobA65zYC3hGKef7I7EFUOdHr2gvuRwR4FkcPcfwaN0gkyDIKJ2FpMPYFgk0Qwy CgzxD0BtDcmBgZ75Yo4j/m0sIMKBFO6506yqgKv6hAQD27f3fGv64AOlmjj+op4HVvwOMyjbMC5S iA9/iJ1KP8MEeHoRzNCm+cHpCzYD9GMkSIlRhDAo6z95b5A+xHf8UdnrTQPVmIe3k1I5q5nIj5I8 4YGoh6yy9AoqxBkEgyEGCQiCQGQSAKQNa0ILUFuSTSRSfkDJJJYokC+EwlQKIfAH6gdyOYD70fij d+eavjoTTLHwRD2g2R2m0g9jAWMChIgQCMSDCMjJID8gY+96eUOXquEdDtPUDWpHucxdP6gZo8XF n0I2o7Y3JaVzZ2veqlZAdCO+lPw8qQaK4WTyCP4QfiQOZB+9opD+geMhgmKBfwM/GmuROU2IjICw qUEvLRsC8ChKP0/dLAhyGSnR3H5ma8fHRWwrlV6vBX0iPut1fNHt2G8O1BVDuPYj5q+G5uweKJv8 6PdqTm1ijziFvPjRsjbUj7kFUOk0GKAdoMF6UfPiN50HA9pgdEXawYw8kWEBT42zSAqal55q8nXZ FNbxut76Cv2gp7y4e6dyyI6PG0wL4xQHQDHRq11WvDG9jCi9/4tjd2PuR/FHd2e43MJJJJ6EZzI7 S9oQkk3/AUujiIDsAv0HQK9p0I9nia0e4QH44G0h1Ryhl0V1valv4tGbFukY5p7g87t4TJSNAwv3 lFwjSMNuzoSFYgOwhZQYz3kAmdp4wnvxT5ZG7gHErmB37RzdMA9onuEglHp6d+/yvdN0a06y6YTw mazW/CE39Gb3x8kD62HYQiQCQEhtX26zY7WNHURoLBAp5oRkm2B0cwyqapoIxj7p/EgZGZDuR1bE NKFI+niDwE/NHHjR9Z5vpR9CPo7XiVDIdiOQpYTl++jmPmFIWvRkfH4+G/DOfKSNFSmoBIdkDTpp cR0aizH2X9VzrOwhQmqCH3S7F0Bt70bZGBCjcRosQ0oCL2oxFfyMC4YBAoLgpzCnoR2ilaUbc8fj 9xVpzmX4aIXH5MHxDI+Bnsl+iYz1y5MjQ1QYaoBhZvL4TQambwmjZhgSTc8rKwFm7NMOCmiQlOKO Wc02s1eMzykmnU45nGVwq/pmpQRe748V8yznt43Nh0S4Ek3ceHMZdQNZNQwFYh1I+Svej3pcH6e9 D4/hbnFPWjsA6UeebeK9FOii1kKcGAgWKCg5DgUrwHkEoxAPc+y4p7/p8A97yi6Pv+aOzcj1GkNS POYI73EQHlXRB6zJX5o8zyHCCHsR73iDUHzFOlQ50YruFEh7Iek2CcaO4dhBgz1b0Hl2diMVD+sF QrQcqPMbCMgSSSSKeCODsvdjJJz9j4HMKbxPLZqN8WQbo9SP2ur3vp1F0dvWJ96OnV5o94eKeKOD ZGI7DzA7eMHVvEOpHeID28m1HQIIuru30lhEUhFQT1wA6ANGzH0I3AOfA9LrBXf6Abj64cy9KMG4 niJ3AdgG+yMBdKPQji6BTtR6UfNH7+b7vkQtbDGgh+0CwP8I6d3dc3NWhhgzJMZ//i7kinChIPIp 5Jo= ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-08-05 2:33 ` Paul Eggert @ 2011-08-05 9:26 ` Jan Djärv 2011-08-06 1:24 ` Paul Eggert 0 siblings, 1 reply; 13+ messages in thread From: Jan Djärv @ 2011-08-05 9:26 UTC (permalink / raw) To: Paul Eggert; +Cc: 9196 Paul Eggert skrev 2011-08-05 04:33: > === modified file 'src/xrdb.c' > --- src/xrdb.c 2011-07-10 08:20:10 +0000 > +++ src/xrdb.c 2011-08-05 02:15:35 +0000 > @@ -426,24 +426,22 @@ > { > XrmDatabase db; > char *p; > - char *path = 0, *home = 0; > - const char *host; > + char *path = 0; > > if ((p = getenv ("XENVIRONMENT")) == NULL) > { > - home = gethomedir (); > - host = get_system_name (); > - path = (char *) xmalloc (strlen (home) > - + sizeof (".Xdefaults-") > - + strlen (host)); > - sprintf (path, "%s%s%s", home, ".Xdefaults-", host); > + static char const xdefaults[] = ".Xdefaults-"; I think there might be problems with dumping and static variables. There is a reason for initializing static variables in init-functions rather in an initializer. I don't remember the details. > + char *home = gethomedir (); > + char const *host = get_system_name (); > + ptrdiff_t pathsize = strlen (home) + sizeof xdefaults + strlen (host); > + path = (char *) xrealloc (home, pathsize); > + strcat (strcat (path, xdefaults), host); > p = path; > } > > db = XrmGetFileDatabase (p); > > xfree (path); > - xfree (home); Since home isn't free:d, you have introduced a memory leak. > === modified file 'src/xselect.c' > --- src/xselect.c 2011-07-13 03:45:56 +0000 > +++ src/xselect.c 2011-08-05 02:15:35 +0000 > @@ -66,22 +66,15 @@ > static void wait_for_property_change (struct prop_location *); > static Lisp_Object x_get_foreign_selection (Lisp_Object, Lisp_Object, > Lisp_Object, Lisp_Object); > -static void x_get_window_property (Display *, Window, Atom, > - unsigned char **, int *, > - Atom *, int *, unsigned long *, int); > -static void receive_incremental_selection (Display *, Window, Atom, > - Lisp_Object, unsigned, > - unsigned char **, int *, > - Atom *, int *, unsigned long *); > static Lisp_Object x_get_window_property_as_lisp_data (Display *, > Window, Atom, > Lisp_Object, Atom); > static Lisp_Object selection_data_to_lisp_data (Display *, > const unsigned char *, > - int, Atom, int); > + ptrdiff_t, Atom, int); > static void lisp_data_to_selection_data (Display *, Lisp_Object, > unsigned char **, Atom *, > - unsigned *, int *, int *); > + ptrdiff_t *, int *, int *); > static Lisp_Object clean_local_selection_data (Lisp_Object); > > /* Printing traces to stderr. */ > @@ -114,15 +107,37 @@ > static Lisp_Object Qforeign_selection; > static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions; > > +/* Bytes needed to represent 'long' data. This is as per libX11; it > + is not necessarily sizeof (long). */ > +#define X_LONG_SIZE 4 > + > +/* Maximum unsigned 'short' and 'long' values suitable for libX11. */ > +#define X_USHRT_MAX 0xffff > +#define X_ULONG_MAX 0xffffffff > + > /* If this is a smaller number than the max-request-size of the display, > emacs will use INCR selection transfer when the selection is larger > than this. The max-request-size is usually around 64k, so if you want > emacs to use incremental selection transfers when the selection is > smaller than that, set this. I added this mostly for debugging the > - incremental transfer stuff, but it might improve server performance. */ > -#define MAX_SELECTION_QUANTUM 0xFFFFFF > - > -#define SELECTION_QUANTUM(dpy) ((XMaxRequestSize(dpy)<< 2) - 100) > + incremental transfer stuff, but it might improve server performance. > + > + This value cannot exceed INT_MAX / max (X_LONG_SIZE, sizeof (long)) > + because it is multiplied by X_LONG_SIZE and by sizeof (long) in > + subscript calculations. Similarly for PTRDIFF_MAX - 1 or SIZE_MAX > + - 1 in place of INT_MAX. */ > +#define MAX_SELECTION_QUANTUM \ > + ((int) min (0xFFFFFF, (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) - 1) \ > + / max (X_LONG_SIZE, sizeof (long))))) > + > +static int > +selection_quantum (Display *display) > +{ > + long mrs = XMaxRequestSize (display); > + return (mrs< MAX_SELECTION_QUANTUM / X_LONG_SIZE + 25 > + ? (mrs - 25) * X_LONG_SIZE > + : MAX_SELECTION_QUANTUM); > +} > > #define LOCAL_SELECTION(selection_symbol,dpyinfo) \ > assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist) > @@ -477,7 +492,7 @@ > struct selection_data > { > unsigned char *data; > - unsigned int size; > + ptrdiff_t size; > int format; > Atom type; > int nofree; > @@ -581,14 +596,11 @@ > XSelectionEvent *reply =&(reply_base.xselection); > Display *display = SELECTION_EVENT_DISPLAY (event); > Window window = SELECTION_EVENT_REQUESTOR (event); > - int bytes_remaining; > - int max_bytes = SELECTION_QUANTUM (display); > + ptrdiff_t bytes_remaining; > + int max_bytes = selection_quantum (display); > int count = SPECPDL_INDEX (); > struct selection_data *cs; > > - if (max_bytes> MAX_SELECTION_QUANTUM) > - max_bytes = MAX_SELECTION_QUANTUM; > - > reply->type = SelectionNotify; > reply->display = display; > reply->requestor = window; > @@ -616,11 +628,12 @@ > if (cs->property == None) > continue; > > - bytes_remaining = cs->size * (cs->format / 8); > + bytes_remaining = cs->size; > + bytes_remaining *= cs->format>> 3; > if (bytes_remaining<= max_bytes) > { > /* Send all the data at once, with minimal handshaking. */ > - TRACE1 ("Sending all %d bytes", bytes_remaining); > + TRACE1 ("Sending all %"pD"d bytes", bytes_remaining); > XChangeProperty (display, window, cs->property, > cs->type, cs->format, PropModeReplace, > cs->data, cs->size); > @@ -628,9 +641,9 @@ > else > { > /* Send an INCR tag to initiate incremental transfer. */ > - long value[1]; > + unsigned long value[1]; This is wrong, X11 expects long, not unsigned long. Even if the value here can't be negative, it can be in other situations, so stick with long for consistency. > > - TRACE2 ("Start sending %d bytes incrementally (%s)", > + TRACE2 ("Start sending %"pD"d bytes incrementally (%s)", > bytes_remaining, XGetAtomName (display, cs->property)); > cs->wait_object > = expect_property_change (display, window, cs->property, > @@ -638,7 +651,7 @@ > > /* XChangeProperty expects an array of long even if long is > more than 32 bits. */ > - value[0] = bytes_remaining; > + value[0] = min (bytes_remaining, X_ULONG_MAX); X_ULONG_MAX is wrong, max value is LONG_MAX as X11 can accept negative values. > @@ -1269,19 +1283,28 @@ > > static void > x_get_window_property (Display *display, Window window, Atom property, > - unsigned char **data_ret, int *bytes_ret, > + unsigned char **data_ret, ptrdiff_t *bytes_ret, > Atom *actual_type_ret, int *actual_format_ret, > unsigned long *actual_size_ret, int delete_p) > { > - int total_size; > + ptrdiff_t total_size; > unsigned long bytes_remaining; > - int offset = 0; > + ptrdiff_t offset = 0; > + unsigned char *data = 0; > unsigned char *tmp_data = 0; > int result; > - int buffer_size = SELECTION_QUANTUM (display); > - > - if (buffer_size> MAX_SELECTION_QUANTUM) > - buffer_size = MAX_SELECTION_QUANTUM; > + int buffer_size = selection_quantum (display); > + > + /* Wide enough to avoid overflow in expressions using it. */ > + ptrdiff_t x_long_size = X_LONG_SIZE; > + > + /* Maximum value for TOTAL_SIZE. It cannot exceed PTRDIFF_MAX - 1 > + and SIZE_MAX - 1, for an extra byte at the end. And it cannot > + exceed LONG_MAX * X_LONG_SIZE, for XGetWindowProperty. */ > + ptrdiff_t total_size_max = > + ((min (PTRDIFF_MAX, SIZE_MAX) - 1) / x_long_size< LONG_MAX > + ? min (PTRDIFF_MAX, SIZE_MAX) - 1 > + : LONG_MAX * x_long_size); > > BLOCK_INPUT; > > @@ -1292,49 +1315,44 @@ > actual_size_ret, > &bytes_remaining,&tmp_data); > if (result != Success) > - { > - UNBLOCK_INPUT; > - *data_ret = 0; > - *bytes_ret = 0; > - return; > - } > + goto done; > > /* This was allocated by Xlib, so use XFree. */ > XFree ((char *) tmp_data); > > if (*actual_type_ret == None || *actual_format_ret == 0) > - { > - UNBLOCK_INPUT; > - return; > - } > + goto done; > > - total_size = bytes_remaining + 1; > - *data_ret = (unsigned char *) xmalloc (total_size); > + if (total_size_max< bytes_remaining) > + goto size_overflow; > + total_size = bytes_remaining; > + data = malloc (total_size + 1); Why isn't xmalloc used here? > + if (! data) > + goto memory_exhausted; > > /* Now read, until we've gotten it all. */ > while (bytes_remaining) > { > -#ifdef TRACE_SELECTION > - unsigned long last = bytes_remaining; > -#endif > + ptrdiff_t bytes_gotten; > + int bytes_per_item; > result > = XGetWindowProperty (display, window, property, > - (long)offset/4, (long)buffer_size/4, > + offset / X_LONG_SIZE, > + buffer_size / X_LONG_SIZE, > False, > AnyPropertyType, > actual_type_ret, actual_format_ret, > actual_size_ret,&bytes_remaining,&tmp_data); > > - TRACE2 ("Read %lu bytes from property %s", > - last - bytes_remaining, > - XGetAtomName (display, property)); > - > /* If this doesn't return Success at this point, it means that > some clod deleted the selection while we were in the midst of > reading it. Deal with that, I guess.... */ > if (result != Success) > break; > > + bytes_per_item = *actual_format_ret>> 3; > + xassert (*actual_size_ret<= buffer_size / bytes_per_item); > + > /* The man page for XGetWindowProperty says: > "If the returned format is 32, the returned data is represented > as a long array and should be cast to that type to obtain the > @@ -1348,32 +1366,61 @@ > The bytes and offsets passed to XGetWindowProperty refers to the > property and those are indeed in 32 bit quantities if format is 32. */ > > + bytes_gotten = *actual_size_ret; > + bytes_gotten *= bytes_per_item; > + > + TRACE2 ("Read %"pD"d bytes from property %s", > + bytes_gotten, XGetAtomName (display, property)); > + > + if (total_size - offset< bytes_gotten) > + { > + unsigned char *data1; > + ptrdiff_t remaining_lim = total_size_max - offset - bytes_gotten; > + if (remaining_lim< 0 || remaining_lim< bytes_remaining) > + goto size_overflow; > + total_size = offset + bytes_gotten + bytes_remaining; > + data1 = realloc (data, total_size + 1); > + if (! data1) > + goto memory_exhausted; > + data = data1; > + } > + > if (32< BITS_PER_LONG&& *actual_format_ret == 32) > { > unsigned long i; > - int *idata = (int *) ((*data_ret) + offset); > + int *idata = (int *) (data + offset); > long *ldata = (long *) tmp_data; > > for (i = 0; i< *actual_size_ret; ++i) > - { > - idata[i]= (int) ldata[i]; > - offset += 4; > - } > + idata[i] = ldata[i]; You must have the cast to int, otherwise there will be a warning on 64 bit hosts (possible loss of precision). > @@ -2426,7 +2479,7 @@ > unsigned long size = 160/event->format; > int x, y; > unsigned char *data = (unsigned char *) event->data.b; > - int idata[5]; > + unsigned int idata[5]; idata can be signed, so why the change to unsigned? > ptrdiff_t i; > > for (i = 0; i< dpyinfo->x_dnd_atoms_length; ++i) > @@ -2444,7 +2497,7 @@ > if (32< BITS_PER_LONG&& event->format == 32) > { > for (i = 0; i< 5; ++i) /* There are only 5 longs in a ClientMessage. */ > - idata[i] = (int) event->data.l[i]; > + idata[i] = event->data.l[i]; > data = (unsigned char *) idata; > } > > > # Begin bundle > IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWXkU8k0BAh7/gH/wAht7//// Why send this? What is it? It seems to just take up bandwidth. Jan D. ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-08-05 9:26 ` Jan Djärv @ 2011-08-06 1:24 ` Paul Eggert 2011-08-08 18:01 ` Jan Djärv 0 siblings, 1 reply; 13+ messages in thread From: Paul Eggert @ 2011-08-06 1:24 UTC (permalink / raw) To: Jan Djärv; +Cc: 9196 On 08/05/2011 02:26 AM, Jan Djärv wrote: >> + static char const xdefaults[] = ".Xdefaults-"; > > I think there might be problems with dumping and static variables. > There is a reason for initializing static variables in init-functions > rather in an initializer. I don't remember the details. In the old days, Emacs sometimes did '#define static /* empty */' as part of its undumping scheme, which meant that static variables inside functions didn't preserve their values from call to call. Emacs no longer does that, so we're OK here. (And even if Emacs still did that, this particular code would be safe, as this particular variable would be reinitialized to the correct value on every call.) >> + char *home = gethomedir (); >> + char const *host = get_system_name (); >> + ptrdiff_t pathsize = strlen (home) + sizeof xdefaults + strlen (host); >> + path = (char *) xrealloc (home, pathsize); >> + strcat (strcat (path, xdefaults), host); >> p = path; >> } >> >> db = XrmGetFileDatabase (p); >> >> xfree (path); >> - xfree (home); > > Since home isn't free:d, you have introduced a memory leak. No, we should be OK here -- the realloc frees 'home'. >> @@ -628,9 +641,9 @@ >> else >> { >> /* Send an INCR tag to initiate incremental transfer. */ >> - long value[1]; >> + unsigned long value[1]; > > This is wrong, X11 expects long, not unsigned long. Even if the value > here can't be negative, it can be in other situations, so stick with > long for consistency. Thanks, will do. >> - value[0] = bytes_remaining; >> + value[0] = min (bytes_remaining, X_ULONG_MAX); > > X_ULONG_MAX is wrong, max value is LONG_MAX as X11 can accept negative > values. Thanks again, I'll fix that too. >> - total_size = bytes_remaining + 1; >> - *data_ret = (unsigned char *) xmalloc (total_size); >> + if (total_size_max< bytes_remaining) >> + goto size_overflow; >> + total_size = bytes_remaining; >> + data = malloc (total_size + 1); > > Why isn't xmalloc used here? This code is already protected against interrupts and it already checks for memory exhaustion. There's no need to call xmalloc, and there are potential problems if the nested interrupt-blocking goes awry. >> + idata[i] = ldata[i]; > > You must have the cast to int, otherwise there will be a warning on 64 > bit hosts (possible loss of precision). That sort of thing used to be a concern, but it isn't any more. The existing Emacs code must have hundreds of assignments of 64-bit values to 32-bit variables without a cast (on 64-bit hosts). Here's one example, taken from the trunk's xselect.c: usecs = (x_selection_timeout % 1000) * 1000; It is possible to cause GCC to warn about these assignments, but nobody does that any more because it cries wolf far too often. Since the rest of Emacs doesn't worry about this issue, we needn't worry about it here. >> unsigned char *data = (unsigned char *) event->data.b; >> - int idata[5]; >> + unsigned int idata[5]; > > idata can be signed, so why the change to unsigned? Sorry, I misunderstood that. I'll change it back to 'signed'. > IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWXkU8k0BAh7/gH/wAht7//// > > Why send this? What is it? It seems to just take up bandwidth. It records all the details of the patch, including intervening changes, in a format suitable for bzr. It's generated by "bzr send", as suggested in <http://www.emacswiki.org/emacs/BzrForEmacsDevs>. But I agree it's pretty useless here, so I'll omit it from now on. Here's a further patch that I hope addresses all the comments satisfactorily. And thanks again for the review. === modified file 'src/xselect.c' --- src/xselect.c 2011-08-05 02:15:35 +0000 +++ src/xselect.c 2011-08-06 01:10:24 +0000 @@ -111,9 +111,11 @@ static Lisp_Object Qx_lost_selection_fun is not necessarily sizeof (long). */ #define X_LONG_SIZE 4 -/* Maximum unsigned 'short' and 'long' values suitable for libX11. */ -#define X_USHRT_MAX 0xffff -#define X_ULONG_MAX 0xffffffff +/* Extreme 'short' and 'long' values suitable for libX11. */ +#define X_SHRT_MAX 0x7fff +#define X_SHRT_MIN (-1 - X_SHRT_MAX) +#define X_LONG_MAX 0x7fffffff +#define X_LONG_MIN (-1 - X_LONG_MAX) /* If this is a smaller number than the max-request-size of the display, emacs will use INCR selection transfer when the selection is larger @@ -641,7 +643,7 @@ x_reply_selection_request (struct input_ else { /* Send an INCR tag to initiate incremental transfer. */ - unsigned long value[1]; + long value[1]; TRACE2 ("Start sending %"pD"d bytes incrementally (%s)", bytes_remaining, XGetAtomName (display, cs->property)); @@ -651,7 +653,7 @@ x_reply_selection_request (struct input_ /* XChangeProperty expects an array of long even if long is more than 32 bits. */ - value[0] = min (bytes_remaining, X_ULONG_MAX); + value[0] = min (bytes_remaining, X_LONG_MAX); XChangeProperty (display, window, cs->property, dpyinfo->Xatom_INCR, 32, PropModeReplace, (unsigned char *) value, 1); @@ -1764,13 +1766,13 @@ lisp_data_to_selection_data (Display *di (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj); if (NILP (type)) type = QATOM; } - else if (RANGED_INTEGERP (0, obj, X_USHRT_MAX)) + else if (RANGED_INTEGERP (X_SHRT_MIN, obj, X_SHRT_MAX)) { *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1); *format_ret = 16; *size_ret = 1; (*data_ret) [sizeof (short)] = 0; - (*(unsigned short **) data_ret) [0] = XINT (obj); + (*(short **) data_ret) [0] = XINT (obj); if (NILP (type)) type = QINTEGER; } else if (INTEGERP (obj) @@ -1783,7 +1785,7 @@ lisp_data_to_selection_data (Display *di *format_ret = 32; *size_ret = 1; (*data_ret) [sizeof (long)] = 0; - (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, X_ULONG_MAX); + (*(long **) data_ret) [0] = cons_to_signed (obj, X_LONG_MIN, X_LONG_MAX); if (NILP (type)) type = QINTEGER; } else if (VECTORP (obj)) @@ -1817,25 +1819,30 @@ lisp_data_to_selection_data (Display *di int data_size = sizeof (short); if (NILP (type)) type = QINTEGER; for (i = 0; i < size; i++) - if (X_USHRT_MAX - < cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX)) - { - /* Use sizeof (long) even if it is more than 32 bits. - See comment in x_get_window_property and - x_fill_property_data. */ - data_size = sizeof (long); - format = 32; - } + { + intmax_t v = cons_to_signed (XVECTOR (obj)->contents[i], + X_LONG_MIN, X_LONG_MAX); + if (X_SHRT_MIN <= v && v <= X_SHRT_MAX) + { + /* Use sizeof (long) even if it is more than 32 bits. + See comment in x_get_window_property and + x_fill_property_data. */ + data_size = sizeof (long); + format = 32; + } + } *data_ret = xnmalloc (size, data_size); *format_ret = format; *size_ret = size; for (i = 0; i < size; i++) - if (format == 32) - (*((unsigned long **) data_ret)) [i] = - cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX); - else - (*((unsigned short **) data_ret)) [i] = - cons_to_unsigned (XVECTOR (obj)->contents[i], X_USHRT_MAX); + { + long v = cons_to_signed (XVECTOR (obj)->contents[i], + X_LONG_MIN, X_LONG_MAX); + if (format == 32) + (*((long **) data_ret)) [i] = v; + else + (*((short **) data_ret)) [i] = v; + } } } else @@ -2479,7 +2486,7 @@ x_handle_dnd_message (struct frame *f, X unsigned long size = 160/event->format; int x, y; unsigned char *data = (unsigned char *) event->data.b; - unsigned int idata[5]; + int idata[5]; ptrdiff_t i; for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i) ^ permalink raw reply [flat|nested] 13+ messages in thread
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) 2011-08-06 1:24 ` Paul Eggert @ 2011-08-08 18:01 ` Jan Djärv 0 siblings, 0 replies; 13+ messages in thread From: Jan Djärv @ 2011-08-08 18:01 UTC (permalink / raw) To: Paul Eggert; +Cc: 9196 Paul Eggert skrev 2011-08-06 03:24: > On 08/05/2011 02:26 AM, Jan Djärv wrote: >>> + static char const xdefaults[] = ".Xdefaults-"; >> >> I think there might be problems with dumping and static variables. >> There is a reason for initializing static variables in init-functions >> rather in an initializer. I don't remember the details. > > In the old days, Emacs sometimes did '#define static /* empty */' as > part of its undumping scheme, which meant that static variables inside > functions didn't preserve their values from call to call. Emacs no > longer does that, so we're OK here. (And even if Emacs still did > that, this particular code would be safe, as this particular variable > would be reinitialized to the correct value on every call.) That is not what I meant. Tale a look at xterm.c, syms_of_xterm. Static variables are initialized there. The manual says: " You must not use C initializers for static or global variables unless the variables are never written once Emacs is dumped. These variables with initializers are allocated in an area of memory that becomes read-only (on certain operating systems) as a result of dumping Emacs. " So I guess this usage is ok. > >>> + char *home = gethomedir (); >>> + char const *host = get_system_name (); >>> + ptrdiff_t pathsize = strlen (home) + sizeof xdefaults + strlen (host); >>> + path = (char *) xrealloc (home, pathsize); >>> + strcat (strcat (path, xdefaults), host); >>> p = path; >>> } >>> >>> db = XrmGetFileDatabase (p); >>> >>> xfree (path); >>> - xfree (home); >> >> Since home isn't free:d, you have introduced a memory leak. > > No, we should be OK here -- the realloc frees 'home'. Right, missed that. Jan D. ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <handler.9196.B.131192196724343.ack@debbugs.gnu.org>]
* bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) [not found] ` <handler.9196.B.131192196724343.ack@debbugs.gnu.org> @ 2011-08-26 16:38 ` Paul Eggert 0 siblings, 0 replies; 13+ messages in thread From: Paul Eggert @ 2011-08-26 16:38 UTC (permalink / raw) To: 9196-done I installed the revised patch (with a few fixups discovered by further private testing) into the trunk as bzr 105581, and am marking this as done. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-08-26 16:38 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-07-29 6:44 bug#9196: integer and memory overflow issues (e.g., cut-and-paste crashes Emacs) Paul Eggert 2011-07-29 10:01 ` Jan Djärv 2011-07-29 16:21 ` Paul Eggert 2011-07-29 16:49 ` Jan Djärv 2011-07-29 21:03 ` Paul Eggert 2011-07-30 5:52 ` Jan Djärv 2011-07-30 19:16 ` Paul Eggert 2011-07-31 8:57 ` Jan Djärv 2011-08-05 2:33 ` Paul Eggert 2011-08-05 9:26 ` Jan Djärv 2011-08-06 1:24 ` Paul Eggert 2011-08-08 18:01 ` Jan Djärv [not found] ` <handler.9196.B.131192196724343.ack@debbugs.gnu.org> 2011-08-26 16:38 ` Paul Eggert
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).