diff --git a/NEWS b/NEWS index 8ac895254..40831aa1b 100644 --- a/NEWS +++ b/NEWS @@ -119,6 +119,7 @@ roughly in decreasing order of importance. if the terminal uses some other charset. - (bugfix 947) document.html.wrap_html also affects text in tables. - (bugfix 816) Convert entity references in input/@value only once. + - (Debian bug 380347) Prevent a buffer overflow in entity_cache. * Changes in parsing and rendering of non-HTML content-types - (new feature 121) If a mailcap entry indicates copiousoutput, ELinks itself acts as a pager. diff --git a/src/intl/charsets.c b/src/intl/charsets.c index 48d13f55f..1c59f96d3 100644 --- a/src/intl/charsets.c +++ b/src/intl/charsets.c @@ -1129,7 +1129,17 @@ skip: end: /* Take care of potential buffer overflow. */ if (strlen < sizeof(entity_cache[slen][0].str)) { - struct entity_cache *ece = &entity_cache[slen][nb_entity_cache[slen]]; + struct entity_cache *ece; + + /* Sort entries by hit order. */ + if (nb_entity_cache[slen] > 1) + qsort(&entity_cache[slen][0], nb_entity_cache[slen], + sizeof(entity_cache[slen][0]), (void *) hits_cmp); + + /* Increment number of cache entries if possible. + * Else, just replace the least used entry. */ + if (nb_entity_cache[slen] < ENTITY_CACHE_SIZE) nb_entity_cache[slen]++; + ece = &entity_cache[slen][nb_entity_cache[slen] - 1]; /* Copy new entry to cache. */ ece->hits = 1; @@ -1139,21 +1149,11 @@ end: memcpy(ece->str, str, strlen); ece->str[strlen] = '\0'; - /* Increment number of cache entries if possible. */ - if (nb_entity_cache[slen] < ENTITY_CACHE_SIZE) nb_entity_cache[slen]++; #ifdef DEBUG_ENTITY_CACHE fprintf(stderr, "Added in [%u]: l=%d st='%s'\n", slen, entity_cache[slen][0].strlen, entity_cache[slen][0].str); -#endif - - /* Sort entries by hit order. */ - if (nb_entity_cache[slen] > 1) - qsort(&entity_cache[slen][0], nb_entity_cache[slen], - sizeof(entity_cache[slen][0]), (void *) hits_cmp); - -#ifdef DEBUG_ENTITY_CACHE { unsigned int i; @@ -1164,7 +1164,7 @@ end: entity_cache[slen][i].str); fprintf(stderr, "-----------------\n"); } -#endif +#endif /* DEBUG_ENTITY_CACHE */ } return result; }