[cairo-commit] 2 commits - src/cairo-truetype-subset.c

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 2 11:38:00 UTC 2022


 src/cairo-truetype-subset.c |   28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

New commits:
commit 541719ff756c4ec77b4de5771660863fbece7636
Merge: afba39684 53faf76e5
Author: Uli Schlachter <psychon at znc.in>
Date:   Tue Aug 2 11:37:58 2022 +0000

    Merge branch 'issue-579' into 'master'
    
    Fix issue 579
    
    Closes #579
    
    See merge request cairo/cairo!340

commit 53faf76e577c5f08b4fec6bbd5a2a871834ba597
Author: Uli Schlachter <psychon at znc.in>
Date:   Thu Jul 7 17:30:15 2022 +0200

    Fix issue 579
    
    cairo-trutype-subset.c would blindly trust a font saying that its name
    list has thousands of entries. This commit changes find_name() to also
    get the size of the input memory region and to do some bounds checking
    on its memory accesses.
    
    Fixes: https://gitlab.freedesktop.org/cairo/cairo/-/issues/579
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index efb67f9a6..c58b96665 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -1442,17 +1442,17 @@ cleanup:
 #define MAX_FONT_NAME_LENGTH 127
 
 static cairo_status_t
-find_name (tt_name_t *name, int name_id, int platform, int encoding, int language, char **str_out)
+find_name (tt_name_t *name, unsigned long size, int name_id, int platform, int encoding, int language, char **str_out)
 {
     tt_name_record_t *record;
-    int i, len;
+    unsigned int i, len;
     char *str;
     char *p;
     cairo_bool_t has_tag;
     cairo_status_t status;
 
     str = NULL;
-    for (i = 0; i < be16_to_cpu (name->num_records); i++) {
+    for (i = 0; i < MIN(be16_to_cpu (name->num_records), size / sizeof(name->records[0])); i++) {
         record = &(name->records[i]);
 	if (be16_to_cpu (record->name) == name_id &&
 	    be16_to_cpu (record->platform) == platform &&
@@ -1466,14 +1466,18 @@ find_name (tt_name_t *name, int name_id, int platform, int encoding, int languag
 	    if (len > MAX_FONT_NAME_LENGTH)
 		break;
 
+	    uint16_t offset = be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset);
+	    if (offset + len > size)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	    str = _cairo_malloc (len + 1);
 	    if (str == NULL)
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	    memcpy (str,
-		    ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
+		    ((char*)name) + offset,
 		    len);
-	    str[be16_to_cpu (record->length)] = 0;
+	    str[len] = 0;
 	    break;
 	}
     }
@@ -1487,7 +1491,7 @@ find_name (tt_name_t *name, int name_id, int platform, int encoding, int languag
 	int size = 0;
 	char *utf8;
 	uint16_t *u = (uint16_t *) str;
-	int u_len = len/2;
+	unsigned int u_len = len/2;
 
 	for (i = 0; i < u_len; i++)
 	    size += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), NULL);
@@ -1585,35 +1589,35 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t  	 *scaled_font,
 
     /* Find PS Name (name_id = 6). OT spec says PS name must be one of
      * the following two encodings */
-    status = find_name (name, 6, 3, 1, 0x409, &ps_name); /* win, unicode, english-us */
+    status = find_name (name, size, 6, 3, 1, 0x409, &ps_name); /* win, unicode, english-us */
     if (unlikely(status))
 	goto fail;
 
     if (!ps_name) {
-	status = find_name (name, 6, 1, 0, 0, &ps_name); /* mac, roman, english */
+	status = find_name (name, size, 6, 1, 0, 0, &ps_name); /* mac, roman, english */
 	if (unlikely(status))
 	    goto fail;
     }
 
     /* Find Family name (name_id = 1) */
-    status = find_name (name, 1, 3, 1, 0x409, &family_name); /* win, unicode, english-us */
+    status = find_name (name, size, 1, 3, 1, 0x409, &family_name); /* win, unicode, english-us */
     if (unlikely(status))
 	goto fail;
 
     if (!family_name) {
-	status = find_name (name, 1, 3, 0, 0x409, &family_name); /* win, symbol, english-us */
+	status = find_name (name, size, 1, 3, 0, 0x409, &family_name); /* win, symbol, english-us */
 	if (unlikely(status))
 	    goto fail;
     }
 
     if (!family_name) {
-	status = find_name (name, 1, 1, 0, 0, &family_name); /* mac, roman, english */
+	status = find_name (name, size, 1, 1, 0, 0, &family_name); /* mac, roman, english */
 	if (unlikely(status))
 	    goto fail;
     }
 
     if (!family_name) {
-	status = find_name (name, 1, 3, 1, -1, &family_name); /* win, unicode, any language */
+	status = find_name (name, size, 1, 3, 1, -1, &family_name); /* win, unicode, any language */
 	if (unlikely(status))
 	    goto fail;
     }


More information about the cairo-commit mailing list