diff options
| author | Paul Eggert | 2011-07-28 18:55:31 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-28 18:55:31 -0700 |
| commit | c678c83546bee743707bd0e259cc2aba192180c3 (patch) | |
| tree | 6e5c90ab1d218649c814f96c87967815be03275d /src | |
| parent | b7b603a0dca7695a852db57f8983bc0239f49678 (diff) | |
| download | emacs-c678c83546bee743707bd0e259cc2aba192180c3.tar.gz emacs-c678c83546bee743707bd0e259cc2aba192180c3.zip | |
* xfns.c: Integer and memory overflow fixes.
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/xfns.c | 38 |
2 files changed, 29 insertions, 14 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 3ac8c562a52..7a0543e46c5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,10 @@ | |||
| 1 | 2011-07-29 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-07-29 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | * xfns.c: Integer and memory overflow fixes. | ||
| 4 | (x_encode_text, x_set_name_internal, Fx_change_window_property): | ||
| 5 | Use ptrdiff_t, not int, to count sizes, since they can exceed | ||
| 6 | INT_MAX in size. Check for size calculation overflow. | ||
| 7 | |||
| 3 | * xfaces.c: Integer and memory overflow fixes. | 8 | * xfaces.c: Integer and memory overflow fixes. |
| 4 | (Finternal_make_lisp_face): Use ptrdiff_t, not int, for sizes. | 9 | (Finternal_make_lisp_face): Use ptrdiff_t, not int, for sizes. |
| 5 | Check for size calculation overflow. | 10 | Check for size calculation overflow. |
diff --git a/src/xfns.c b/src/xfns.c index 623b7847c1e..2751544d822 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -1471,7 +1471,8 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old | |||
| 1471 | the result should be `COMPOUND_TEXT'. */ | 1471 | the result should be `COMPOUND_TEXT'. */ |
| 1472 | 1472 | ||
| 1473 | static unsigned char * | 1473 | static unsigned char * |
| 1474 | x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, int *text_bytes, int *stringp, int *freep) | 1474 | x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, |
| 1475 | ptrdiff_t *text_bytes, int *stringp, int *freep) | ||
| 1475 | { | 1476 | { |
| 1476 | int result = string_xstring_p (string); | 1477 | int result = string_xstring_p (string); |
| 1477 | struct coding_system coding; | 1478 | struct coding_system coding; |
| @@ -1489,6 +1490,8 @@ x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, in | |||
| 1489 | coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK); | 1490 | coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK); |
| 1490 | /* We suppress producing escape sequences for composition. */ | 1491 | /* We suppress producing escape sequences for composition. */ |
| 1491 | coding.common_flags &= ~CODING_ANNOTATION_MASK; | 1492 | coding.common_flags &= ~CODING_ANNOTATION_MASK; |
| 1493 | if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < SCHARS (string)) | ||
| 1494 | memory_full (SIZE_MAX); | ||
| 1492 | coding.dst_bytes = SCHARS (string) * 2; | 1495 | coding.dst_bytes = SCHARS (string) * 2; |
| 1493 | coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); | 1496 | coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); |
| 1494 | encode_coding_object (&coding, string, 0, 0, | 1497 | encode_coding_object (&coding, string, 0, 0, |
| @@ -1512,7 +1515,8 @@ x_set_name_internal (FRAME_PTR f, Lisp_Object name) | |||
| 1512 | BLOCK_INPUT; | 1515 | BLOCK_INPUT; |
| 1513 | { | 1516 | { |
| 1514 | XTextProperty text, icon; | 1517 | XTextProperty text, icon; |
| 1515 | int bytes, stringp; | 1518 | ptrdiff_t bytes; |
| 1519 | int stringp; | ||
| 1516 | int do_free_icon_value = 0, do_free_text_value = 0; | 1520 | int do_free_icon_value = 0, do_free_text_value = 0; |
| 1517 | Lisp_Object coding_system; | 1521 | Lisp_Object coding_system; |
| 1518 | Lisp_Object encoded_name; | 1522 | Lisp_Object encoded_name; |
| @@ -1551,6 +1555,8 @@ x_set_name_internal (FRAME_PTR f, Lisp_Object name) | |||
| 1551 | : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); | 1555 | : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); |
| 1552 | text.format = 8; | 1556 | text.format = 8; |
| 1553 | text.nitems = bytes; | 1557 | text.nitems = bytes; |
| 1558 | if (text.nitems != bytes) | ||
| 1559 | error ("Window name too large"); | ||
| 1554 | 1560 | ||
| 1555 | if (!STRINGP (f->icon_name)) | 1561 | if (!STRINGP (f->icon_name)) |
| 1556 | { | 1562 | { |
| @@ -1566,6 +1572,8 @@ x_set_name_internal (FRAME_PTR f, Lisp_Object name) | |||
| 1566 | : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); | 1572 | : FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT); |
| 1567 | icon.format = 8; | 1573 | icon.format = 8; |
| 1568 | icon.nitems = bytes; | 1574 | icon.nitems = bytes; |
| 1575 | if (icon.nitems != bytes) | ||
| 1576 | error ("Icon name too large"); | ||
| 1569 | 1577 | ||
| 1570 | encoded_icon_name = ENCODE_UTF_8 (f->icon_name); | 1578 | encoded_icon_name = ENCODE_UTF_8 (f->icon_name); |
| 1571 | } | 1579 | } |
| @@ -4194,21 +4202,21 @@ FRAME. Default is to change on the edit X window. */) | |||
| 4194 | 4202 | ||
| 4195 | if (CONSP (value)) | 4203 | if (CONSP (value)) |
| 4196 | { | 4204 | { |
| 4205 | ptrdiff_t elsize; | ||
| 4206 | |||
| 4197 | nelements = x_check_property_data (value); | 4207 | nelements = x_check_property_data (value); |
| 4198 | if (nelements == -1) | 4208 | if (nelements == -1) |
| 4199 | error ("Bad data in VALUE, must be number, string or cons"); | 4209 | error ("Bad data in VALUE, must be number, string or cons"); |
| 4200 | 4210 | ||
| 4201 | if (element_format == 8) | 4211 | /* The man page for XChangeProperty: |
| 4202 | data = (unsigned char *) xmalloc (nelements); | 4212 | "If the specified format is 32, the property data must be a |
| 4203 | else if (element_format == 16) | 4213 | long array." |
| 4204 | data = (unsigned char *) xmalloc (nelements*2); | 4214 | This applies even if long is more than 32 bits. The X library |
| 4205 | else /* format == 32 */ | 4215 | converts to 32 bits before sending to the X server. */ |
| 4206 | /* The man page for XChangeProperty: | 4216 | elsize = element_format == 32 ? sizeof (long) : element_format >> 3; |
| 4207 | "If the specified format is 32, the property data must be a | 4217 | if (min (PTRDIFF_MAX, SIZE_MAX) / elsize < nelements) |
| 4208 | long array." | 4218 | memory_full (SIZE_MAX); |
| 4209 | This applies even if long is more than 64 bits. The X library | 4219 | data = (unsigned char *) xmalloc (nelements * elsize); |
| 4210 | converts to 32 bits before sending to the X server. */ | ||
| 4211 | data = (unsigned char *) xmalloc (nelements * sizeof(long)); | ||
| 4212 | 4220 | ||
| 4213 | x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format); | 4221 | x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format); |
| 4214 | } | 4222 | } |
| @@ -4216,7 +4224,9 @@ FRAME. Default is to change on the edit X window. */) | |||
| 4216 | { | 4224 | { |
| 4217 | CHECK_STRING (value); | 4225 | CHECK_STRING (value); |
| 4218 | data = SDATA (value); | 4226 | data = SDATA (value); |
| 4219 | nelements = SCHARS (value); | 4227 | if (INT_MAX < SBYTES (value)) |
| 4228 | error ("VALUE too long"); | ||
| 4229 | nelements = SBYTES (value); | ||
| 4220 | } | 4230 | } |
| 4221 | 4231 | ||
| 4222 | BLOCK_INPUT; | 4232 | BLOCK_INPUT; |