aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-08-29 11:46:42 -0700
committerPaul Eggert2011-08-29 11:46:42 -0700
commitc21721cc3953732047ffdfe268764898f089f74b (patch)
tree3ada1b251b233bf7f723d8649384f6b2968078c8 /src
parentb5cd19054673bfa46a4f0d1ac3905deeafcf94ff (diff)
downloademacs-c21721cc3953732047ffdfe268764898f089f74b.tar.gz
emacs-c21721cc3953732047ffdfe268764898f089f74b.zip
* font.c (font_unparse_xlfd): Don't blindly alloca long strings.
Don't assume XINT result fits in int, or that XFLOAT_DATA * 10 fits in int, when using sprintf. Use single snprintf to count length of string rather than counting it via multiple sprintfs; that's simpler and more reliable. (APPEND_SPRINTF): New macro. (font_unparse_fcname): Use it to avoid sprintf buffer overrun. (generate_otf_features) [0 && HAVE_LIBOTF]: Use esprintf, not sprintf, in case result does not fit in int.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/font.c173
2 files changed, 77 insertions, 106 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4624e5fc30e..f94f9c4632f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -39,6 +39,16 @@
39 * filelock.c (lock_file_1, lock_file): Don't blindly alloca long name; 39 * filelock.c (lock_file_1, lock_file): Don't blindly alloca long name;
40 use SAFE_ALLOCA instead. Use esprintf to avoid int-overflow issues. 40 use SAFE_ALLOCA instead. Use esprintf to avoid int-overflow issues.
41 41
42 * font.c (font_unparse_xlfd): Don't blindly alloca long strings.
43 Don't assume XINT result fits in int, or that XFLOAT_DATA * 10
44 fits in int, when using sprintf. Use single snprintf to count
45 length of string rather than counting it via multiple sprintfs;
46 that's simpler and more reliable.
47 (APPEND_SPRINTF): New macro.
48 (font_unparse_fcname): Use it to avoid sprintf buffer overrun.
49 (generate_otf_features) [0 && HAVE_LIBOTF]: Use esprintf, not
50 sprintf, in case result does not fit in int.
51
422011-08-26 Paul Eggert <eggert@cs.ucla.edu> 522011-08-26 Paul Eggert <eggert@cs.ucla.edu>
43 53
44 Integer and memory overflow issues (Bug#9196). 54 Integer and memory overflow issues (Bug#9196).
diff --git a/src/font.c b/src/font.c
index 5f8d22157d6..cc5939982d3 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1180,7 +1180,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1180 char *p; 1180 char *p;
1181 const char *f[XLFD_REGISTRY_INDEX + 1]; 1181 const char *f[XLFD_REGISTRY_INDEX + 1];
1182 Lisp_Object val; 1182 Lisp_Object val;
1183 int i, j, len = 0; 1183 int i, j, len;
1184 1184
1185 font_assert (FONTP (font)); 1185 font_assert (FONTP (font));
1186 1186
@@ -1195,9 +1195,9 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1195 if (NILP (val)) 1195 if (NILP (val))
1196 { 1196 {
1197 if (j == XLFD_REGISTRY_INDEX) 1197 if (j == XLFD_REGISTRY_INDEX)
1198 f[j] = "*-*", len += 4; 1198 f[j] = "*-*";
1199 else 1199 else
1200 f[j] = "*", len += 2; 1200 f[j] = "*";
1201 } 1201 }
1202 else 1202 else
1203 { 1203 {
@@ -1207,21 +1207,15 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1207 && ! strchr (SSDATA (val), '-')) 1207 && ! strchr (SSDATA (val), '-'))
1208 { 1208 {
1209 /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */ 1209 /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */
1210 if (SDATA (val)[SBYTES (val) - 1] == '*') 1210 ptrdiff_t alloc = SBYTES (val) + 4;
1211 { 1211 if (nbytes <= alloc)
1212 f[j] = p = alloca (SBYTES (val) + 3); 1212 return -1;
1213 sprintf (p, "%s-*", SDATA (val)); 1213 f[j] = p = alloca (alloc);
1214 len += SBYTES (val) + 3; 1214 sprintf (p, "%s%s-*", SDATA (val),
1215 } 1215 "*" + (SDATA (val)[SBYTES (val) - 1] == '*'));
1216 else
1217 {
1218 f[j] = p = alloca (SBYTES (val) + 4);
1219 sprintf (p, "%s*-*", SDATA (val));
1220 len += SBYTES (val) + 4;
1221 }
1222 } 1216 }
1223 else 1217 else
1224 f[j] = SSDATA (val), len += SBYTES (val) + 1; 1218 f[j] = SSDATA (val);
1225 } 1219 }
1226 } 1220 }
1227 1221
@@ -1230,11 +1224,11 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1230 { 1224 {
1231 val = font_style_symbolic (font, i, 0); 1225 val = font_style_symbolic (font, i, 0);
1232 if (NILP (val)) 1226 if (NILP (val))
1233 f[j] = "*", len += 2; 1227 f[j] = "*";
1234 else 1228 else
1235 { 1229 {
1236 val = SYMBOL_NAME (val); 1230 val = SYMBOL_NAME (val);
1237 f[j] = SSDATA (val), len += SBYTES (val) + 1; 1231 f[j] = SSDATA (val);
1238 } 1232 }
1239 } 1233 }
1240 1234
@@ -1242,64 +1236,62 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1242 font_assert (NUMBERP (val) || NILP (val)); 1236 font_assert (NUMBERP (val) || NILP (val));
1243 if (INTEGERP (val)) 1237 if (INTEGERP (val))
1244 { 1238 {
1245 i = XINT (val); 1239 EMACS_INT v = XINT (val);
1246 if (i <= 0) 1240 if (v <= 0)
1247 i = pixel_size; 1241 v = pixel_size;
1248 if (i > 0) 1242 if (v > 0)
1249 { 1243 {
1250 f[XLFD_PIXEL_INDEX] = p = alloca (22); 1244 f[XLFD_PIXEL_INDEX] = p =
1251 len += sprintf (p, "%d-*", i) + 1; 1245 alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
1246 sprintf (p, "%"pI"d-*", v);
1252 } 1247 }
1253 else 1248 else
1254 f[XLFD_PIXEL_INDEX] = "*-*", len += 4; 1249 f[XLFD_PIXEL_INDEX] = "*-*";
1255 } 1250 }
1256 else if (FLOATP (val)) 1251 else if (FLOATP (val))
1257 { 1252 {
1258 i = XFLOAT_DATA (val) * 10; 1253 double v = XFLOAT_DATA (val) * 10;
1259 f[XLFD_PIXEL_INDEX] = p = alloca (12); 1254 f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1);
1260 len += sprintf (p, "*-%d", i) + 1; 1255 sprintf (p, "*-%.0f", v);
1261 } 1256 }
1262 else 1257 else
1263 f[XLFD_PIXEL_INDEX] = "*-*", len += 4; 1258 f[XLFD_PIXEL_INDEX] = "*-*";
1264 1259
1265 if (INTEGERP (AREF (font, FONT_DPI_INDEX))) 1260 if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
1266 { 1261 {
1267 i = XINT (AREF (font, FONT_DPI_INDEX)); 1262 EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
1268 f[XLFD_RESX_INDEX] = p = alloca (22); 1263 f[XLFD_RESX_INDEX] = p =
1269 len += sprintf (p, "%d-%d", i, i) + 1; 1264 alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
1265 sprintf (p, "%"pI"d-%"pI"d", v, v);
1270 } 1266 }
1271 else 1267 else
1272 f[XLFD_RESX_INDEX] = "*-*", len += 4; 1268 f[XLFD_RESX_INDEX] = "*-*";
1273 if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) 1269 if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
1274 { 1270 {
1275 int spacing = XINT (AREF (font, FONT_SPACING_INDEX)); 1271 EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
1276 1272
1277 f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p" 1273 f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p"
1278 : spacing <= FONT_SPACING_DUAL ? "d" 1274 : spacing <= FONT_SPACING_DUAL ? "d"
1279 : spacing <= FONT_SPACING_MONO ? "m" 1275 : spacing <= FONT_SPACING_MONO ? "m"
1280 : "c"); 1276 : "c");
1281 len += 2;
1282 } 1277 }
1283 else 1278 else
1284 f[XLFD_SPACING_INDEX] = "*", len += 2; 1279 f[XLFD_SPACING_INDEX] = "*";
1285 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) 1280 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
1286 { 1281 {
1287 f[XLFD_AVGWIDTH_INDEX] = p = alloca (22); 1282 f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT));
1288 len += sprintf (p, "%"pI"d", 1283 sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
1289 XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1;
1290 } 1284 }
1291 else 1285 else
1292 f[XLFD_AVGWIDTH_INDEX] = "*", len += 2; 1286 f[XLFD_AVGWIDTH_INDEX] = "*";
1293 len++; /* for terminating '\0'. */ 1287 len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
1294 if (len >= nbytes)
1295 return -1;
1296 return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
1297 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX], 1288 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
1298 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX], 1289 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
1299 f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX], 1290 f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX],
1300 f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX], 1291 f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX],
1301 f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX], 1292 f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
1302 f[XLFD_REGISTRY_INDEX]); 1293 f[XLFD_REGISTRY_INDEX]);
1294 return len < nbytes ? len : -1;
1303} 1295}
1304 1296
1305/* Parse NAME (null terminated) and store information in FONT 1297/* Parse NAME (null terminated) and store information in FONT
@@ -1553,23 +1545,19 @@ int
1553font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes) 1545font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
1554{ 1546{
1555 Lisp_Object family, foundry; 1547 Lisp_Object family, foundry;
1556 Lisp_Object tail, val; 1548 Lisp_Object val;
1557 int point_size; 1549 int point_size;
1558 int i; 1550 int i;
1559 ptrdiff_t len = 1;
1560 char *p; 1551 char *p;
1552 char *lim;
1561 Lisp_Object styles[3]; 1553 Lisp_Object styles[3];
1562 const char *style_names[3] = { "weight", "slant", "width" }; 1554 const char *style_names[3] = { "weight", "slant", "width" };
1563 char work[256];
1564 1555
1565 family = AREF (font, FONT_FAMILY_INDEX); 1556 family = AREF (font, FONT_FAMILY_INDEX);
1566 if (! NILP (family)) 1557 if (! NILP (family))
1567 { 1558 {
1568 if (SYMBOLP (family)) 1559 if (SYMBOLP (family))
1569 { 1560 family = SYMBOL_NAME (family);
1570 family = SYMBOL_NAME (family);
1571 len += SBYTES (family);
1572 }
1573 else 1561 else
1574 family = Qnil; 1562 family = Qnil;
1575 } 1563 }
@@ -1580,7 +1568,6 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
1580 if (XINT (val) != 0) 1568 if (XINT (val) != 0)
1581 pixel_size = XINT (val); 1569 pixel_size = XINT (val);
1582 point_size = -1; 1570 point_size = -1;
1583 len += 21; /* for ":pixelsize=NUM" */
1584 } 1571 }
1585 else 1572 else
1586 { 1573 {
@@ -1588,80 +1575,54 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
1588 abort (); 1575 abort ();
1589 pixel_size = -1; 1576 pixel_size = -1;
1590 point_size = (int) XFLOAT_DATA (val); 1577 point_size = (int) XFLOAT_DATA (val);
1591 len += 11; /* for "-NUM" */
1592 } 1578 }
1593 1579
1594 foundry = AREF (font, FONT_FOUNDRY_INDEX); 1580 foundry = AREF (font, FONT_FOUNDRY_INDEX);
1595 if (! NILP (foundry)) 1581 if (! NILP (foundry))
1596 { 1582 {
1597 if (SYMBOLP (foundry)) 1583 if (SYMBOLP (foundry))
1598 { 1584 foundry = SYMBOL_NAME (foundry);
1599 foundry = SYMBOL_NAME (foundry);
1600 len += 9 + SBYTES (foundry); /* ":foundry=NAME" */
1601 }
1602 else 1585 else
1603 foundry = Qnil; 1586 foundry = Qnil;
1604 } 1587 }
1605 1588
1606 for (i = 0; i < 3; i++) 1589 for (i = 0; i < 3; i++)
1607 { 1590 styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
1608 styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
1609 if (! NILP (styles[i]))
1610 len += sprintf (work, ":%s=%s", style_names[i],
1611 SDATA (SYMBOL_NAME (styles[i])));
1612 }
1613 1591
1614 if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
1615 len += sprintf (work, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX)));
1616 if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
1617 len += strlen (":spacing=100");
1618 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
1619 len += strlen (":scalable=false"); /* or ":scalable=true" */
1620 for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
1621 {
1622 Lisp_Object key = XCAR (XCAR (tail)), value = XCDR (XCAR (tail));
1623
1624 len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */
1625 if (STRINGP (value))
1626 len += SBYTES (value);
1627 else if (INTEGERP (value))
1628 len += sprintf (work, "%"pI"d", XINT (value));
1629 else if (SYMBOLP (value))
1630 len += (NILP (value) ? 5 : 4); /* for "false" or "true" */
1631 }
1632
1633 if (len > nbytes)
1634 return -1;
1635 p = name; 1592 p = name;
1593 lim = name + nbytes;
1594# define APPEND_SNPRINTF(args) \
1595 do { \
1596 int len = snprintf args; \
1597 if (! (0 <= len && len < lim - p)) \
1598 return -1; \
1599 p += len; \
1600 } while (0)
1636 if (! NILP (family)) 1601 if (! NILP (family))
1637 p += sprintf (p, "%s", SDATA (family)); 1602 APPEND_SNPRINTF ((p, lim - p, "%s", SSDATA (family)));
1638 if (point_size > 0) 1603 if (point_size > 0)
1639 { 1604 APPEND_SNPRINTF ((p, lim - p, "-%d" + (p == name), point_size));
1640 if (p == name)
1641 p += sprintf (p, "%d", point_size);
1642 else
1643 p += sprintf (p, "-%d", point_size);
1644 }
1645 else if (pixel_size > 0) 1605 else if (pixel_size > 0)
1646 p += sprintf (p, ":pixelsize=%d", pixel_size); 1606 APPEND_SNPRINTF ((p, lim - p, ":pixelsize=%d", pixel_size));
1647 if (! NILP (AREF (font, FONT_FOUNDRY_INDEX))) 1607 if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
1648 p += sprintf (p, ":foundry=%s", 1608 APPEND_SNPRINTF ((p, lim - p, ":foundry=%s",
1649 SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX)))); 1609 SSDATA (SYMBOL_NAME (AREF (font,
1610 FONT_FOUNDRY_INDEX)))));
1650 for (i = 0; i < 3; i++) 1611 for (i = 0; i < 3; i++)
1651 if (! NILP (styles[i])) 1612 if (! NILP (styles[i]))
1652 p += sprintf (p, ":%s=%s", style_names[i], 1613 APPEND_SNPRINTF ((p, lim - p, ":%s=%s", style_names[i],
1653 SDATA (SYMBOL_NAME (styles[i]))); 1614 SSDATA (SYMBOL_NAME (styles[i]))));
1654 if (INTEGERP (AREF (font, FONT_DPI_INDEX))) 1615 if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
1655 p += sprintf (p, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX))); 1616 APPEND_SNPRINTF ((p, lim - p, ":dpi=%"pI"d",
1617 XINT (AREF (font, FONT_DPI_INDEX))));
1656 if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) 1618 if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
1657 p += sprintf (p, ":spacing=%"pI"d", XINT (AREF (font, FONT_SPACING_INDEX))); 1619 APPEND_SNPRINTF ((p, lim - p, ":spacing=%"pI"d",
1620 XINT (AREF (font, FONT_SPACING_INDEX))));
1658 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) 1621 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
1659 { 1622 APPEND_SNPRINTF ((p, lim - p,
1660 if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0) 1623 (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
1661 p += sprintf (p, ":scalable=true"); 1624 ? ":scalable=true"
1662 else 1625 : ":scalable=false")));
1663 p += sprintf (p, ":scalable=false");
1664 }
1665 return (p - name); 1626 return (p - name);
1666} 1627}
1667 1628
@@ -1952,12 +1913,12 @@ generate_otf_features (Lisp_Object spec, char *features)
1952 else if (! asterisk) 1913 else if (! asterisk)
1953 { 1914 {
1954 val = SYMBOL_NAME (val); 1915 val = SYMBOL_NAME (val);
1955 p += sprintf (p, "%s", SDATA (val)); 1916 p += esprintf (p, "%s", SDATA (val));
1956 } 1917 }
1957 else 1918 else
1958 { 1919 {
1959 val = SYMBOL_NAME (val); 1920 val = SYMBOL_NAME (val);
1960 p += sprintf (p, "~%s", SDATA (val)); 1921 p += esprintf (p, "~%s", SDATA (val));
1961 } 1922 }
1962 } 1923 }
1963 if (CONSP (spec)) 1924 if (CONSP (spec))