diff options
author | Owen Taylor <otaylor@redhat.com> | 2005-07-26 18:07:59 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2005-07-26 18:07:59 +0000 |
commit | 8d45583fa1f13d77feb5d96abeae59d21ad5fe65 (patch) | |
tree | 17eeeaf4847625186a334393821864f61738c14c /pango/pango-attributes.c | |
parent | 5e762f5014222d71358a28474e7f53dfed609112 (diff) | |
download | pango-8d45583fa1f13d77feb5d96abeae59d21ad5fe65.tar.gz |
Fixes for signed/unsigned in PangoAttrIterator ((#166700, Morten Welinder)
2005-07-26 Owen Taylor <otaylor@redhat.com>
Fixes for signed/unsigned in PangoAttrIterator ((#166700,
Morten Welinder)
* pango/pango-attributes.c (pango_attr_iterator_range):
Clamp results to G_MAXINT to avoid negative numbers from
signed/unsigned conversions.
* pango/pango-attributes.c: Make PangoAttrIterator
start_index/end_index unsigned to match PangoAttribute.
Change various local variables to match.
* pango/ellipsize.c (advance_iterator_to)
pango/pango-attributes.c (pango_attr_iterator_range)
pango/pango-glyph-item.c (pango_glyph_item_apply_attrs)
pango/pango-layout.c (pango_layout_line_get_empty_extents):
Always check the return value from pango_attr_iterator()
to deal with potential infinite loops when trying to
advance to position G_MAXINT.
* pango/pango-layout.c (pango_layout_set_text): Handle
the case where the text passed in is longer than
than G_MAXINT and length < 0.
* pango/pango-attributes.c (pango_attr_list_splice): Be
careful about integer overflow - clamp addition.
(#163246, Morten Welinder)
Diffstat (limited to 'pango/pango-attributes.c')
-rw-r--r-- | pango/pango-attributes.c | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index ecf41e47..d2fe3ce2 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -36,8 +36,8 @@ struct _PangoAttrIterator { GSList *next_attribute; GList *attribute_stack; - int start_index; - int end_index; + guint start_index; + guint end_index; }; static PangoAttribute *pango_attr_color_new (const PangoAttrClass *klass, @@ -1054,7 +1054,7 @@ pango_attr_list_insert_internal (PangoAttrList *list, gboolean before) { GSList *tmp_list, *prev, *link; - gint start_index = attr->start_index; + guint start_index = attr->start_index; if (!list->attributes) { @@ -1161,8 +1161,8 @@ pango_attr_list_change (PangoAttrList *list, PangoAttribute *attr) { GSList *tmp_list, *prev, *link; - gint start_index = attr->start_index; - gint end_index = attr->end_index; + guint start_index = attr->start_index; + guint end_index = attr->end_index; g_return_if_fail (list != NULL); @@ -1371,26 +1371,40 @@ pango_attr_list_splice (PangoAttrList *list, gint len) { GSList *tmp_list; + guint upos, ulen; g_return_if_fail (list != NULL); g_return_if_fail (other != NULL); g_return_if_fail (pos >= 0); g_return_if_fail (len >= 0); - + + upos = (guint)pos; + ulen = (guint)len; + +/* This definition only works when a and b are unsigned; overflow + * isn't defined in the C standard for signed integers + */ +#define CLAMP_ADD(a,b) (((a) + (b) < (a)) ? G_MAXUINT : (a) + (b)) + tmp_list = list->attributes; while (tmp_list) { PangoAttribute *attr = tmp_list->data; - if (attr->start_index <= pos) + if (attr->start_index <= upos) { - if (attr->end_index > pos) - attr->end_index += len; + if (attr->end_index > upos) + attr->end_index = CLAMP_ADD (attr->end_index, ulen); } else { - attr->start_index += len; - attr->end_index += len; + /* This could result in a zero length attribute if it + * gets squashed up against G_MAXUINT, but deleting such + * an element could (in theory) suprise the caller, so + * we don't delete it. + */ + attr->start_index = CLAMP_ADD (attr->end_index, ulen); + attr->end_index = CLAMP_ADD (attr->end_index, ulen); } tmp_list = tmp_list->next; @@ -1400,13 +1414,17 @@ pango_attr_list_splice (PangoAttrList *list, while (tmp_list) { PangoAttribute *attr = pango_attribute_copy (tmp_list->data); - attr->start_index += pos; - attr->end_index += pos; + attr->start_index = CLAMP_ADD (attr->start_index, upos); + attr->end_index = CLAMP_ADD (attr->end_index, upos); + /* Same as above, the attribute could be squashed to zero-length; here + * pango_attr_list_change() will take care of deleting it. + */ pango_attr_list_change (list, attr); tmp_list = tmp_list->next; } +#undef CLAMP_ADD } /** @@ -1433,7 +1451,7 @@ pango_attr_list_get_iterator (PangoAttrList *list) iterator->end_index = 0; if (!pango_attr_iterator_next (iterator)) - iterator->end_index = G_MAXINT; + iterator->end_index = G_MAXUINT; return iterator; } @@ -1444,7 +1462,11 @@ pango_attr_list_get_iterator (PangoAttrList *list) * @start: location to store the start of the range * @end: location to store the end of the range * - * Get the range of the current segment. + * Get the range of the current segment. Note that the + * stored return values are signed, not unsigned like + * the values in #PangoAttribute. To deal with this API + * oversight, stored return values that wouldn't fit into + * a signed integer are clamped to %G_MAXINT. **/ void pango_attr_iterator_range (PangoAttrIterator *iterator, @@ -1454,9 +1476,9 @@ pango_attr_iterator_range (PangoAttrIterator *iterator, g_return_if_fail (iterator != NULL); if (start) - *start = iterator->start_index; + *start = MIN (iterator->start_index, G_MAXINT); if (end) - *end = iterator->end_index; + *end = MIN (iterator->end_index, G_MAXINT); } /** @@ -1478,7 +1500,7 @@ pango_attr_iterator_next (PangoAttrIterator *iterator) return FALSE; iterator->start_index = iterator->end_index; - iterator->end_index = G_MAXINT; + iterator->end_index = G_MAXUINT; tmp_list = iterator->attribute_stack; while (tmp_list) |