diff options
Diffstat (limited to 'libXfont')
-rw-r--r-- | libXfont/ChangeLog | 403 | ||||
-rw-r--r-- | libXfont/INSTALL | 121 | ||||
-rw-r--r-- | libXfont/README | 59 | ||||
-rw-r--r-- | libXfont/aclocal.m4 | 27 | ||||
-rw-r--r-- | libXfont/configure | 43 | ||||
-rw-r--r-- | libXfont/configure.ac | 9 | ||||
-rw-r--r-- | libXfont/src/FreeType/ftfuncs.c | 2 | ||||
-rw-r--r-- | libXfont/src/FreeType/xttcap.c | 1 | ||||
-rw-r--r-- | libXfont/src/builtins/fpe.c | 5 | ||||
-rw-r--r-- | libXfont/src/fc/fsconvert.c | 68 | ||||
-rw-r--r-- | libXfont/src/fc/fserve.c | 540 | ||||
-rw-r--r-- | libXfont/src/fc/fsio.h | 3 | ||||
-rw-r--r-- | libXfont/src/fontfile/bufio.c | 6 | ||||
-rw-r--r-- | libXfont/src/fontfile/catalogue.c | 9 | ||||
-rw-r--r-- | libXfont/src/fontfile/dirfile.c | 12 | ||||
-rw-r--r-- | libXfont/src/fontfile/fontdir.c | 5 |
16 files changed, 1054 insertions, 259 deletions
diff --git a/libXfont/ChangeLog b/libXfont/ChangeLog index 5901d9918..201ab8a11 100644 --- a/libXfont/ChangeLog +++ b/libXfont/ChangeLog @@ -1,3 +1,406 @@ +commit 6ed205bd618f3f3016e34ab132019d53d0623576 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Thu May 15 19:21:07 2014 -0700 + + libXfont 1.4.8 + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + +commit 23a7a10aaada0a4b00272b512bd430545ce799e3 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri May 2 19:24:17 2014 -0700 + + CVE-2014-0210: unvalidated length fields in fs_read_list_info() + + fs_read_list_info() parses a reply from the font server. The reply + contains a number of additional data items with embedded length or + count fields, none of which are validated. This can cause out of + bound reads when looping over these items in the reply. + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + (cherry picked from commit d338f81df1e188eb16e1d6aeea7f4800f89c1218) + +commit a455f111eb2779e3258d49c1c003d3023d1b9bab +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri May 2 19:24:17 2014 -0700 + + CVE-2014-0210: unvalidated length fields in fs_read_list() + + fs_read_list() parses a reply from the font server. The reply + contains a list of strings with embedded length fields, none of + which are validated. This can cause out of bound reads when looping + over the strings in the reply. + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + (cherry picked from commit 5fa73ac18474be3032ee7af9c6e29deab163ea39) + +commit 2b7b6f21ec67c2e4fdc3cee9db3199a6edef5c5c +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:03:24 2014 -0700 + + CVE-2014-0210: unvalidated length fields in fs_read_glyphs() + + fs_read_glyphs() parses a reply from the font server. The reply + contains embedded length fields, none of which are validated. + This can cause out of bound reads when looping over the glyph + bitmaps in the reply. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit 520683652564c2a4e42328ae23eef9bb63271565) + +commit 573c3fdcb934ca1f3243f6ced40e1f037ea6cefe +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:03:05 2014 -0700 + + CVE-2014-0210: unvalidated length fields in fs_read_extent_info() + + Looping over the extents in the reply could go past the end of the + reply buffer if the reply indicated more extents than could fit in + the specified reply length. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit a3f21421537620fc4e1f844a594a4bcd9f7e2bd8) + +commit 4b762a7eb73d4d84466331be2d48565561018fc1 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:02:54 2014 -0700 + + CVE-2014-0211: integer overflow in fs_alloc_glyphs() + + fs_alloc_glyphs() is a malloc wrapper used by the font code. + It contains a classic integer overflow in the malloc() call, + which can cause memory corruption. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit a42f707f8a62973f5e8bbcd08afb10a79e9cee33) + +commit e6d9db84113650c4f4d9bebddb60cdb72690d798 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:02:42 2014 -0700 + + CVE-2014-0211: integer overflow in fs_read_extent_info() + + fs_read_extent_info() parses a reply from the font server. + The reply contains a 32bit number of elements field which is used + to calculate a buffer length. There is an integer overflow in this + calculation which can lead to memory corruption. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit c578408c1fd4db09e4e3173f8a9e65c81cc187c1) + +commit fb4ecda3014744fa690959da9c5b09233b73c016 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:02:34 2014 -0700 + + CVE-2014-0210: unvalidated length fields in fs_read_query_info() + + fs_read_query_info() parses a reply from the font server. The reply + contains embedded length fields, none of which are validated. This + can cause out of bound reads in either fs_read_query_info() or in + _fs_convert_props() which it calls to parse the fsPropInfo in the reply. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit 491291cabf78efdeec8f18b09e14726a9030cc8f) + +commit 633005ac24a44dacaf6beb3ed240ae0ea7e022d7 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:02:25 2014 -0700 + + CVE-2014-0211: Integer overflow in fs_get_reply/_fs_start_read + + fs_get_reply() would take any reply size, multiply it by 4 and pass to + _fs_start_read. If that size was bigger than the current reply buffer + size, _fs_start_read would add it to the existing buffer size plus the + buffer size increment constant and realloc the buffer to that result. + + This math could overflow, causing the code to allocate a smaller + buffer than the amount it was about to read into that buffer from + the network. It could also succeed, allowing the remote font server + to cause massive allocations in the X server, possibly using up all + the address space in a 32-bit X server, allowing the triggering of + other bugs in code that fails to handle malloc failure properly. + + This patch protects against both problems, by disconnecting any + font server trying to feed us more than (the somewhat arbitrary) + 64 mb in a single reply. + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit 0f1a5d372c143f91a602bdf10c917d7eabaee09b) + +commit 647d9ea15e34779afa442d362997d92488778907 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:02:12 2014 -0700 + + CVE-2014-0210: unvalidated lengths when reading replies from font server + + Functions to handle replies to font server requests were casting replies + from the generic form to reply specific structs without first checking + that the reply was at least as long as the struct being cast to. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit cbb64aef35960b2882be721f4b8fbaa0fb649d12) + +commit 23dcf6b1da8b5088856aef12b4a3f4581836f63a +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:02:00 2014 -0700 + + CVE-2014-0210: unvalidated length in _fs_recv_conn_setup() + + The connection setup reply from the font server can include a list + of alternate servers to contact if this font server stops working. + + The reply specifies a total size of all the font server names, and + then provides a list of names. _fs_recv_conn_setup() allocated the + specified total size for copying the names to, but didn't check to + make sure it wasn't copying more data to that buffer than the size + it had allocated. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit 891e084b26837162b12f841060086a105edde86d) + +commit 26643c0c3f4e53945516e20e00dfbb4d69a39c65 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:01:48 2014 -0700 + + CVE-2014-0209: integer overflow of realloc() size in lexAlias() + + lexAlias() reads from a file in a loop. It does this by starting with a + 64 byte buffer. If that size limit is hit, it does a realloc of the + buffer size << 1, basically doubling the needed length every time the + length limit is hit. + + Eventually, this will shift out to 0 (for a length of ~4gig), and that + length will be passed on to realloc(). A length of 0 (with a valid + pointer) causes realloc to free the buffer on most POSIX platforms, + but the caller will still have a pointer to it, leading to use after + free issues. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit 05c8020a49416dd8b7510cbba45ce4f3fc81a7dc) + +commit 0a37bf2d9977db81573f300b0dc203df8fe108b5 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Apr 25 23:01:11 2014 -0700 + + CVE-2014-0209: integer overflow of realloc() size in FontFileAddEntry() + + FontFileReadDirectory() opens a fonts.dir file, and reads over every + line in an fscanf loop. For each successful entry read (font name, + file name) a call is made to FontFileAddFontFile(). + + FontFileAddFontFile() will add a font file entry (for the font name + and file) each time it’s called, by calling FontFileAddEntry(). + FontFileAddEntry() will do the actual adding. If the table it has + to add to is full, it will do a realloc, adding 100 more entries + to the table size without checking to see if that will overflow the + int used to store the size. + + Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + (cherry picked from commit 2f5e57317339c526e6eaee1010b0e2ab8089c42e) + +commit c1ccb7d4eb34c99178ace3956768abfb4cf866fd +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Tue Apr 22 23:49:29 2014 -0700 + + Clean up warnings when src/fc is built with -DDEBUG + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + (cherry picked from commit 77902e1422315963364fcba3736ff9b5b0f32d47) + +commit e9a07053d2b5aa55634c2bb2fd080fae77020e3c +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Tue Apr 22 23:45:41 2014 -0700 + + Allow enabling src/fc DEBUG helpers via CPPFLAGS + + Instead of editing fsio.h to turn on debugging logs, just add + -DDEBUG to CPPFLAGS when building. + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + (cherry picked from commit f75f7bde4cedc36d5ca1289988b3daebb80528d2) + +commit 9b41f3d0c7c430a2909c9455eff347e714f0c4b4 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sun Apr 20 18:10:07 2014 -0700 + + Require fontsproto < 2.1.3 for matching function prototypes + + Building libXfont-1.4.x against fontsproto 2.1.3 causes clang + complaints of: + + patcache.c:130:1: error: conflicting types for 'CacheFontPattern' + CacheFontPattern (FontPatternCachePtr cache, + ^ + patcache.c:176:1: error: conflicting types for 'FindCachedFontPattern' + FindCachedFontPattern (FontPatternCachePtr cache, + ^ + + due to the constification of arguments not matching. + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Thomas Klausner <wiz@NetBSD.org> + +commit 371f8582a33235afa1b61d76e4fe98bdc9d7c083 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Sun Apr 20 17:59:14 2014 -0700 + + Check if pointer returned by BufFileCreate is NULL before writing to it + + Fixes clang analyzer warning: + + bufio.c:165:13: warning: Access to field 'bufp' results in a dereference + of a null pointer (loaded from variable 'f') + f->bufp = f->buffer; + ~ ^ + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Thomas Klausner <wiz@NetBSD.org> + (cherry picked from commit c77a0784bdfc8c178f0742689cf6ae02a2fce37f) + +commit 5bb34807642589e5b592b04418855fd059fc5022 +Author: Peter Harris <pharris@opentext.com> +Date: Mon Apr 7 14:25:02 2014 -0400 + + Fix buffer read overrun + + "FreeType" is only eight bytes long. The atom "FreeType\x00\x??" is + probably not what the author intended. + + Signed-off-by: Peter Harris <pharris@opentext.com> + Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> + (cherry picked from commit c8855746aec2a9b732502da0ca3258b4e701c61a) + +commit 2a3429413df27224ceeddd22500ce43b5431d698 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Jan 17 22:25:56 2014 -0800 + + Add note to README declaring snf fonts to be deprecated + + pcf was introduced to replace snf in X11R5 in 1991: + http://www.x.org/wiki/X11R5/#index56h3 + 22 years is long enough to move off a font format that was alive for + less than a decade before that, and widely considered a bad idea even + then: + http://www.faqs.org/faqs/fonts-faq/part15/ + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + Reviewed-by: Eric Anholt <eric@anholt.net> + Reviewed-by: Julien Cristau <jcristau@debian.org> + +commit efcb136a03f642fba7e289e25d5dcf609bd13f07 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Jan 17 22:25:01 2014 -0800 + + Add notes to README about various font formats & configure options + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + Reviewed-by: Eric Anholt <eric@anholt.net> + Reviewed-by: Julien Cristau <jcristau@debian.org> + +commit 5d696738c2ab901bdef004169799bb63939fa7b5 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Fri Jan 17 22:00:25 2014 -0800 + + Correct comment in configure.ac about scalable font support + + Bitstream Speedo support was removed in commit d50de26430c1a114a. + All scalable font support now goes through FreeType, which can + also handle some bitmap font formats as well. + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> + Reviewed-by: Eric Anholt <eric@anholt.net> + Reviewed-by: Julien Cristau <jcristau@debian.org> + +commit 6371fcf2b60e48605ed59f098d1e642e35b1d142 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Tue Jan 7 23:09:08 2014 -0800 + + Remove redundant setting of 'len' in SPropRecValList_add_by_font_cap + + Found by cppcheck 1.63: + [FreeType/xttcap.c:621] -> [FreeType/xttcap.c:624]: (performance) + Variable 'len' is reassigned a value before the old one has been used. + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net> + +commit 63c7ac4dbb739e51d55249e71282699e5e0d7e1d +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Tue Jan 7 22:58:22 2014 -0800 + + Initialize (unused) data field in fsListCataloguesReq before sending it. + + Quiets cppcheck 1.63 warning: + [fc/fserve.c:2972]: (error) Uninitialized variable: lcreq + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net> + +commit d279ffa49284b5e5f787f76edbe8c52226534a64 +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Tue Jan 7 22:29:04 2014 -0800 + + Remove redundant declaration of FontFileStartListFonts() + + Fixes gcc warning: + catalogue.c:336:1: warning: redundant redeclaration of + 'FontFileStartListFonts' [-Wredundant-decls] + In file included from ../../include/X11/fonts/fntfilst.h:40:0, + from catalogue.c:32: + ../../include/X11/fonts/fntfil.h:92:12: note: previous declaration + of 'FontFileStartListFonts' was here + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net> + +commit 2fb6295ace36394732815aca5aef1a85e63de56c +Author: Alan Coopersmith <alan.coopersmith@oracle.com> +Date: Tue Jan 7 22:15:50 2014 -0800 + + Fix unused variable 'dir' warnings + + catalogue.c: In function 'CatalogueOpenFont': + catalogue.c:290:22: warning: variable 'dir' set but not used [-Wunused-but-set-variable] + catalogue.c: In function 'CatalogueListFonts': + catalogue.c:324:22: warning: variable 'dir' set but not used [-Wunused-but-set-variable] + fpe.c: In function 'BuiltinResetFPE': + fpe.c:57:22: warning: variable 'dir' set but not used [-Wunused-but-set-variable] + + Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net> + commit 30110063857ff9a5f93f6d8d13f535c9b6e59e2a Author: Alan Coopersmith <alan.coopersmith@oracle.com> Date: Tue Jan 7 08:22:31 2014 -0800 diff --git a/libXfont/INSTALL b/libXfont/INSTALL index 8b82ade08..a1e89e18a 100644 --- a/libXfont/INSTALL +++ b/libXfont/INSTALL @@ -1,11 +1,13 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. Basic Installation ================== @@ -13,7 +15,11 @@ Basic Installation Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for -instructions specific to this package. +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -42,7 +48,7 @@ may remove or edit it. you want to change it or regenerate `configure' using a newer version of `autoconf'. -The simplest way to compile this package is: + The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. @@ -53,12 +59,22 @@ The simplest way to compile this package is: 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with - the package. + the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is @@ -67,8 +83,15 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. - 6. Often, you can also type `make uninstall' to remove the installed - files again. + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. Compilers and Options ===================== @@ -93,7 +116,8 @@ same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have @@ -120,7 +144,8 @@ Installation Names By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you @@ -131,15 +156,46 @@ Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. -Optional Features -================= - Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE @@ -152,6 +208,13 @@ find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + Particular systems ================== @@ -159,10 +222,15 @@ Particular systems CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: - ./configure CC="cc -Ae" + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `<wchar.h>' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended @@ -174,6 +242,16 @@ and if that doesn't work, try ./configure CC="cc -nodtk" + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + Specifying the System Type ========================== @@ -189,7 +267,8 @@ type, such as `sun4', or a canonical name which has the form: where SYSTEM can have one of these forms: - OS KERNEL-OS + OS + KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't @@ -277,7 +356,7 @@ operates. `configure' can determine that directory automatically. `--prefix=DIR' - Use DIR as the installation prefix. *Note Installation Names:: + Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. diff --git a/libXfont/README b/libXfont/README index 97a9e8afa..65f1aa437 100644 --- a/libXfont/README +++ b/libXfont/README @@ -5,6 +5,65 @@ X Font Server (xfs), and some font utilities (bdftopcf for instance), but should not be used by normal X11 clients. X11 clients access fonts via either the new API's in libXft, or the legacy API's in libX11. +libXfont supports a number of compression and font formats, and the +configure script takes various options to enable or disable them: + + -- Compression types: + + gzip - always enabled, no option to disable, requires libz + + bzip2 - disabled by default, enable via --with-bzip2, requires libbz2 + + -- Font formats: + + builtins - copies of the "fixed" & "cursor" fonts required by the + X protocol are built into the library so the X server always + has the fonts it requires to start up. Accessed via the + special 'built-ins' entry in the X server font path. + Enabled by default, disable via --disable-builtins. + + freetype - handles scalable font formats including OpenType, FreeType, + and PostScript formats. Requires FreeType2 library. + Can also be used to handle bdf & bitmap pcf font formats. + Enabled by default, disable via --disable-freetype. + + bdf bitmap fonts - text file format for distributing fonts, described + in http://www.x.org/docs/BDF/bdf.pdf specification. Normally + not used by the X server at runtime, as the fonts distributed + by X.Org in bdf format are compiled with bdftopcf when + installing/packaging them. + Enabled by default, disable via --disable-bdfformat. + + pcf bitmap fonts - standard bitmap font format since X11R5 in 1991, + used for all bitmap fonts installed from X.Org packages. + Compiled format is architecture independent. + As noted above, usually produced by bdftopcf. + Enabled by default, disable via --disable-pcfformat. + + snf bitmap fonts - standard bitmap font format prior to X11R5 in 1991, + remains only for backwards compatibility. Unlike pcf, snf files + are architecture specific, and contain less font information + than pcf files. snf fonts are deprecated and may be disabled + by default in future libXfont releases. + Enabled by default, disable via --disable-snfformat. + + -- Font services: + + xfs font servers - allows retreiving fonts as a client of an xfs server. + Enabled by default, disable via --disable-fc (font client). + + If enabled, you can also use the standard libxtrans flags to + configure which transports can be used to connect to xfs: + --enable-unix-transport Enable UNIX domain socket transport + --enable-tcp-transport Enable TCP socket transport (IPv4) + --enable-ipv6 Enable IPv6 support for tcp-transport + --enable-local-transport Enable os-specific local transport + (Change --enable to --disable to force disabling support.) + The default setting is to enable all of the transports the + configure script can find OS support for. + +-------------------------------------------------------------------------- + Please submit bugs & patches to the Xorg bugzilla: https://bugs.freedesktop.org/enter_bug.cgi?product=xorg diff --git a/libXfont/aclocal.m4 b/libXfont/aclocal.m4 index 17ad91eb5..e65b6ecd5 100644 --- a/libXfont/aclocal.m4 +++ b/libXfont/aclocal.m4 @@ -9929,7 +9929,7 @@ dnl DEALINGS IN THE SOFTWARE. # See the "minimum version" comment for each macro you use to see what # version you require. m4_defun([XORG_MACROS_VERSION],[ -m4_define([vers_have], [1.18.0]) +m4_define([vers_have], [1.19.0]) m4_define([maj_have], m4_substr(vers_have, 0, m4_index(vers_have, [.]))) m4_define([maj_needed], m4_substr([$1], 0, m4_index([$1], [.]))) m4_if(m4_cmp(maj_have, maj_needed), 0,, @@ -9979,6 +9979,7 @@ if test `${RAWCPP} < conftest.$ac_ext | grep -c 'preserve \"'` -eq 1 ; then AC_MSG_RESULT([no]) else if test `${RAWCPP} -traditional < conftest.$ac_ext | grep -c 'preserve \"'` -eq 1 ; then + TRADITIONALCPPFLAGS="-traditional" RAWCPPFLAGS="${RAWCPPFLAGS} -traditional" AC_MSG_RESULT([yes]) else @@ -9987,6 +9988,7 @@ else fi rm -f conftest.$ac_ext AC_SUBST(RAWCPPFLAGS) +AC_SUBST(TRADITIONALCPPFLAGS) ]) # XORG_PROG_RAWCPP # XORG_MANPAGE_SECTIONS() @@ -10774,6 +10776,29 @@ fi]) AM_CONDITIONAL([HAVE_FOP], [test "$have_fop" = yes]) ]) # XORG_WITH_FOP +# XORG_WITH_M4([MIN-VERSION]) +# --------------------------- +# Minimum version: 1.19.0 +# +# This macro attempts to locate an m4 macro processor which supports +# -I option and is only useful for modules relying on M4 in order to +# expand macros in source code files. +# +# Interface to module: +# M4: returns the path of the m4 program found +# returns the path set by the user in the environment +# +AC_DEFUN([XORG_WITH_M4], [ +AC_CACHE_CHECK([for m4 that supports -I option], [ac_cv_path_M4], + [AC_PATH_PROGS_FEATURE_CHECK([M4], [m4 gm4], + [[$ac_path_M4 -I. /dev/null > /dev/null 2>&1 && \ + ac_cv_path_M4=$ac_path_M4 ac_path_M4_found=:]], + [AC_MSG_ERROR([could not find m4 that supports -I option])], + [$PATH:/usr/gnu/bin])]) + +AC_SUBST([M4], [$ac_cv_path_M4]) +]) # XORG_WITH_M4 + # XORG_WITH_PS2PDF([DEFAULT]) # ---------------- # Minimum version: 1.6.0 diff --git a/libXfont/configure b/libXfont/configure index 618a6daeb..765aaf3db 100644 --- a/libXfont/configure +++ b/libXfont/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for libXfont 1.4.7. +# Generated by GNU Autoconf 2.68 for libXfont 1.4.8. # # Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=xorg>. # @@ -631,8 +631,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libXfont' PACKAGE_TARNAME='libXfont' -PACKAGE_VERSION='1.4.7' -PACKAGE_STRING='libXfont 1.4.7' +PACKAGE_VERSION='1.4.8' +PACKAGE_STRING='libXfont 1.4.8' PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg' PACKAGE_URL='' @@ -1440,7 +1440,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libXfont 1.4.7 to adapt to many kinds of systems. +\`configure' configures libXfont 1.4.8 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1510,7 +1510,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libXfont 1.4.7:";; + short | recursive ) echo "Configuration of libXfont 1.4.8:";; esac cat <<\_ACEOF @@ -1649,7 +1649,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libXfont configure 1.4.7 +libXfont configure 1.4.8 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2175,7 +2175,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libXfont $as_me 1.4.7, which was +It was created by libXfont $as_me 1.4.8, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3043,7 +3043,7 @@ fi # Define the identity of the package. PACKAGE='libXfont' - VERSION='1.4.7' + VERSION='1.4.8' cat >>confdefs.h <<_ACEOF @@ -18656,9 +18656,8 @@ fi XFONT_FONTFILE=no # -# Scalable fonts in files: -# FreeType -# Bitstream Speedo rasterizer +# FreeType for all scalable (OpenType, TrueType, PostScript) and +# some bitmap formats (BDF & PCF) # # Check whether --enable-freetype was given. if test "${enable_freetype+set}" = set; then : @@ -19139,12 +19138,12 @@ if test -n "$XFONT_CFLAGS"; then pkg_cv_XFONT_CFLAGS="$XFONT_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xproto xtrans fontsproto fontenc\""; } >&5 - ($PKG_CONFIG --exists --print-errors "xproto xtrans fontsproto fontenc") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xproto xtrans fontsproto < 2.1.3 fontenc\""; } >&5 + ($PKG_CONFIG --exists --print-errors "xproto xtrans fontsproto < 2.1.3 fontenc") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_XFONT_CFLAGS=`$PKG_CONFIG --cflags "xproto xtrans fontsproto fontenc" 2>/dev/null` + pkg_cv_XFONT_CFLAGS=`$PKG_CONFIG --cflags "xproto xtrans fontsproto < 2.1.3 fontenc" 2>/dev/null` else pkg_failed=yes fi @@ -19155,12 +19154,12 @@ if test -n "$XFONT_LIBS"; then pkg_cv_XFONT_LIBS="$XFONT_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xproto xtrans fontsproto fontenc\""; } >&5 - ($PKG_CONFIG --exists --print-errors "xproto xtrans fontsproto fontenc") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xproto xtrans fontsproto < 2.1.3 fontenc\""; } >&5 + ($PKG_CONFIG --exists --print-errors "xproto xtrans fontsproto < 2.1.3 fontenc") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_XFONT_LIBS=`$PKG_CONFIG --libs "xproto xtrans fontsproto fontenc" 2>/dev/null` + pkg_cv_XFONT_LIBS=`$PKG_CONFIG --libs "xproto xtrans fontsproto < 2.1.3 fontenc" 2>/dev/null` else pkg_failed=yes fi @@ -19178,14 +19177,14 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - XFONT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "xproto xtrans fontsproto fontenc" 2>&1` + XFONT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "xproto xtrans fontsproto < 2.1.3 fontenc" 2>&1` else - XFONT_PKG_ERRORS=`$PKG_CONFIG --print-errors "xproto xtrans fontsproto fontenc" 2>&1` + XFONT_PKG_ERRORS=`$PKG_CONFIG --print-errors "xproto xtrans fontsproto < 2.1.3 fontenc" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$XFONT_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (xproto xtrans fontsproto fontenc) were not met: + as_fn_error $? "Package requirements (xproto xtrans fontsproto < 2.1.3 fontenc) were not met: $XFONT_PKG_ERRORS @@ -20153,7 +20152,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libXfont $as_me 1.4.7, which was +This file was extended by libXfont $as_me 1.4.8, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20219,7 +20218,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libXfont config.status 1.4.7 +libXfont config.status 1.4.8 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/libXfont/configure.ac b/libXfont/configure.ac index 01e7b6e58..ea3368442 100644 --- a/libXfont/configure.ac +++ b/libXfont/configure.ac @@ -21,7 +21,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([libXfont], [1.4.7], +AC_INIT([libXfont], [1.4.8], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXfont]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h include/X11/fonts/fontconf.h]) @@ -64,9 +64,8 @@ PKG_PROG_PKG_CONFIG XFONT_FONTFILE=no # -# Scalable fonts in files: -# FreeType -# Bitstream Speedo rasterizer +# FreeType for all scalable (OpenType, TrueType, PostScript) and +# some bitmap formats (BDF & PCF) # AC_ARG_ENABLE(freetype, [ --disable-freetype],[XFONT_FREETYPE=$enableval],[XFONT_FREETYPE=yes]) AM_CONDITIONAL(XFONT_FREETYPE, [test x$XFONT_FREETYPE = xyes]) @@ -181,7 +180,7 @@ fi AC_CHECK_LIB(m, hypot, [MATH_LIBS=-lm AC_SUBST(MATH_LIBS)], AC_MSG_ERROR([*** libm is required])) -PKG_CHECK_MODULES(XFONT, xproto xtrans fontsproto fontenc) +PKG_CHECK_MODULES(XFONT, [xproto xtrans fontsproto < 2.1.3 fontenc]) # Transport selection macro from xtrans.m4 XTRANS_CONNECTION_FLAGS diff --git a/libXfont/src/FreeType/ftfuncs.c b/libXfont/src/FreeType/ftfuncs.c index 44e5e0288..bca58188b 100644 --- a/libXfont/src/FreeType/ftfuncs.c +++ b/libXfont/src/FreeType/ftfuncs.c @@ -1865,7 +1865,7 @@ FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info, i++; info->props[i].name = MakeAtom("RASTERIZER_NAME", 15, TRUE); - info->props[i].value = MakeAtom("FreeType", 10, TRUE); + info->props[i].value = MakeAtom("FreeType", 8, TRUE); info->isStringProp[i] = 1; i++; diff --git a/libXfont/src/FreeType/xttcap.c b/libXfont/src/FreeType/xttcap.c index 104dc89e4..cee752ebf 100644 --- a/libXfont/src/FreeType/xttcap.c +++ b/libXfont/src/FreeType/xttcap.c @@ -621,7 +621,6 @@ SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList, int len = term-p-1; char *value; - len = term-p-1; value=malloc(len+1); memcpy(value, p+1, len); value[len]='\0'; diff --git a/libXfont/src/builtins/fpe.c b/libXfont/src/builtins/fpe.c index 403dbb7db..689f22a52 100644 --- a/libXfont/src/builtins/fpe.c +++ b/libXfont/src/builtins/fpe.c @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Keith Packard, SuSE, Inc. @@ -54,9 +54,6 @@ BuiltinInitFPE (FontPathElementPtr fpe) static int BuiltinResetFPE (FontPathElementPtr fpe) { - FontDirectoryPtr dir; - - dir = (FontDirectoryPtr) fpe->private; /* builtins can't change! */ return Successful; } diff --git a/libXfont/src/fc/fsconvert.c b/libXfont/src/fc/fsconvert.c index 15c5e4200..7a6033119 100644 --- a/libXfont/src/fc/fsconvert.c +++ b/libXfont/src/fc/fsconvert.c @@ -86,7 +86,7 @@ _fs_init_fontinfo(FSFpePtr conn, FontInfoPtr pfi) } int -_fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd, +_fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd, FontInfoPtr pfi) { FontPropPtr dprop; @@ -102,22 +102,26 @@ _fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd, nprops = pfi->nprops = pi->num_offsets; - if (nprops < 0 - || nprops > SIZE_MAX/(sizeof(FontPropRec) + sizeof(char))) + if (nprops < 0 + || nprops > SIZE_MAX/(sizeof(FontPropRec) + sizeof(char))) return -1; - + dprop = malloc(sizeof(FontPropRec) * nprops + sizeof (char) * nprops); if (!dprop) return -1; - + is_str = (char *) (dprop + nprops); pfi->props = dprop; pfi->isStringProp = is_str; off_adr = (char *)po; - for (i = 0; i < nprops; i++, dprop++, is_str++) + for (i = 0; i < nprops; i++, dprop++, is_str++) { memcpy(&local_off, off_adr, SIZEOF(fsPropOffset)); + if ((local_off.name.position >= pi->data_len) || + (local_off.name.length > + (pi->data_len - local_off.name.position))) + goto bail; dprop->name = MakeAtom(&pdc[local_off.name.position], local_off.name.length, 1); if (local_off.type != PropTypeString) { @@ -125,10 +129,15 @@ _fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd, dprop->value = local_off.value.position; } else { *is_str = TRUE; + if ((local_off.value.position >= pi->data_len) || + (local_off.value.length > + (pi->data_len - local_off.value.position))) + goto bail; dprop->value = (INT32) MakeAtom(&pdc[local_off.value.position], local_off.value.length, 1); if (dprop->value == BAD_RESOURCE) { + bail: free (pfi->props); pfi->nprops = 0; pfi->props = 0; @@ -154,8 +163,8 @@ _fs_free_props (FontInfoPtr pfi) } int -_fs_convert_lfwi_reply(FSFpePtr conn, FontInfoPtr pfi, - fsListFontsWithXInfoReply *fsrep, +_fs_convert_lfwi_reply(FSFpePtr conn, FontInfoPtr pfi, + fsListFontsWithXInfoReply *fsrep, fsPropInfo *pi, fsPropOffset *po, pointer pd) { fsUnpack_XFontInfoHeader(fsrep, pfi); @@ -188,8 +197,8 @@ _fs_convert_lfwi_reply(FSFpePtr conn, FontInfoPtr pfi, */ /* ARGSUSED */ int -fs_build_range(FontPtr pfont, Bool range_flag, unsigned int count, - int item_size, unsigned char *data, int *nranges, +fs_build_range(FontPtr pfont, Bool range_flag, unsigned int count, + int item_size, unsigned char *data, int *nranges, fsRange **ranges) { FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate); @@ -350,7 +359,7 @@ fs_build_range(FontPtr pfont, Bool range_flag, unsigned int count, requests needs to be cancelled. */ void -_fs_clean_aborted_loadglyphs(FontPtr pfont, int num_expected_ranges, +_fs_clean_aborted_loadglyphs(FontPtr pfont, int num_expected_ranges, fsRange *expected_ranges) { register FSFontPtr fsfont; @@ -396,8 +405,8 @@ _fs_clean_aborted_loadglyphs(FontPtr pfont, int num_expected_ranges, } static int -_fs_get_glyphs(FontPtr pFont, unsigned long count, unsigned char *chars, - FontEncoding charEncoding, +_fs_get_glyphs(FontPtr pFont, unsigned long count, unsigned char *chars, + FontEncoding charEncoding, unsigned long *glyphCount, /* RETURN */ CharInfoPtr *glyphs) /* RETURN */ { @@ -508,8 +517,8 @@ _fs_get_glyphs(FontPtr pFont, unsigned long count, unsigned char *chars, static int -_fs_get_metrics(FontPtr pFont, unsigned long count, unsigned char *chars, - FontEncoding charEncoding, +_fs_get_metrics(FontPtr pFont, unsigned long count, unsigned char *chars, + FontEncoding charEncoding, unsigned long *glyphCount, /* RETURN */ xCharInfo **glyphs) /* RETURN */ { @@ -620,15 +629,15 @@ _fs_unload_font(FontPtr pfont) fsdata->glyphs = glyphs->next; free (glyphs); } - + /* XXX we may get called after the resource DB has been cleaned out */ if (find_old_font(fsd->fontid)) DeleteFontClientID (fsd->fontid); - + _fs_free_props (&pfont->info); - + free(fsdata); - + DestroyFontRec(pfont); } @@ -656,11 +665,11 @@ fs_create_font (FontPathElementPtr fpe, fsd = (FSFontDataPtr) (fsfont + 1); bzero((char *) fsfont, sizeof(FSFontRec)); bzero((char *) fsd, sizeof(FSFontDataRec)); - + pfont->fpe = fpe; pfont->fontPrivate = (pointer) fsfont; pfont->fpePrivate = (pointer) fsd; - + /* These font components will be needed in packGlyphs */ CheckFSFormat(format, BitmapFormatMaskBit | BitmapFormatMaskByte | @@ -676,17 +685,17 @@ fs_create_font (FontPathElementPtr fpe, pfont->byte = byte; pfont->scan = scan; pfont->glyph = glyph; - + pfont->info.nprops = 0; pfont->info.props = 0; pfont->info.isStringProp = 0; - + /* set font function pointers */ pfont->get_glyphs = _fs_get_glyphs; pfont->get_metrics = _fs_get_metrics; pfont->unload_font = _fs_unload_font; pfont->unload_glyphs = NULL; - + /* set the FPE private information */ fsd->format = format; fsd->fmask = fmask; @@ -694,9 +703,9 @@ fs_create_font (FontPathElementPtr fpe, memcpy (fsd->name, name, namelen); fsd->name[namelen] = '\0'; fsd->fontid = GetNewFontClientID (); - + /* save the ID */ - if (!StoreFontClientFont(pfont, fsd->fontid)) + if (!StoreFontClientFont(pfont, fsd->fontid)) { free (fsfont); DestroyFontRec (pfont); @@ -712,7 +721,12 @@ fs_alloc_glyphs (FontPtr pFont, int size) FSGlyphPtr glyphs; FSFontPtr fsfont = (FSFontPtr) pFont->fontPrivate; - glyphs = malloc (sizeof (FSGlyphRec) + size); + if (size < (INT_MAX - sizeof (FSGlyphRec))) + glyphs = malloc (sizeof (FSGlyphRec) + size); + else + glyphs = NULL; + if (glyphs == NULL) + return NULL; glyphs->next = fsfont->glyphs; fsfont->glyphs = glyphs; return (pointer) (glyphs + 1); diff --git a/libXfont/src/fc/fserve.c b/libXfont/src/fc/fserve.c index b02b0b749..1e1093cd5 100644 --- a/libXfont/src/fc/fserve.c +++ b/libXfont/src/fc/fserve.c @@ -70,6 +70,7 @@ in this Software without prior written authorization from The Open Group. #include "fservestr.h" #include <X11/fonts/fontutil.h> #include <errno.h> +#include <limits.h> #include <time.h> #define Time_t time_t @@ -84,28 +85,37 @@ in this Software without prior written authorization from The Open Group. #define MIN(a,b) ((a)<(b)?(a):(b)) #endif #define TimeCmp(a,c,b) ((int) ((a) - (b)) c 0) - + #define NONZEROMETRICS(pci) ((pci)->leftSideBearing || \ (pci)->rightSideBearing || \ (pci)->ascent || \ (pci)->descent || \ (pci)->characterWidth) +/* + * SIZEOF(r) is in bytes, length fields in the protocol are in 32-bit words, + * so this converts for doing size comparisons. + */ +#define LENGTHOF(r) (SIZEOF(r) >> 2) + +/* Somewhat arbitrary limit on maximum reply size we'll try to read. */ +#define MAX_REPLY_LENGTH ((64 * 1024 * 1024) >> 2) + extern void ErrorF(const char *f, ...); static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec ); static int fs_read_list ( FontPathElementPtr fpe, FSBlockDataPtr blockrec ); -static int fs_read_list_info ( FontPathElementPtr fpe, +static int fs_read_list_info ( FontPathElementPtr fpe, FSBlockDataPtr blockrec ); extern fd_set _fs_fd_mask; -static void fs_block_handler ( pointer data, OSTimePtr wt, +static void fs_block_handler ( pointer data, OSTimePtr wt, pointer LastSelectMask ); static int fs_wakeup ( FontPathElementPtr fpe, unsigned long *mask ); /* - * List of all FPEs + * List of all FPEs */ static FSFpePtr fs_fpes; /* @@ -114,7 +124,7 @@ static FSFpePtr fs_fpes; static CARD32 fs_blockState; static int _fs_restart_connection ( FSFpePtr conn ); -static void fs_send_query_bitmaps ( FontPathElementPtr fpe, +static void fs_send_query_bitmaps ( FontPathElementPtr fpe, FSBlockDataPtr blockrec ); static int fs_send_close_font ( FontPathElementPtr fpe, Font id ); static void fs_client_died ( pointer client, FontPathElementPtr fpe ); @@ -206,9 +216,22 @@ _fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep) rep->sequenceNumber, conn->reqbuffer[i].opcode); } + +#define _fs_reply_failed(rep, name, op) do { \ + if (rep) { \ + if (rep->type == FS_Error) \ + fprintf (stderr, "Error: %d Request: %s\n", \ + ((fsError *)rep)->request, #name); \ + else \ + fprintf (stderr, "Bad Length for %s Reply: %d %s %d\n", \ + #name, rep->length, op, LENGTHOF(name)); \ + } \ +} while (0) + #else #define _fs_add_req_log(conn,op) ((conn)->current_seq++) #define _fs_add_rep_log(conn,rep) +#define _fs_reply_failed(rep,name,op) #endif static Bool @@ -240,7 +263,7 @@ _fs_client_resolution(FSFpePtr conn) } } -/* +/* * close font server and remove any state associated with * this connection - this includes any client records. */ @@ -251,8 +274,8 @@ fs_close_conn(FSFpePtr conn) FSClientPtr client, nclient; _fs_close_server (conn); - - for (client = conn->clients; client; client = nclient) + + for (client = conn->clients; client; client = nclient) { nclient = client->next; free (client); @@ -308,7 +331,7 @@ fs_init_fpe(FontPathElementPtr fpe) err = Successful; } } - + if (err == Successful) { #ifdef NCD @@ -348,7 +371,7 @@ static int fs_free_fpe(FontPathElementPtr fpe) { FSFpePtr conn = (FSFpePtr) fpe->private, *prev; - + /* unhook from chain of all font servers */ for (prev = &fs_fpes; *prev; prev = &(*prev)->next) { @@ -410,7 +433,7 @@ fs_new_block_rec(FontPathElementPtr fpe, pointer client, int type) blockrec->type = type; blockrec->depending = 0; blockrec->next = (FSBlockDataPtr) 0; - + /* stick it on the end of the list (since its expected last) */ for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next) ; @@ -423,7 +446,7 @@ static void _fs_set_pending_reply (FSFpePtr conn) { FSBlockDataPtr blockrec; - + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) if (blockrec->errcode == StillWorking) break; @@ -442,7 +465,7 @@ _fs_remove_block_rec(FSFpePtr conn, FSBlockDataPtr blockrec) FSBlockDataPtr *prev; for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next) - if (*prev == blockrec) + if (*prev == blockrec) { *prev = blockrec->next; break; @@ -461,7 +484,7 @@ static void _fs_signal_clients_depending(FSClientsDependingPtr *clients_depending) { FSClientsDependingPtr p; - + while ((p = *clients_depending)) { *clients_depending = p->next; @@ -474,14 +497,14 @@ static int _fs_add_clients_depending(FSClientsDependingPtr *clients_depending, pointer client) { FSClientsDependingPtr new, cd; - - for (; (cd = *clients_depending); + + for (; (cd = *clients_depending); clients_depending = &(*clients_depending)->next) { - if (cd->client == client) + if (cd->client == client) return Suspended; } - + new = malloc (sizeof (FSClientsDependingRec)); if (!new) return BadAlloc; @@ -503,17 +526,17 @@ _fs_clean_aborted_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec) switch(blockrec->type) { case FS_OPEN_FONT: { FSBlockedFontPtr bfont = (FSBlockedFontPtr)blockrec->data; - + fs_cleanup_bfont (bfont); _fs_signal_clients_depending(&bfont->clients_depending); break; } case FS_LOAD_GLYPHS: { FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data; - + _fs_clean_aborted_loadglyphs(bglyph->pfont, bglyph->num_expected_ranges, - bglyph->expected_ranges); + bglyph->expected_ranges); _fs_signal_clients_depending(&bglyph->clients_depending); break; } @@ -550,12 +573,12 @@ fs_cleanup_bfont (FSBlockedFontPtr bfont) if (bfont->pfont) { fsd = (FSFontDataRec *) bfont->pfont->fpePrivate; - + /* make sure the FS knows we choked on it */ fs_send_close_font(bfont->pfont->fpe, bfont->fontid); - + /* - * Either unload the font if it's being opened for + * Either unload the font if it's being opened for * the first time, or smash the generation field to * mark this font as an orphan */ @@ -590,16 +613,31 @@ fs_get_reply (FSFpePtr conn, int *error) *error = FSIO_BLOCK; return 0; } - + ret = _fs_start_read (conn, sizeof (fsGenericReply), &buf); if (ret != FSIO_READY) { *error = FSIO_BLOCK; return 0; } - + rep = (fsGenericReply *) buf; + /* + * Refuse to accept replies longer than a maximum reasonable length, + * before we pass to _fs_start_read, since it will try to resize the + * incoming connection buffer to this size. Also avoids integer overflow + * on 32-bit systems. + */ + if (rep->length > MAX_REPLY_LENGTH) + { + ErrorF("fserve: reply length %d > MAX_REPLY_LENGTH, disconnecting" + " from font server\n", rep->length); + _fs_connection_died (conn); + *error = FSIO_ERROR; + return 0; + } + ret = _fs_start_read (conn, rep->length << 2, &buf); if (ret != FSIO_READY) { @@ -608,7 +646,7 @@ fs_get_reply (FSFpePtr conn, int *error) } *error = FSIO_READY; - + return (fsGenericReply *) buf; } @@ -616,7 +654,7 @@ static Bool fs_reply_ready (FSFpePtr conn) { fsGenericReply *rep; - + if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask)) return FALSE; if (fs_data_read (conn) < sizeof (fsGenericReply)) @@ -651,10 +689,10 @@ static int fs_await_reply (FSFpePtr conn) { int ret; - + if (conn->blockState & FS_COMPLETE_REPLY) return FSIO_READY; - + while (!fs_get_reply (conn, &ret)) { if (ret != FSIO_BLOCK) @@ -682,16 +720,18 @@ fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec) int ret; rep = (fsOpenBitmapFontReply *) fs_get_reply (conn, &ret); - if (!rep || rep->type == FS_Error) + if (!rep || rep->type == FS_Error || + (rep->length != LENGTHOF(fsOpenBitmapFontReply))) { if (ret == FSIO_BLOCK) return StillWorking; if (rep) _fs_done_read (conn, rep->length << 2); fs_cleanup_bfont (bfont); + _fs_reply_failed (rep, fsOpenBitmapFontReply, "!="); return BadFontName; } - + /* If we're not reopening a font and FS detected a duplicate font open request, replace our reference to the new font with a reference to an existing font (possibly one not finished @@ -701,10 +741,10 @@ fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec) if we we decide (in fs_read_query_info()) that we don't like what we got. */ - if (rep->otherid && !(bfont->flags & FontReopen)) + if (rep->otherid && !(bfont->flags & FontReopen)) { fs_cleanup_bfont (bfont); - + /* Find old font if we're completely done getting it from server. */ bfont->pfont = find_old_font(rep->otherid); bfont->freeFont = FALSE; @@ -715,12 +755,12 @@ fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec) */ for (blockOrig = conn->blockedRequests; blockOrig; - blockOrig = blockOrig->next) + blockOrig = blockOrig->next) { - if (blockOrig != blockrec && blockOrig->type == FS_OPEN_FONT) + if (blockOrig != blockrec && blockOrig->type == FS_OPEN_FONT) { origBfont = (FSBlockedFontPtr) blockOrig->data; - if (origBfont->fontid == rep->otherid) + if (origBfont->fontid == rep->otherid) { blockrec->depending = blockOrig->depending; blockOrig->depending = blockrec; @@ -757,7 +797,7 @@ static Bool fs_fonts_match (FontInfoPtr pInfo1, FontInfoPtr pInfo2) { int i; - + if (pInfo1->firstCol != pInfo2->firstCol || pInfo1->lastCol != pInfo2->lastCol || pInfo1->firstRow != pInfo2->firstRow || @@ -815,6 +855,7 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) FSFpePtr conn = (FSFpePtr) fpe->private; fsQueryXInfoReply *rep; char *buf; + long bufleft; /* length of reply left to use */ fsPropInfo *pi; fsPropOffset *po; pointer pd; @@ -824,16 +865,18 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) int ret; rep = (fsQueryXInfoReply *) fs_get_reply (conn, &ret); - if (!rep || rep->type == FS_Error) + if (!rep || rep->type == FS_Error || + (rep->length < LENGTHOF(fsQueryXInfoReply))) { if (ret == FSIO_BLOCK) return StillWorking; if (rep) _fs_done_read (conn, rep->length << 2); fs_cleanup_bfont (bfont); + _fs_reply_failed (rep, fsQueryXInfoReply, "<"); return BadFontName; } - + /* If this is a reopen, accumulate the query info into a dummy font and compare to our original data. */ if (bfont->flags & FontReopen) @@ -843,27 +886,63 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) buf = (char *) rep; buf += SIZEOF(fsQueryXInfoReply); - + + bufleft = rep->length << 2; + bufleft -= SIZEOF(fsQueryXInfoReply); + /* move the data over */ fsUnpack_XFontInfoHeader(rep, pInfo); - + /* compute accelerators */ _fs_init_fontinfo(conn, pInfo); /* Compute offsets into the reply */ + if (bufleft < SIZEOF(fsPropInfo)) + { + ret = -1; +#ifdef DEBUG + fprintf(stderr, "fsQueryXInfo: bufleft (%ld) < SIZEOF(fsPropInfo)\n", + bufleft); +#endif + goto bail; + } pi = (fsPropInfo *) buf; buf += SIZEOF (fsPropInfo); - + bufleft -= SIZEOF(fsPropInfo); + + if ((bufleft / SIZEOF(fsPropOffset)) < pi->num_offsets) + { + ret = -1; +#ifdef DEBUG + fprintf(stderr, + "fsQueryXInfo: bufleft (%ld) / SIZEOF(fsPropOffset) < %d\n", + bufleft, pi->num_offsets); +#endif + goto bail; + } po = (fsPropOffset *) buf; buf += pi->num_offsets * SIZEOF(fsPropOffset); + bufleft -= pi->num_offsets * SIZEOF(fsPropOffset); + if (bufleft < pi->data_len) + { + ret = -1; +#ifdef DEBUG + fprintf(stderr, + "fsQueryXInfo: bufleft (%ld) < data_len (%d)\n", + bufleft, pi->data_len); +#endif + goto bail; + } pd = (pointer) buf; buf += pi->data_len; - + bufleft -= pi->data_len; + /* convert the properties and step over the reply */ ret = _fs_convert_props(pi, po, pd, pInfo); + bail: _fs_done_read (conn, rep->length << 2); - + if (ret == -1) { fs_cleanup_bfont (bfont); @@ -889,7 +968,7 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) err = BadFontName; } _fs_free_props (pInfo); - + return err; } @@ -904,14 +983,14 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) * Figure out if the whole font should get loaded right now. */ if (glyphCachingMode == CACHING_OFF || - (glyphCachingMode == CACHE_16_BIT_GLYPHS + (glyphCachingMode == CACHE_16_BIT_GLYPHS && !bfont->pfont->info.lastRow)) { bfont->flags |= FontLoadAll; } - + /* - * Ready to send the query bitmaps; the terminal font bit has + * Ready to send the query bitmaps; the terminal font bit has * been computed and glyphCaching has been considered */ if (bfont->flags & FontLoadBitmaps) @@ -927,7 +1006,7 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) */ blockrec->sequenceNumber = bfont->queryExtentsSequence; conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout; - + return StillWorking; } @@ -951,16 +1030,18 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) FontInfoRec *fi = &bfont->pfont->info; rep = (fsQueryXExtents16Reply *) fs_get_reply (conn, &ret); - if (!rep || rep->type == FS_Error) + if (!rep || rep->type == FS_Error || + (rep->length < LENGTHOF(fsQueryXExtents16Reply))) { if (ret == FSIO_BLOCK) return StillWorking; if (rep) _fs_done_read (conn, rep->length << 2); fs_cleanup_bfont (bfont); + _fs_reply_failed (rep, fsQueryXExtents16Reply, "<"); return BadFontName; } - + /* move the data over */ /* need separate inkMetrics for fixed font server protocol version */ numExtents = rep->num_extents; @@ -970,9 +1051,28 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) numInfos *= 2; haveInk = TRUE; } - ci = pCI = malloc(sizeof(CharInfoRec) * numInfos); + if (numInfos >= (INT_MAX / sizeof(CharInfoRec))) { +#ifdef DEBUG + fprintf(stderr, + "fsQueryXExtents16: numInfos (%d) >= %ld\n", + numInfos, (INT_MAX / sizeof(CharInfoRec))); +#endif + pCI = NULL; + } + else if (numExtents > ((rep->length - LENGTHOF(fsQueryXExtents16Reply)) + / LENGTHOF(fsXCharInfo))) { +#ifdef DEBUG + fprintf(stderr, + "fsQueryXExtents16: numExtents (%d) > (%d - %d) / %d\n", + numExtents, rep->length, + LENGTHOF(fsQueryXExtents16Reply), LENGTHOF(fsXCharInfo)); +#endif + pCI = NULL; + } + else + pCI = malloc(sizeof(CharInfoRec) * numInfos); - if (!pCI) + if (!pCI) { _fs_done_read (conn, rep->length << 2); fs_cleanup_bfont(bfont); @@ -987,10 +1087,10 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) buf = (char *) rep; buf += SIZEOF (fsQueryXExtents16Reply); fsci = buf; - + fsd->glyphs_to_get = 0; ci = fsfont->inkMetrics; - for (i = 0; i < numExtents; i++) + for (i = 0; i < numExtents; i++) { memcpy(&fscilocal, fsci, SIZEOF(fsXCharInfo)); /* align it */ _fs_convert_char_info(&fscilocal, &ci->metrics); @@ -1030,7 +1130,7 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) /* Done with reply */ _fs_done_read (conn, rep->length << 2); - + /* build bitmap metrics, ImageRectMax style */ if (haveInk) { @@ -1098,7 +1198,7 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) } bfont->state = FS_GLYPHS_REPLY; - if (bfont->flags & FontLoadBitmaps) + if (bfont->flags & FontLoadBitmaps) { /* * Reset the blockrec for the next reply @@ -1111,7 +1211,7 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) } #ifdef DEBUG -static char *fs_open_states[] = { +static const char *fs_open_states[] = { "OPEN_REPLY ", "INFO_REPLY ", "EXTENT_REPLY", @@ -1129,7 +1229,7 @@ fs_do_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec) #ifdef DEBUG fprintf (stderr, "fs_do_open_font state %s %s\n", - fs_open_states[bfont->state], + fs_open_states[bfont->state], ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name); #endif err = BadFontName; @@ -1165,10 +1265,10 @@ fs_do_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec) #ifdef DEBUG fprintf (stderr, "fs_do_open_font err %d\n", err); #endif - if (err != StillWorking) + if (err != StillWorking) { bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */ - while ((blockrec = blockrec->depending)) + while ((blockrec = blockrec->depending)) { bfont = (FSBlockedFontPtr) blockrec->data; bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */ @@ -1188,7 +1288,7 @@ void _fs_unmark_block (FSFpePtr conn, CARD32 mask) { FSFpePtr c; - + if (conn->blockState & mask) { conn->blockState &= ~mask; @@ -1207,7 +1307,7 @@ fs_block_handler(pointer data, OSTimePtr wt, pointer LastSelectMask) int soonest; FSFpePtr conn; - XFD_ORSET((fd_set *)LastSelectMask, (fd_set *)LastSelectMask, + XFD_ORSET((fd_set *)LastSelectMask, (fd_set *)LastSelectMask, &_fs_fd_mask); /* * Flush all pending output @@ -1280,7 +1380,7 @@ fs_block_handler(pointer data, OSTimePtr wt, pointer LastSelectMask) static void fs_handle_unexpected(FSFpePtr conn, fsGenericReply *rep) { - if (rep->type == FS_Event && rep->data1 == KeepAlive) + if (rep->type == FS_Event && rep->data1 == KeepAlive) { fsNoopReq req; @@ -1302,27 +1402,27 @@ fs_read_reply (FontPathElementPtr fpe, pointer client) int ret; int err; fsGenericReply *rep; - + if ((rep = fs_get_reply (conn, &ret))) { _fs_add_rep_log (conn, rep); - for (blockrec = conn->blockedRequests; - blockrec; - blockrec = blockrec->next) + for (blockrec = conn->blockedRequests; + blockrec; + blockrec = blockrec->next) { if (blockrec->sequenceNumber == rep->sequenceNumber) break; } err = Successful; - if (!blockrec) + if (!blockrec) { fs_handle_unexpected(conn, rep); } else { - /* - * go read it, and if we're done, - * wake up the appropriate client + /* + * go read it, and if we're done, + * wake up the appropriate client */ switch (blockrec->type) { case FS_OPEN_FONT: @@ -1343,7 +1443,7 @@ fs_read_reply (FontPathElementPtr fpe, pointer client) err = blockrec->errcode; if (err != StillWorking) { - while (blockrec) + while (blockrec) { blockrec->errcode = err; if (client != blockrec->client) @@ -1366,7 +1466,7 @@ fs_wakeup(FontPathElementPtr fpe, unsigned long *mask) fd_set *LastSelectMask = (fd_set *) mask; FSFpePtr conn = (FSFpePtr) fpe->private; - /* + /* * Don't continue if the fd is -1 (which will be true when the * font server terminates */ @@ -1381,7 +1481,6 @@ fs_wakeup(FontPathElementPtr fpe, unsigned long *mask) { FSBlockDataPtr blockrec; FSBlockedFontPtr bfont; - FSBlockedListPtr blist; static CARD32 lastState; static FSBlockDataPtr lastBlock; @@ -1400,12 +1499,11 @@ fs_wakeup(FontPathElementPtr fpe, unsigned long *mask) blockrec->errcode, blockrec->sequenceNumber, fs_open_states[bfont->state], - bfont->pfont ? + bfont->pfont ? ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name : "<freed>"); break; case FS_LIST_FONTS: - blist = (FSBlockedListPtr) blockrec->data; fprintf (stderr, " Blocked list errcode %d sequence %d\n", blockrec->errcode, blockrec->sequenceNumber); break; @@ -1418,7 +1516,7 @@ fs_wakeup(FontPathElementPtr fpe, unsigned long *mask) } } } -#endif +#endif return FALSE; } @@ -1446,7 +1544,7 @@ _fs_restart_connection(FSFpePtr conn) FSBlockDataPtr block; _fs_unmark_block (conn, FS_GIVE_UP); - while ((block = (FSBlockDataPtr) conn->blockedRequests)) + while ((block = (FSBlockDataPtr) conn->blockedRequests)) { if (block->errcode == StillWorking) { @@ -1471,7 +1569,7 @@ _fs_giveup (FSFpePtr conn) fprintf (stderr, "give up on FS \"%s\"\n", conn->servername); #endif _fs_mark_block (conn, FS_GIVE_UP); - while ((block = (FSBlockDataPtr) conn->blockedRequests)) + while ((block = (FSBlockDataPtr) conn->blockedRequests)) { if (block->errcode == StillWorking) { @@ -1494,7 +1592,7 @@ _fs_do_blocked (FSFpePtr conn) { _fs_giveup (conn); } - else + else { if (conn->blockState & FS_BROKEN_CONNECTION) { @@ -1516,9 +1614,9 @@ _fs_do_blocked (FSFpePtr conn) */ /* ARGSUSED */ static int -fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, - char *name, int namelen, - fsBitmapFormat format, fsBitmapFormatMask fmask, +fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, + char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, XID id, FontPtr *ppfont) { FSFpePtr conn = (FSFpePtr) fpe->private; @@ -1534,10 +1632,10 @@ fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, if (conn->blockState & FS_GIVE_UP) return BadFontName; - + if (namelen <= 0 || namelen > sizeof (buf) - 1) return BadFontName; - + /* * Get the font structure put together, either by reusing * the existing one or creating a new one @@ -1574,10 +1672,10 @@ fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, font = fs_create_font (fpe, name, namelen, format, fmask); if (!font) return AllocError; - + fsd = (FSFontDataPtr)font->fpePrivate; } - + /* make a new block record, and add it to the end of the list */ blockrec = fs_new_block_rec(font->fpe, client, FS_OPEN_FONT); if (!blockrec) @@ -1586,7 +1684,7 @@ fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, (*font->unload_font) (font); return AllocError; } - + /* * Must check this before generating any protocol, otherwise we'll * mess up a reconnect in progress @@ -1596,7 +1694,7 @@ fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, _fs_pending_reply (conn); return Suspended; } - + fsd->generation = conn->generation; bfont = (FSBlockedFontPtr) blockrec->data; @@ -1626,17 +1724,17 @@ fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, _fs_write_pad(conn, (char *) buf, namelen + 1); blockrec->sequenceNumber = conn->current_seq; - + inforeq.reqType = FS_QueryXInfo; inforeq.pad = 0; inforeq.id = fsd->fontid; inforeq.length = SIZEOF(fsQueryXInfoReq) >> 2; bfont->queryInfoSequence = conn->current_seq + 1; - + _fs_add_req_log(conn, FS_QueryXInfo); _fs_write(conn, (char *) &inforeq, SIZEOF(fsQueryXInfoReq)); - + if (!(bfont->flags & FontReopen)) { extreq.reqType = FS_QueryXExtents16; @@ -1644,15 +1742,15 @@ fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, extreq.fid = fsd->fontid; extreq.num_ranges = 0; extreq.length = SIZEOF(fsQueryXExtents16Req) >> 2; - + bfont->queryExtentsSequence = conn->current_seq + 1; - + _fs_add_req_log(conn, FS_QueryXExtents16); _fs_write(conn, (char *) &extreq, SIZEOF(fsQueryXExtents16Req)); } - + #ifdef NCD - if (configData.ExtendedFontDiags) + if (configData.ExtendedFontDiags) { memcpy(buf, name, MIN(256, namelen)); buf[MIN(256, namelen)] = '\0'; @@ -1661,7 +1759,7 @@ fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, } #endif _fs_prepare_for_reply (conn); - + err = blockrec->errcode; if (bfont->flags & FontOpenSync) { @@ -1701,16 +1799,16 @@ fs_send_query_bitmaps(FontPathElementPtr fpe, FSBlockDataPtr blockrec) bitreq.num_ranges = 0; bfont->queryBitmapsSequence = conn->current_seq + 1; - + _fs_add_req_log(conn, FS_QueryXBitmaps16); _fs_write(conn, (char *) &bitreq, SIZEOF(fsQueryXBitmaps16Req)); } /* ARGSUSED */ static int -fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags, - char *name, int namelen, - fsBitmapFormat format, fsBitmapFormatMask fmask, +fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags, + char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, XID id, FontPtr *ppfont, char **alias, FontPtr non_cachable_font) { @@ -1725,12 +1823,12 @@ fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags, *alias = (char *) 0; for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) { - if (blockrec->type == FS_OPEN_FONT && blockrec->client == client) + if (blockrec->type == FS_OPEN_FONT && blockrec->client == client) { err = blockrec->errcode; if (err == StillWorking) return Suspended; - + bfont = (FSBlockedFontPtr) blockrec->data; if (err == Successful) *ppfont = bfont->pfont; @@ -1809,6 +1907,7 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec) FontInfoPtr pfi = &pfont->info; fsQueryXBitmaps16Reply *rep; char *buf; + long bufleft; /* length of reply left to use */ fsOffset32 *ppbits; fsOffset32 local_off; char *off_adr; @@ -1825,22 +1924,48 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec) unsigned long minchar, maxchar; rep = (fsQueryXBitmaps16Reply *) fs_get_reply (conn, &ret); - if (!rep || rep->type == FS_Error) + if (!rep || rep->type == FS_Error || + (rep->length < LENGTHOF(fsQueryXBitmaps16Reply))) { if (ret == FSIO_BLOCK) return StillWorking; if (rep) _fs_done_read (conn, rep->length << 2); err = AllocError; + _fs_reply_failed (rep, fsQueryXBitmaps16Reply, "<"); goto bail; } buf = (char *) rep; buf += SIZEOF (fsQueryXBitmaps16Reply); + bufleft = rep->length << 2; + bufleft -= SIZEOF (fsQueryXBitmaps16Reply); + + if ((bufleft / SIZEOF (fsOffset32)) < rep->num_chars) + { +#ifdef DEBUG + fprintf(stderr, + "fsQueryXBitmaps16: num_chars (%d) > bufleft (%ld) / %d\n", + rep->num_chars, bufleft, SIZEOF (fsOffset32)); +#endif + err = AllocError; + goto bail; + } ppbits = (fsOffset32 *) buf; buf += SIZEOF (fsOffset32) * (rep->num_chars); + bufleft -= SIZEOF (fsOffset32) * (rep->num_chars); + if (bufleft < rep->nbytes) + { +#ifdef DEBUG + fprintf(stderr, + "fsQueryXBitmaps16: nbytes (%d) > bufleft (%ld)\n", + rep->nbytes, bufleft); +#endif + err = AllocError; + goto bail; + } pbitmaps = (pointer ) buf; if (blockrec->type == FS_LOAD_GLYPHS) @@ -1871,21 +1996,21 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec) } off_adr = (char *)ppbits; - + allbits = fs_alloc_glyphs (pfont, rep->nbytes); - + if (!allbits) { err = AllocError; goto bail; } - + #ifdef DEBUG origallbits = allbits; fprintf (stderr, "Reading %d glyphs in %d bytes for %s\n", (int) rep->num_chars, (int) rep->nbytes, fsd->name); #endif - + for (i = 0; i < rep->num_chars; i++) { memcpy(&local_off, off_adr, SIZEOF(fsOffset32)); /* align it */ @@ -1898,7 +2023,9 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec) */ if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics)) { - if (local_off.length) + if (local_off.length && + (local_off.position < rep->nbytes) && + (local_off.length <= (rep->nbytes - local_off.position))) { bits = allbits; allbits += local_off.length; @@ -1945,7 +2072,7 @@ bail: } static int -fs_send_load_glyphs(pointer client, FontPtr pfont, +fs_send_load_glyphs(pointer client, FontPtr pfont, int nranges, fsRange *ranges) { FontPathElementPtr fpe = pfont->fpe; @@ -1956,7 +2083,7 @@ fs_send_load_glyphs(pointer client, FontPtr pfont, if (conn->blockState & FS_GIVE_UP) return BadCharRange; - + /* make a new block record, and add it to the end of the list */ blockrec = fs_new_block_rec(fpe, client, FS_LOAD_GLYPHS); if (!blockrec) @@ -1973,7 +2100,7 @@ fs_send_load_glyphs(pointer client, FontPtr pfont, _fs_pending_reply (conn); return Suspended; } - + /* send the request */ req.reqType = FS_QueryXBitmaps16; req.fid = ((FSFontDataPtr) pfont->fpePrivate)->fontid; @@ -1989,7 +2116,7 @@ fs_send_load_glyphs(pointer client, FontPtr pfont, _fs_write(conn, (char *) &req, SIZEOF(fsQueryXBitmaps16Req)); blockrec->sequenceNumber = conn->current_seq; - + /* Send ranges to the server... pack into a char array by hand to avoid structure-packing portability problems and to handle swapping for version1 protocol */ @@ -2039,7 +2166,7 @@ extern pointer serverClient; /* This could be any number that client values. */ static int -_fs_load_glyphs(pointer client, FontPtr pfont, Bool range_flag, +_fs_load_glyphs(pointer client, FontPtr pfont, Bool range_flag, unsigned int nchars, int item_size, unsigned char *data) { FSFpePtr conn = (FSFpePtr) pfont->fpe->private; @@ -2095,7 +2222,7 @@ _fs_load_glyphs(pointer client, FontPtr pfont, Bool range_flag, err = blockrec->errcode; if (err == StillWorking) return Suspended; - + _fs_signal_clients_depending(&bfont->clients_depending); _fs_remove_block_rec(conn, blockrec); if (err != Successful) @@ -2228,38 +2355,55 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec) FSBlockedListPtr blist = (FSBlockedListPtr) blockrec->data; fsListFontsReply *rep; char *data; + long dataleft; /* length of reply left to use */ int length, i, ret; int err; rep = (fsListFontsReply *) fs_get_reply (conn, &ret); - if (!rep || rep->type == FS_Error) + if (!rep || rep->type == FS_Error || + (rep->length < LENGTHOF(fsListFontsReply))) { if (ret == FSIO_BLOCK) return StillWorking; if (rep) _fs_done_read (conn, rep->length << 2); + _fs_reply_failed (rep, fsListFontsReply, "<"); return AllocError; } data = (char *) rep + SIZEOF (fsListFontsReply); + dataleft = (rep->length << 2) - SIZEOF (fsListFontsReply); err = Successful; /* copy data into FontPathRecord */ - for (i = 0; i < rep->nFonts; i++) + for (i = 0; i < rep->nFonts; i++) { + if (dataleft < 1) + break; length = *(unsigned char *)data++; + dataleft--; /* used length byte */ + if (length > dataleft) { +#ifdef DEBUG + fprintf(stderr, + "fsListFonts: name length (%d) > dataleft (%ld)\n", + length, dataleft); +#endif + err = BadFontName; + break; + } err = AddFontNamesName(blist->names, data, length); if (err != Successful) break; data += length; + dataleft -= length; } _fs_done_read (conn, rep->length << 2); return err; } static int -fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, +fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, int patlen, int maxnames, FontNamesPtr newnames) { FSFpePtr conn = (FSFpePtr) fpe->private; @@ -2269,7 +2413,7 @@ fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, if (conn->blockState & FS_GIVE_UP) return BadFontName; - + /* make a new block record, and add it to the end of the list */ blockrec = fs_new_block_rec(fpe, client, FS_LIST_FONTS); if (!blockrec) @@ -2282,7 +2426,7 @@ fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, _fs_pending_reply (conn); return Suspended; } - + _fs_client_access (conn, client, FALSE); _fs_client_resolution(conn); @@ -2297,7 +2441,7 @@ fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, _fs_write_pad(conn, (char *) pattern, patlen); blockrec->sequenceNumber = conn->current_seq; - + #ifdef NCD if (configData.ExtendedFontDiags) { char buf[256]; @@ -2314,7 +2458,7 @@ fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, } static int -fs_list_fonts(pointer client, FontPathElementPtr fpe, +fs_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, int patlen, int maxnames, FontNamesPtr newnames) { FSFpePtr conn = (FSFpePtr) fpe->private; @@ -2324,7 +2468,7 @@ fs_list_fonts(pointer client, FontPathElementPtr fpe, /* see if the result is already there */ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) { - if (blockrec->type == FS_LIST_FONTS && blockrec->client == client) + if (blockrec->type == FS_LIST_FONTS && blockrec->client == client) { err = blockrec->errcode; if (err == StillWorking) @@ -2347,6 +2491,7 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) FSBlockedListInfoPtr binfo = (FSBlockedListInfoPtr) blockrec->data; fsListFontsWithXInfoReply *rep; char *buf; + long bufleft; FSFpePtr conn = (FSFpePtr) fpe->private; fsPropInfo *pi; fsPropOffset *po; @@ -2358,12 +2503,15 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) _fs_free_props (&binfo->info); rep = (fsListFontsWithXInfoReply *) fs_get_reply (conn, &ret); - if (!rep || rep->type == FS_Error) + if (!rep || rep->type == FS_Error || + ((rep->nameLength != 0) && + (rep->length < LENGTHOF(fsListFontsWithXInfoReply)))) { if (ret == FSIO_BLOCK) return StillWorking; binfo->status = FS_LFWI_FINISHED; err = AllocError; + _fs_reply_failed (rep, fsListFontsWithXInfoReply, "<"); goto done; } /* @@ -2380,7 +2528,8 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) } buf = (char *) rep + SIZEOF (fsListFontsWithXInfoReply); - + bufleft = (rep->length << 2) - SIZEOF (fsListFontsWithXInfoReply); + /* * The original FS implementation didn't match * the spec, version 1 was respecified to match the FS. @@ -2388,19 +2537,71 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) */ if (conn->fsMajorVersion <= 1) { + if (rep->nameLength > bufleft) { +#ifdef DEBUG + fprintf(stderr, + "fsListFontsWithXInfo: name length (%d) > bufleft (%ld)\n", + (int) rep->nameLength, bufleft); +#endif + err = AllocError; + goto done; + } + /* binfo->name is a 256 char array, rep->nameLength is a CARD8 */ memcpy (binfo->name, buf, rep->nameLength); buf += _fs_pad_length (rep->nameLength); + bufleft -= _fs_pad_length (rep->nameLength); } pi = (fsPropInfo *) buf; + if (SIZEOF (fsPropInfo) > bufleft) { +#ifdef DEBUG + fprintf(stderr, + "fsListFontsWithXInfo: PropInfo length (%d) > bufleft (%ld)\n", + (int) SIZEOF (fsPropInfo), bufleft); +#endif + err = AllocError; + goto done; + } + bufleft -= SIZEOF (fsPropInfo); buf += SIZEOF (fsPropInfo); po = (fsPropOffset *) buf; + if (pi->num_offsets > (bufleft / SIZEOF (fsPropOffset))) { +#ifdef DEBUG + fprintf(stderr, + "fsListFontsWithXInfo: offset length (%d * %d) > bufleft (%ld)\n", + pi->num_offsets, (int) SIZEOF (fsPropOffset), bufleft); +#endif + err = AllocError; + goto done; + } + bufleft -= pi->num_offsets * SIZEOF (fsPropOffset); buf += pi->num_offsets * SIZEOF (fsPropOffset); pd = (pointer) buf; + if (pi->data_len > bufleft) { +#ifdef DEBUG + fprintf(stderr, + "fsListFontsWithXInfo: data length (%d) > bufleft (%ld)\n", + pi->data_len, bufleft); +#endif + err = AllocError; + goto done; + } + bufleft -= pi->data_len; buf += pi->data_len; if (conn->fsMajorVersion > 1) { + if (rep->nameLength > bufleft) { +#ifdef DEBUG + fprintf(stderr, + "fsListFontsWithXInfo: name length (%d) > bufleft (%ld)\n", + (int) rep->nameLength, bufleft); +#endif + err = AllocError; + goto done; + } + /* binfo->name is a 256 char array, rep->nameLength is a CARD8 */ memcpy (binfo->name, buf, rep->nameLength); buf += _fs_pad_length (rep->nameLength); + bufleft -= _fs_pad_length (rep->nameLength); } #ifdef DEBUG @@ -2417,18 +2618,18 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) binfo->remaining = rep->nReplies; binfo->status = FS_LFWI_REPLY; - + /* disable this font server until we've processed this response */ _fs_unmark_block (conn, FS_COMPLETE_REPLY); FD_CLR(conn->fs_fd, &_fs_fd_mask); -done: +done: _fs_done_read (conn, rep->length << 2); return err; } /* ARGSUSED */ static int -fs_start_list_with_info(pointer client, FontPathElementPtr fpe, +fs_start_list_with_info(pointer client, FontPathElementPtr fpe, char *pattern, int len, int maxnames, pointer *pdata) { FSFpePtr conn = (FSFpePtr) fpe->private; @@ -2443,7 +2644,7 @@ fs_start_list_with_info(pointer client, FontPathElementPtr fpe, blockrec = fs_new_block_rec(fpe, client, FS_LIST_WITH_INFO); if (!blockrec) return AllocError; - + binfo = (FSBlockedListInfoPtr) blockrec->data; bzero((char *) binfo, sizeof(FSBlockedListInfoRec)); binfo->status = FS_LFWI_WAITING; @@ -2453,7 +2654,7 @@ fs_start_list_with_info(pointer client, FontPathElementPtr fpe, _fs_pending_reply (conn); return Suspended; } - + _fs_client_access (conn, client, FALSE); _fs_client_resolution(conn); @@ -2468,7 +2669,7 @@ fs_start_list_with_info(pointer client, FontPathElementPtr fpe, (void) _fs_write_pad(conn, pattern, len); blockrec->sequenceNumber = conn->current_seq; - + #ifdef NCD if (configData.ExtendedFontDiags) { char buf[256]; @@ -2486,8 +2687,8 @@ fs_start_list_with_info(pointer client, FontPathElementPtr fpe, /* ARGSUSED */ static int -fs_next_list_with_info(pointer client, FontPathElementPtr fpe, - char **namep, int *namelenp, +fs_next_list_with_info(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, FontInfoPtr *pFontInfo, int *numFonts, pointer private) { @@ -2498,7 +2699,7 @@ fs_next_list_with_info(pointer client, FontPathElementPtr fpe, /* see if the result is already there */ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) - if (blockrec->type == FS_LIST_WITH_INFO && blockrec->client == client) + if (blockrec->type == FS_LIST_WITH_INFO && blockrec->client == client) break; if (!blockrec) @@ -2513,7 +2714,7 @@ fs_next_list_with_info(pointer client, FontPathElementPtr fpe, } binfo = (FSBlockedListInfoPtr) blockrec->data; - + if (binfo->status == FS_LFWI_WAITING) return Suspended; @@ -2521,12 +2722,12 @@ fs_next_list_with_info(pointer client, FontPathElementPtr fpe, *namelenp = binfo->namelen; *pFontInfo = &binfo->info; *numFonts = binfo->remaining; - + /* Restart reply processing from this font server */ FD_SET(conn->fs_fd, &_fs_fd_mask); if (fs_reply_ready (conn)) _fs_mark_block (conn, FS_COMPLETE_REPLY); - + err = blockrec->errcode; switch (binfo->status) { case FS_LFWI_FINISHED: @@ -2539,7 +2740,7 @@ fs_next_list_with_info(pointer client, FontPathElementPtr fpe, _fs_mark_block (conn, FS_PENDING_REPLY); break; } - + return err; } @@ -2574,12 +2775,12 @@ fs_client_died(pointer client, FontPathElementPtr fpe) for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) if (blockrec->client == client) break; - + if (!blockrec) return; - + /* replace the client pointers in this block rec with the chained one */ - if ((depending = blockrec->depending)) + if ((depending = blockrec->depending)) { blockrec->client = depending->client; blockrec->depending = depending->depending; @@ -2681,7 +2882,7 @@ static int _fs_check_connect (FSFpePtr conn) { int ret; - + ret = _fs_poll_connect (conn->trans_conn, 0); switch (ret) { case FSIO_READY: @@ -2715,7 +2916,7 @@ _fs_get_conn_setup (FSFpePtr conn, int *error, int *setup_len) *error = ret; return 0; } - + setup = (fsConnSetup *) data; if (setup->major_version > FS_PROTOCOL) { @@ -2786,10 +2987,10 @@ _fs_recv_conn_setup (FSFpePtr conn) int ret = FSIO_ERROR; fsConnSetup *setup; FSFpeAltPtr alts; - int i, alt_len; + unsigned int i, alt_len; int setup_len; char *alt_save, *alt_names; - + setup = _fs_get_conn_setup (conn, &ret, &setup_len); if (!setup) return ret; @@ -2813,8 +3014,9 @@ _fs_recv_conn_setup (FSFpePtr conn) } if (setup->num_alternates) { + size_t alt_name_len = setup->alternate_len << 2; alts = malloc (setup->num_alternates * sizeof (FSFpeAltRec) + - (setup->alternate_len << 2)); + alt_name_len); if (alts) { alt_names = (char *) (setup + 1); @@ -2823,10 +3025,25 @@ _fs_recv_conn_setup (FSFpePtr conn) { alts[i].subset = alt_names[0]; alt_len = alt_names[1]; + if (alt_len >= alt_name_len) { + /* + * Length is longer than setup->alternate_len + * told us to allocate room for, assume entire + * alternate list is corrupted. + */ +#ifdef DEBUG + fprintf (stderr, + "invalid alt list (length %lx >= %lx)\n", + (long) alt_len, (long) alt_name_len); +#endif + free(alts); + return FSIO_ERROR; + } alts[i].name = alt_save; memcpy (alt_save, alt_names + 2, alt_len); alt_save[alt_len] = '\0'; alt_save += alt_len + 1; + alt_name_len -= alt_len + 1; alt_names += _fs_pad_length (alt_len + 2); } conn->numAlts = setup->num_alternates; @@ -2845,7 +3062,7 @@ _fs_open_server (FSFpePtr conn) { int ret; char *servername; - + if (conn->alternate == 0) servername = conn->servername; else @@ -2877,13 +3094,13 @@ _fs_send_init_packets (FSFpePtr conn) char *cat; char len; char *end; - int num_res; + int num_res; FontResolutionPtr res; #define CATALOGUE_SEP '+' res = GetClientResolutions(&num_res); - if (num_res) + if (num_res) { srreq.reqType = FS_SetResolution; srreq.num_resolutions = num_res; @@ -2902,14 +3119,14 @@ _fs_send_init_packets (FSFpePtr conn) catalogues = _fs_catalog_name (conn->alts[conn->alternate-1].name); if (!catalogues) catalogues = _fs_catalog_name (conn->servername); - + if (!catalogues) { conn->has_catalogues = FALSE; return FSIO_READY; } conn->has_catalogues = TRUE; - + /* turn cats into counted list */ catalogues++; @@ -2929,11 +3146,11 @@ _fs_send_init_packets (FSFpePtr conn) screq.reqType = FS_SetCatalogues; screq.num_catalogues = num_cats; screq.length = (SIZEOF(fsSetCataloguesReq) + clen + 3) >> 2; - + _fs_add_req_log(conn, FS_SetCatalogues); if (_fs_write(conn, (char *) &screq, SIZEOF(fsSetCataloguesReq)) != FSIO_READY) return FSIO_ERROR; - + while (*cat) { num_cats++; @@ -2947,10 +3164,10 @@ _fs_send_init_packets (FSFpePtr conn) return FSIO_ERROR; cat = end; } - + if (_fs_write (conn, "....", _fs_pad_length (clen) - clen) != FSIO_READY) return FSIO_ERROR; - + return FSIO_READY; } @@ -2958,12 +3175,13 @@ static int _fs_send_cat_sync (FSFpePtr conn) { fsListCataloguesReq lcreq; - + /* * now sync up with the font server, to see if an error was generated * by a bogus catalogue */ lcreq.reqType = FS_ListCatalogues; + lcreq.data = 0; lcreq.length = (SIZEOF(fsListCataloguesReq)) >> 2; lcreq.maxNames = 0; lcreq.nbytes = 0; @@ -2986,7 +3204,7 @@ _fs_recv_cat_sync (FSFpePtr conn) reply = fs_get_reply (conn, &err); if (!reply) return err; - + ret = FSIO_READY; if (reply->type == FS_Error) { @@ -3020,7 +3238,7 @@ static int _fs_do_setup_connection (FSFpePtr conn) { int ret; - + do { #ifdef DEBUG @@ -3113,7 +3331,7 @@ static void _fs_check_reconnect (FSFpePtr conn) { int ret; - + ret = _fs_do_setup_connection (conn); switch (ret) { case FSIO_READY: diff --git a/libXfont/src/fc/fsio.h b/libXfont/src/fc/fsio.h index 2bb8e0b73..fa1e7d8f9 100644 --- a/libXfont/src/fc/fsio.h +++ b/libXfont/src/fc/fsio.h @@ -26,8 +26,9 @@ #ifndef _FSIO_H_ #define _FSIO_H_ -#undef DEBUG +#ifdef DEBUG #define REQUEST_LOG_SIZE 100 +#endif typedef struct _fs_fpe_alternate { char *name; diff --git a/libXfont/src/fontfile/bufio.c b/libXfont/src/fontfile/bufio.c index 34b7f3665..d8d4f2964 100644 --- a/libXfont/src/fontfile/bufio.c +++ b/libXfont/src/fontfile/bufio.c @@ -162,8 +162,10 @@ BufFileOpenWrite (int fd) setmode(fd,O_BINARY); #endif f = BufFileCreate ((char *)(long) fd, 0, BufFileRawFlush, 0, BufFileFlush); - f->bufp = f->buffer; - f->left = BUFFILESIZE; + if (f != NULL) { + f->bufp = f->buffer; + f->left = BUFFILESIZE; + } return f; } diff --git a/libXfont/src/fontfile/catalogue.c b/libXfont/src/fontfile/catalogue.c index 09ca2ae8a..623093011 100644 --- a/libXfont/src/fontfile/catalogue.c +++ b/libXfont/src/fontfile/catalogue.c @@ -287,7 +287,6 @@ CatalogueOpenFont (pointer client, FontPathElementPtr fpe, Mask flags, { CataloguePtr cat = fpe->private; FontPathElementPtr subfpe; - FontDirectoryPtr dir; int i, status; CatalogueRescan (fpe, FALSE); @@ -295,7 +294,6 @@ CatalogueOpenFont (pointer client, FontPathElementPtr fpe, Mask flags, for (i = 0; i < cat->fpeCount; i++) { subfpe = cat->fpeList[i]; - dir = subfpe->private; status = FontFileOpenFont(client, subfpe, flags, name, namelen, format, fmask, id, pFont, aliasName, non_cachable_font); @@ -321,7 +319,6 @@ CatalogueListFonts (pointer client, FontPathElementPtr fpe, char *pat, { CataloguePtr cat = fpe->private; FontPathElementPtr subfpe; - FontDirectoryPtr dir; int i; CatalogueRescan (fpe, FALSE); @@ -329,18 +326,12 @@ CatalogueListFonts (pointer client, FontPathElementPtr fpe, char *pat, for (i = 0; i < cat->fpeCount; i++) { subfpe = cat->fpeList[i]; - dir = subfpe->private; FontFileListFonts(client, subfpe, pat, len, max, names); } return Successful; } -int -FontFileStartListFonts(pointer client, FontPathElementPtr fpe, - char *pat, int len, int max, - pointer *privatep, int mark_aliases); - typedef struct _LFWIData { pointer *privates; int current; diff --git a/libXfont/src/fontfile/dirfile.c b/libXfont/src/fontfile/dirfile.c index c8aff6f4f..639310c31 100644 --- a/libXfont/src/fontfile/dirfile.c +++ b/libXfont/src/fontfile/dirfile.c @@ -42,6 +42,7 @@ in this Software without prior written authorization from The Open Group. #include <sys/types.h> #include <sys/stat.h> #include <errno.h> +#include <limits.h> static Bool AddFileNameAliases ( FontDirectoryPtr dir ); static int ReadFontAlias ( char *directory, Bool isFile, @@ -90,7 +91,7 @@ FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir) strcat(dir_file, FontDirFile); file = fopen(dir_file, "rt"); if (file) { -#ifndef WIN32 +#ifndef WIN32 if (fstat (fileno(file), &statb) == -1) #else if (stat (dir_file, &statb) == -1) @@ -135,7 +136,7 @@ FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir) FontFileAddFontFile (dir, font_name, file_name); } fclose(file); - + } else if (errno != ENOENT) { return BadFontPath; } @@ -188,7 +189,7 @@ FontFileDirectoryChanged(FontDirectoryPtr dir) return TRUE; return FALSE; } - + /* * Make each of the file names an automatic alias for each of the files. */ @@ -212,7 +213,7 @@ AddFileNameAliases(FontDirectoryPtr dir) renderer = FontFileMatchRenderer (fileName); if (!renderer) continue; - + len = strlen (fileName) - renderer->fileSuffixLen; if (len >= sizeof(copy)) continue; @@ -374,6 +375,9 @@ lexAlias(FILE *file, char **lexToken) int nsize; char *nbuf; + if (tokenSize >= (INT_MAX >> 2)) + /* Stop before we overflow */ + return EALLOC; nsize = tokenSize ? (tokenSize << 1) : 64; nbuf = realloc(tokenBuf, nsize); if (!nbuf) diff --git a/libXfont/src/fontfile/fontdir.c b/libXfont/src/fontfile/fontdir.c index ef7ffa561..7271603ec 100644 --- a/libXfont/src/fontfile/fontdir.c +++ b/libXfont/src/fontfile/fontdir.c @@ -177,6 +177,11 @@ FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype) if (table->sorted) return (FontEntryPtr) 0; /* "cannot" happen */ if (table->used == table->size) { + if (table->size >= ((INT32_MAX / sizeof(FontEntryRec)) - 100)) + /* If we've read so many entries we're going to ask for 2gb + or more of memory, something is so wrong with this font + directory that we should just give up before we overflow. */ + return NULL; newsize = table->size + 100; entry = realloc(table->entries, newsize * sizeof(FontEntryRec)); if (!entry) |