summaryrefslogtreecommitdiff
path: root/src/composite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/composite.c')
-rw-r--r--src/composite.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/src/composite.c b/src/composite.c
index d402d5ad0c4..4ae1d6ebb68 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -142,10 +142,10 @@ Lisp_Object Qcomposition;
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 @@ Lisp_Object composition_temp;
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 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
/* 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);
+ = (struct composition **) xmalloc (sizeof (composition_table[0]) * 256);
+ composition_table_size = 256;
}
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 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
/* 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 @@ static Lisp_Object
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 @@ composition_gstring_put_cache (Lisp_Object gstring, EMACS_INT len)
}
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);