From ea5d11fbb731fd3278c5e97a08a21e6e0245b04e Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 15 2018 15:20:56 +0000 Subject: import ghostscript-9.07-29.el7_5.2 --- diff --git a/.ghostscript.metadata b/.ghostscript.metadata new file mode 100644 index 0000000..f3d9248 --- /dev/null +++ b/.ghostscript.metadata @@ -0,0 +1 @@ +93f816b55c716987f45cf68c85b9923ceafe7bbb SOURCES/ghostscript-9.07-cleaned.tar.bz2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f45a5a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/ghostscript-9.07-cleaned.tar.bz2 diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/CIDFnmap b/SOURCES/CIDFnmap new file mode 100644 index 0000000..2f3d7b7 --- /dev/null +++ b/SOURCES/CIDFnmap @@ -0,0 +1,9 @@ +%! +% following lines are for CJK fonts. +(CIDFnmap.ja) .runlibfileifexists +(CIDFnmap.ko) .runlibfileifexists +(CIDFnmap.zh_CN) .runlibfileifexists +(CIDFnmap.zh_TW) .runlibfileifexists +% must be at the bottom of line to allow people overriding everything. +(CIDFnmap.local) .runlibfileifexists + diff --git a/SOURCES/cidfmap b/SOURCES/cidfmap new file mode 100644 index 0000000..18c1786 --- /dev/null +++ b/SOURCES/cidfmap @@ -0,0 +1,10 @@ +%! +% Don't change following line. We should ensure that the original one is surely loaded. +(cidfmap.GS) .runlibfile +% following lines are for CJK fonts. +(cidfmap.ja) .runlibfileifexists +(cidfmap.ko) .runlibfileifexists +(cidfmap.zh_CN) .runlibfileifexists +(cidfmap.zh_TW) .runlibfileifexists +% must be at the bottom of line to allow people overriding everything. +(cidfmap.local) .runlibfileifexists diff --git a/SOURCES/generate-tarball.sh b/SOURCES/generate-tarball.sh new file mode 100755 index 0000000..61f3f62 --- /dev/null +++ b/SOURCES/generate-tarball.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +VERSION=$1 + +rm -rf ghostscript-$VERSION +tar jxvf ghostscript-$VERSION.tar.bz2 +rm -r ghostscript-$VERSION/jpegxr +tar jcvf ghostscript-$VERSION-cleaned.tar.bz2 ghostscript-$VERSION diff --git a/SOURCES/ghostscript-Fontmap.local.patch b/SOURCES/ghostscript-Fontmap.local.patch new file mode 100644 index 0000000..3d1fee2 --- /dev/null +++ b/SOURCES/ghostscript-Fontmap.local.patch @@ -0,0 +1,9 @@ +diff -up ghostscript-8.71/Resource/Init/Fontmap.Fontmap.local ghostscript-8.71/Resource/Init/Fontmap +--- ghostscript-8.71/Resource/Init/Fontmap.Fontmap.local 2008-08-08 05:22:38.000000000 +0100 ++++ ghostscript-8.71/Resource/Init/Fontmap 2010-09-03 11:53:47.273865979 +0100 +@@ -2,3 +2,5 @@ + % See Fontmap.GS for the syntax of real Fontmap files. + %% Replace 1 (Fontmap.GS) + (Fontmap.GS) .runlibfile ++% must be at the bottom of line to allow people overriding everything. ++(Fontmap.local) .runlibfileifexists diff --git a/SOURCES/ghostscript-check-icc-profile-errors.patch b/SOURCES/ghostscript-check-icc-profile-errors.patch new file mode 100644 index 0000000..e4f54ee --- /dev/null +++ b/SOURCES/ghostscript-check-icc-profile-errors.patch @@ -0,0 +1,103 @@ +From 8d65c0854c049e4c0c8e08006b595ad40a59e696 Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Thu, 28 Mar 2013 21:12:18 +0000 +Subject: [PATCH] Another memory squeeze fix. + +Avoid SEGV in gsicc_alloc_link_entry and callers. +--- + base/gsicc_cache.c | 17 +++++++++++------ + base/gsicc_manage.c | 6 ++++-- + base/gsicc_nocm.c | 3 +++ + base/gsicc_replacecm.c | 3 +++ + 4 files changed, 21 insertions(+), 8 deletions(-) + +diff --git a/base/gsicc_cache.c b/base/gsicc_cache.c +index 616db4c..65b2dd0 100644 +--- a/base/gsicc_cache.c ++++ b/base/gsicc_cache.c +@@ -659,12 +659,14 @@ gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, + /* insert an empty link that we will reserve so we */ + /* can unlock while building the link contents */ + (*ret_link) = gsicc_alloc_link(cache_mem->stable_memory, hash); +- (*ret_link)->icc_link_cache = icc_link_cache; +- (*ret_link)->next = icc_link_cache->head; +- icc_link_cache->head = *ret_link; +- icc_link_cache->num_links++; +- /* now that we own this link we can release +- the lock since it is not valid */ ++ if (*ret_link) { ++ (*ret_link)->icc_link_cache = icc_link_cache; ++ (*ret_link)->next = icc_link_cache->head; ++ icc_link_cache->head = *ret_link; ++ icc_link_cache->num_links++; ++ /* now that we own this link we can release ++ the lock since it is not valid */ ++ } + gx_monitor_leave(icc_link_cache->lock); + return false; + } +@@ -794,6 +796,9 @@ gsicc_get_link_profile(const gs_imager_state *pis, gx_device *dev, + if (gsicc_alloc_link_entry(icc_link_cache, &link, hash, include_softproof, + include_devicelink)) + return link; ++ if (link == NULL) ++ return NULL; ++ + /* Now compute the link contents */ + cms_input_profile = gs_input_profile->profile_handle; + if (cms_input_profile == NULL) { +diff --git a/base/gsicc_manage.c b/base/gsicc_manage.c +index e0e7d93..210be59 100644 +--- a/base/gsicc_manage.c ++++ b/base/gsicc_manage.c +@@ -1521,8 +1521,8 @@ gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, + icc_profile = + gsicc_profile_new(str, mem, file_name, strlen(file_name)); + code = sfclose(str); +- } +- if (str != NULL && icc_profile != NULL) { ++ if (icc_profile == NULL) ++ return_error(gs_error_VMerror); + if (pro_enum < gsPROOFPROFILE) { + if_debug1m(gs_debug_flag_icc, mem, + "[icc] Setting device profile %d\n", pro_enum); +@@ -1542,6 +1542,8 @@ gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, + gsicc_get_profile_handle_buffer(icc_profile->buffer, + icc_profile->buffer_size, + mem); ++ if (icc_profile->profile_handle == NULL) ++ return_error(gs_error_unknownerror); + /* Compute the hash code of the profile. Everything in the + ICC manager will have it's hash code precomputed */ + gsicc_get_icc_buff_hash(icc_profile->buffer, +diff --git a/base/gsicc_nocm.c b/base/gsicc_nocm.c +index 8b2a353..bcc3138 100644 +--- a/base/gsicc_nocm.c ++++ b/base/gsicc_nocm.c +@@ -372,6 +372,9 @@ gsicc_nocm_get_link(const gs_imager_state *pis, gx_device *dev, + if (gsicc_alloc_link_entry(pis->icc_link_cache, &result, hash, false, false)) + return result; + ++ if (result == NULL) ++ return NULL; ++ + /* Now compute the link contents */ + result->procs.map_buffer = gsicc_nocm_transform_color_buffer; + result->procs.map_color = gsicc_nocm_transform_color; +diff --git a/base/gsicc_replacecm.c b/base/gsicc_replacecm.c +index 1a7c9e6..d1ab5ea 100644 +--- a/base/gsicc_replacecm.c ++++ b/base/gsicc_replacecm.c +@@ -330,6 +330,9 @@ gsicc_rcm_get_link(const gs_imager_state *pis, gx_device *dev, + if (gsicc_alloc_link_entry(pis->icc_link_cache, &result, hash, false, false)) + return result; + ++ if (result == NULL) ++ return result; ++ + /* Now compute the link contents */ + result->procs.map_buffer = gsicc_rcm_transform_color_buffer; + result->procs.map_color = gsicc_rcm_transform_color; +-- +2.5.5 + diff --git a/SOURCES/ghostscript-cope-with-negative-run-length.patch b/SOURCES/ghostscript-cope-with-negative-run-length.patch new file mode 100644 index 0000000..209a7c2 --- /dev/null +++ b/SOURCES/ghostscript-cope-with-negative-run-length.patch @@ -0,0 +1,70 @@ +From ab4d21b69bf0717ac93072d24b076681bdb9b3a4 Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Wed, 19 Jun 2013 16:25:17 +0100 +Subject: [PATCH] Bug 693934: CCITT Fax decode - cope with negative run length + +In various places in the fax decode code we coped with the run length being +negative - in just a few we didn't. + +We'll now cope gracefully with negative run lengths in places. + +No cluster differences. +--- + base/scfd.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/base/scfd.c b/base/scfd.c +index 970c925..5f7f798 100644 +--- a/base/scfd.c ++++ b/base/scfd.c +@@ -611,6 +611,7 @@ v0: skip_bits(1); + rlen, "[w2]", d2l, out0); + /* rlen may be run2_pass, run_uncompressed, or */ + /* 0..countof(cf2_run_vertical)-1. */ ++rlen_lt_zero: + if (rlen < 0) + switch (rlen) { + case run2_pass: +@@ -726,6 +727,9 @@ v0: skip_bits(1); + status = ERRC; + goto out; + } ++ ++ if (rlen < 0) goto rlen_lt_zero; ++ + skip_data(rlen, hww); + /* Handle the second half of a white-black horizontal code. */ + hwb:get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits, +@@ -734,6 +738,9 @@ v0: skip_bits(1); + status = ERRC; + goto out; + } ++ ++ if (rlen < 0) goto rlen_lt_zero; ++ + invert_data(rlen, black_byte, goto hwb, ihwb); + goto top; + outww:ss->run_color = -2; +@@ -747,6 +754,9 @@ v0: skip_bits(1); + status = ERRC; + goto out; + } ++ ++ if (rlen < 0) goto rlen_lt_zero; ++ + invert_data(rlen, black_byte, goto hbb, ihbb); + /* Handle the second half of a black-white horizontal code. */ + hbw:get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits, +@@ -755,6 +765,9 @@ v0: skip_bits(1); + status = ERRC; + goto out; + } ++ ++ if (rlen < 0) goto rlen_lt_zero; ++ + skip_data(rlen, hbw); + goto top; + outbb:ss->run_color = 2; +-- +2.9.4 + diff --git a/SOURCES/ghostscript-crash.patch b/SOURCES/ghostscript-crash.patch new file mode 100644 index 0000000..4cd24e8 --- /dev/null +++ b/SOURCES/ghostscript-crash.patch @@ -0,0 +1,21 @@ +diff -up ghostscript-9.10/psi/ialloc.c.crash ghostscript-9.10/psi/ialloc.c +--- ghostscript-9.10/psi/ialloc.c.crash 2013-08-30 11:37:28.000000000 +0100 ++++ ghostscript-9.10/psi/ialloc.c 2014-06-04 10:47:58.294526685 +0100 +@@ -160,6 +160,7 @@ gs_alloc_ref_array(gs_ref_memory_t * mem + uint num_refs, client_name_t cname) + { + ref *obj; ++ int i; + + /* If we're allocating a run of refs already, */ + /* and we aren't about to overflow the maximum run length, use it. */ +@@ -224,6 +225,9 @@ gs_alloc_ref_array(gs_ref_memory_t * mem + cp->where = (ref_packed *)obj; + } + } ++ for (i = 0; i < num_refs; i++) { ++ make_null(&(obj[i])); ++ } + make_array(parr, attrs | mem->space, num_refs, obj); + return 0; + } diff --git a/SOURCES/ghostscript-cups-colord.patch b/SOURCES/ghostscript-cups-colord.patch new file mode 100644 index 0000000..9d3f4e0 --- /dev/null +++ b/SOURCES/ghostscript-cups-colord.patch @@ -0,0 +1,29 @@ +diff -up ghostscript-9.07/cups/gstoraster.c.cups-colord ghostscript-9.07/cups/gstoraster.c +--- ghostscript-9.07/cups/gstoraster.c.cups-colord 2013-07-01 17:06:10.977743028 +0100 ++++ ghostscript-9.07/cups/gstoraster.c 2013-07-01 17:18:36.597852666 +0100 +@@ -596,11 +596,21 @@ main (int argc, char **argv, char *envp[ + + qualifier = colord_get_qualifier_for_ppd (ppd); + if (qualifier != NULL) { ++ const char *env_printer = getenv("PRINTER"); ++ char *device_id; + +- fprintf(stderr, "DEBUG: PPD uses qualifier '%s.%s.%s'\n", +- qualifier[0], qualifier[1], qualifier[2]); +- icc_profile = colord_get_profile_for_device_id (getenv("PRINTER"), +- (const char**) qualifier); ++ if (env_printer) { ++ device_id = malloc (5 + strlen (env_printer) + 1); ++ if (device_id) { ++ strcpy (device_id, "cups-"); ++ strcpy (device_id + 5, env_printer); ++ fprintf(stderr, "DEBUG: PPD uses qualifier '%s.%s.%s'\n", ++ qualifier[0], qualifier[1], qualifier[2]); ++ icc_profile = colord_get_profile_for_device_id (device_id, ++ (const char**) qualifier); ++ free (device_id); ++ } ++ } + + /* fall back to the PPD */ + if (icc_profile == NULL) diff --git a/SOURCES/ghostscript-cups-filters.patch b/SOURCES/ghostscript-cups-filters.patch new file mode 100644 index 0000000..ce82edd --- /dev/null +++ b/SOURCES/ghostscript-cups-filters.patch @@ -0,0 +1,15 @@ +diff -up ghostscript-9.05/cups/cups.mak.cups-filters ghostscript-9.05/cups/cups.mak +--- ghostscript-9.05/cups/cups.mak.cups-filters 2012-02-08 08:48:50.000000000 +0000 ++++ ghostscript-9.05/cups/cups.mak 2012-02-09 11:42:22.211731587 +0000 +@@ -56,9 +56,9 @@ install-cups: cups + $(INSTALL_PROGRAM) $(GSTORASTER_XE) $(DESTDIR)$(CUPSSERVERBIN)/filter; \ + fi + $(INSTALL_PROGRAM) cups/gstopxl $(DESTDIR)$(CUPSSERVERBIN)/filter +- -mkdir -p $(DESTDIR)$(CUPSSERVERROOT) ++ -mkdir -p $(DESTDIR)$(CUPSDATA)/mime + if [ "$(CUPSPDFTORASTER)" = "1" ]; then \ +- $(INSTALL_DATA) cups/gstoraster.convs $(DESTDIR)$(CUPSSERVERROOT); \ ++ $(INSTALL_DATA) cups/gstoraster.convs $(DESTDIR)$(CUPSDATA)/mime; \ + fi + -mkdir -p $(DESTDIR)$(CUPSDATA)/model + $(INSTALL_DATA) cups/pxlcolor.ppd $(DESTDIR)$(CUPSDATA)/model diff --git a/SOURCES/ghostscript-cups-icc-profile.patch b/SOURCES/ghostscript-cups-icc-profile.patch new file mode 100644 index 0000000..5db5e38 --- /dev/null +++ b/SOURCES/ghostscript-cups-icc-profile.patch @@ -0,0 +1,25 @@ +From 9e45d4a26eea12be326c5f515b44c7474a33f6c5 Mon Sep 17 00:00:00 2001 +From: Tim Waugh +Date: Tue, 12 Jul 2016 17:29:49 +0200 +Subject: [PATCH] Do not set device output ICC profile if the string is empty + +--- + cups/gstoraster.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cups/gstoraster.c b/cups/gstoraster.c +index 3ddc21f..8fe77a2 100644 +--- a/cups/gstoraster.c ++++ b/cups/gstoraster.c +@@ -665,7 +665,7 @@ main (int argc, char **argv, char *envp[]) + cupsArrayAdd(gs_args, strdup(tmpstr)); + + /* set the device output ICC profile */ +- if(icc_profile != NULL) { ++ if(icc_profile != NULL && icc_profile[0] != '\0') { + snprintf(tmpstr, sizeof(tmpstr), "-sOutputICCProfile=%s", icc_profile); + cupsArrayAdd(gs_args, strdup(tmpstr)); + } +-- +2.5.5 + diff --git a/SOURCES/ghostscript-cve-2013-5653.patch b/SOURCES/ghostscript-cve-2013-5653.patch new file mode 100644 index 0000000..affca36 --- /dev/null +++ b/SOURCES/ghostscript-cve-2013-5653.patch @@ -0,0 +1,72 @@ +From 950c602dc2dbbcbf5a856e85dba99bc8ac8420b9 Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Sat, 5 Mar 2016 14:56:03 -0800 +Subject: [PATCH 1/1] Bug 694724: Have filenameforall and getenv honor SAFER + +--- + Resource/Init/gs_init.ps | 1 + + psi/zfile.c | 36 ++++++++++++++++++++---------------- + 2 files changed, 21 insertions(+), 16 deletions(-) + +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index c3f567d..abb9489 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -2019,6 +2019,7 @@ readonly def + /LockFilePermissions //true + >> setuserparams + } ++ systemdict /getenv {pop //false} put + if + % setpagedevice has the side effect of clearing the page, but + % we will just document that. Using setpagedevice keeps the device +diff --git a/psi/zfile.c b/psi/zfile.c +index 4011789..dd05919 100644 +--- a/psi/zfile.c ++++ b/psi/zfile.c +@@ -371,22 +371,26 @@ file_continue(i_ctx_t *i_ctx_p) + + if (len < devlen) + return_error(e_rangecheck); /* not even room for device len */ +- memcpy((char *)pscratch->value.bytes, iodev->dname, devlen); +- code = iodev->procs.enumerate_next(pfen, (char *)pscratch->value.bytes + devlen, +- len - devlen); +- if (code == ~(uint) 0) { /* all done */ +- esp -= 5; /* pop proc, pfen, devlen, iodev , mark */ +- return o_pop_estack; +- } else if (code > len) /* overran string */ +- return_error(e_rangecheck); +- else { +- push(1); +- ref_assign(op, pscratch); +- r_set_size(op, code + devlen); +- push_op_estack(file_continue); /* come again */ +- *++esp = pscratch[2]; /* proc */ +- return o_push_estack; +- } ++ ++ do { ++ memcpy((char *)pscratch->value.bytes, iodev->dname, devlen); ++ code = iodev->procs.enumerate_next(pfen, (char *)pscratch->value.bytes + devlen, ++ len - devlen); ++ if (code == ~(uint) 0) { /* all done */ ++ esp -= 5; /* pop proc, pfen, devlen, iodev , mark */ ++ return o_pop_estack; ++ } else if (code > len) /* overran string */ ++ return_error(gs_error_rangecheck); ++ else if (iodev != iodev_default(imemory) ++ || (check_file_permissions_reduced(i_ctx_p, (char *)pscratch->value.bytes, code + devlen, "PermitFileReading")) == 0) { ++ push(1); ++ ref_assign(op, pscratch); ++ r_set_size(op, code + devlen); ++ push_op_estack(file_continue); /* come again */ ++ *++esp = pscratch[2]; /* proc */ ++ return o_push_estack; ++ } ++ } while(1); + } + /* Cleanup procedure for enumerating files */ + static int +-- +2.7.4 + diff --git a/SOURCES/ghostscript-cve-2016-7977.patch b/SOURCES/ghostscript-cve-2016-7977.patch new file mode 100644 index 0000000..43a0cae --- /dev/null +++ b/SOURCES/ghostscript-cve-2016-7977.patch @@ -0,0 +1,28 @@ +From bd7fcaf389a56179281324d8c7b90e90bb3ee4ac Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Mon, 3 Oct 2016 01:46:28 +0100 +Subject: [PATCH] Bug 697169: Be rigorous with SAFER permissions + +Once we've opened our input file from the command line, enforce the SAFER +rules. +--- + psi/zfile.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/psi/zfile.c b/psi/zfile.c +index dd05919..2f13259 100644 +--- a/psi/zfile.c ++++ b/psi/zfile.c +@@ -1002,6 +1002,9 @@ lib_file_open(gs_file_path_ptr lib_path, const gs_memory_t *mem, i_ctx_t *i_ctx + gs_main_instance *minst = get_minst_from_memory(mem); + int code; + ++ if (i_ctx_p && starting_arg_file) ++ i_ctx_p->starting_arg_file = false; ++ + /* when starting arg files (@ files) iodev_default is not yet set */ + if (iodev == 0) + iodev = (gx_io_device *)gx_io_device_table[0]; +-- +2.7.4 + diff --git a/SOURCES/ghostscript-cve-2016-7978.patch b/SOURCES/ghostscript-cve-2016-7978.patch new file mode 100644 index 0000000..c19cd8b --- /dev/null +++ b/SOURCES/ghostscript-cve-2016-7978.patch @@ -0,0 +1,25 @@ +From fc3f0de2d6cd6f74ae94fc340e4d5fe8ac165314 Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Wed, 5 Oct 2016 09:59:25 +0100 +Subject: [PATCH] Bug 697179: Reference count device icc profile + +when copying a device +--- + base/gsdevice.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/base/gsdevice.c b/base/gsdevice.c +index 37fcc7e..b52581c 100644 +--- a/base/gsdevice.c ++++ b/base/gsdevice.c +@@ -536,6 +536,7 @@ gx_device_init(gx_device * dev, const gx_device * proto, gs_memory_t * mem, + dev->memory = mem; + dev->retained = !internal; + rc_init(dev, mem, (internal ? 0 : 1)); ++ rc_increment(dev->icc_struct); + } + + void +-- +2.7.4 + diff --git a/SOURCES/ghostscript-cve-2016-7979.patch b/SOURCES/ghostscript-cve-2016-7979.patch new file mode 100644 index 0000000..33d0404 --- /dev/null +++ b/SOURCES/ghostscript-cve-2016-7979.patch @@ -0,0 +1,43 @@ +From b80fc8cd2469fcdab0630cd507f42b410bb96fda Mon Sep 17 00:00:00 2001 +From: Ken Sharp +Date: Wed, 5 Oct 2016 10:10:58 +0100 +Subject: [PATCH] DSC parser - validate parameters + +Bug #697190 ".initialize_dsc_parser doesn't validate the parameter is a dict type before using it." + +Regardless of any security implications, its simply wrong for a PostScript +operator not to validate its parameter(s). + +No differences expected. +--- + psi/zdscpars.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/psi/zdscpars.c b/psi/zdscpars.c +index a6f8fc9..fa61d88 100644 +--- a/psi/zdscpars.c ++++ b/psi/zdscpars.c +@@ -132,11 +132,16 @@ zinitialize_dsc_parser(i_ctx_t *i_ctx_p) + ref local_ref; + int code; + os_ptr const op = osp; +- dict * const pdict = op->value.pdict; +- gs_memory_t * const mem = (gs_memory_t *)dict_memory(pdict); +- dsc_data_t * const data = +- gs_alloc_struct(mem, dsc_data_t, &st_dsc_data_t, "DSC parser init"); ++ dict *pdict; ++ gs_memory_t *mem; ++ dsc_data_t *data; + ++ check_read_type(*op, t_dictionary); ++ ++ pdict = op->value.pdict; ++ mem = (gs_memory_t *)dict_memory(pdict); ++ ++ data = gs_alloc_struct(mem, dsc_data_t, &st_dsc_data_t, "DSC parser init"); + if (!data) + return_error(e_VMerror); + data->document_level = 0; +-- +2.7.4 + diff --git a/SOURCES/ghostscript-cve-2016-8602.patch b/SOURCES/ghostscript-cve-2016-8602.patch new file mode 100644 index 0000000..91785dc --- /dev/null +++ b/SOURCES/ghostscript-cve-2016-8602.patch @@ -0,0 +1,55 @@ +From 30d5e341367002ca5b853b6b651f63e97ba580d1 Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Sat, 8 Oct 2016 16:10:27 +0100 +Subject: [PATCH] Bug 697203: check for sufficient params in .sethalftone5 + +and param types +--- + base/gserrors.h | 1 + + psi/zht2.c | 12 ++++++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/base/gserrors.h b/base/gserrors.h +index 24b5eb4..c7dbe18 100644 +--- a/base/gserrors.h ++++ b/base/gserrors.h +@@ -33,6 +33,7 @@ + #define gs_error_limitcheck (-13) + #define gs_error_nocurrentpoint (-14) + #define gs_error_rangecheck (-15) ++#define gs_error_stackunderflow (-17) + #define gs_error_typecheck (-20) + #define gs_error_undefined (-21) + #define gs_error_undefinedfilename (-22) +diff --git a/psi/zht2.c b/psi/zht2.c +index a53b71b..95fef4b 100644 +--- a/psi/zht2.c ++++ b/psi/zht2.c +@@ -81,14 +81,22 @@ zsethalftone5(i_ctx_t *i_ctx_p) + gs_memory_t *mem; + uint edepth = ref_stack_count(&e_stack); + int npop = 2; +- int dict_enum = dict_first(op); ++ int dict_enum; + ref rvalue[2]; + int cname, colorant_number; + byte * pname; + uint name_size; + int halftonetype, type = 0; + gs_state *pgs = igs; +- int space_index = r_space_index(op - 1); ++ int space_index; ++ ++ if (ref_stack_count(&o_stack) < 2) ++ return_error(gs_error_stackunderflow); ++ check_type(*op, t_dictionary); ++ check_type(*(op - 1), t_dictionary); ++ ++ dict_enum = dict_first(op); ++ space_index = r_space_index(op - 1); + + mem = (gs_memory_t *) idmemory->spaces_indexed[space_index]; + +-- +2.7.4 + diff --git a/SOURCES/ghostscript-cve-2017-7207.patch b/SOURCES/ghostscript-cve-2017-7207.patch new file mode 100644 index 0000000..ebe83fe --- /dev/null +++ b/SOURCES/ghostscript-cve-2017-7207.patch @@ -0,0 +1,33 @@ +From 309eca4e0a31ea70dcc844812691439312dad091 Mon Sep 17 00:00:00 2001 +From: Ken Sharp +Date: Mon, 20 Mar 2017 09:34:11 +0000 +Subject: [PATCH] Ensure a device has raster memory, before trying to read it. + +Bug #697676 "Null pointer dereference in mem_get_bits_rectangle()" + +This is only possible by abusing/mis-using Ghostscript-specific +language extensions, so cannot happen in a general PostScript program. + +Nevertheless, Ghostscript should not crash. So this commit checks the +memory device to see if raster memory has been allocated, before trying +to read from it. +--- + base/gdevmem.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/base/gdevmem.c b/base/gdevmem.c +index afd05bd..d52d684 100644 +--- a/base/gdevmem.c ++++ b/base/gdevmem.c +@@ -606,6 +606,8 @@ mem_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, + GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE; + return_error(gs_error_rangecheck); + } ++ if (mdev->line_ptrs == 0x00) ++ return_error(gs_error_rangecheck); + if ((w <= 0) | (h <= 0)) { + if ((w | h) < 0) + return_error(gs_error_rangecheck); +-- +2.9.3 + diff --git a/SOURCES/ghostscript-cve-2017-8291.patch b/SOURCES/ghostscript-cve-2017-8291.patch new file mode 100644 index 0000000..41289a3 --- /dev/null +++ b/SOURCES/ghostscript-cve-2017-8291.patch @@ -0,0 +1,185 @@ +From 3a0439ded9a206060f560bd6784942adeab759ff Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Thu, 27 Apr 2017 13:03:33 +0100 +Subject: [PATCH 1/4] Bug 697799: have .eqproc check its parameters + +The Ghostscript custom operator .eqproc was not check the number or type of +the parameters it was given. +--- + psi/zmisc3.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/psi/zmisc3.c b/psi/zmisc3.c +index 54b3042..0d357f1 100644 +--- a/psi/zmisc3.c ++++ b/psi/zmisc3.c +@@ -56,6 +56,12 @@ zeqproc(i_ctx_t *i_ctx_p) + ref2_t stack[MAX_DEPTH + 1]; + ref2_t *top = stack; + ++ if (ref_stack_count(&o_stack) < 2) ++ return_error(e_stackunderflow); ++ if (!r_is_array(op - 1) || !r_is_array(op)) { ++ return_error(e_typecheck); ++ } ++ + make_array(&stack[0].proc1, 0, 1, op - 1); + make_array(&stack[0].proc2, 0, 1, op); + for (;;) { +-- +2.9.3 + + +From 9040e08c62422937c27fa5179657fbe3690809f3 Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Thu, 27 Apr 2017 13:21:31 +0100 +Subject: [PATCH 2/4] Bug 697799: have .rsdparams check its parameters + +The Ghostscript internal operator .rsdparams wasn't checking the number or +type of the operands it was being passed. Do so. +--- + psi/zfrsd.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/psi/zfrsd.c b/psi/zfrsd.c +index fb4bce9..2629afa 100644 +--- a/psi/zfrsd.c ++++ b/psi/zfrsd.c +@@ -49,13 +49,20 @@ zrsdparams(i_ctx_t *i_ctx_p) + ref *pFilter; + ref *pDecodeParms; + int Intent = 0; +- bool AsyncRead; ++ bool AsyncRead = false; + ref empty_array, filter1_array, parms1_array; + uint i; +- int code; ++ int code = 0; ++ ++ if (ref_stack_count(&o_stack) < 1) ++ return_error(e_stackunderflow); ++ if (!r_has_type(op, t_dictionary) && !r_has_type(op, t_null)) { ++ return_error(e_typecheck); ++ } + + make_empty_array(&empty_array, a_readonly); +- if (dict_find_string(op, "Filter", &pFilter) > 0) { ++ if (r_has_type(op, t_dictionary) ++ && dict_find_string(op, "Filter", &pFilter) > 0) { + if (!r_is_array(pFilter)) { + if (!r_has_type(pFilter, t_name)) + return_error(e_typecheck); +@@ -94,12 +101,13 @@ zrsdparams(i_ctx_t *i_ctx_p) + return_error(e_typecheck); + } + } +- code = dict_int_param(op, "Intent", 0, 3, 0, &Intent); ++ if (r_has_type(op, t_dictionary)) ++ code = dict_int_param(op, "Intent", 0, 3, 0, &Intent); + if (code < 0 && code != e_rangecheck) /* out-of-range int is ok, use 0 */ + return code; +- if ((code = dict_bool_param(op, "AsyncRead", false, &AsyncRead)) < 0 +- ) +- return code; ++ if (r_has_type(op, t_dictionary)) ++ if ((code = dict_bool_param(op, "AsyncRead", false, &AsyncRead)) < 0) ++ return code; + push(1); + op[-1] = *pFilter; + if (pDecodeParms) +-- +2.9.3 + + +From ba6c38c25e8c0ece91c47d96578f3f7a0e6c4e6c Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Wed, 3 May 2017 12:05:45 +0100 +Subject: [PATCH 3/4] Bug 697846: revision to commit 4f83478c88 (.eqproc) + +When using the "DELAYBIND" feature, it turns out that .eqproc can be called with +parameters that are not both procedures. In this case, it turns out, the +expectation is for the operator to return 'false', rather than throw an error. +--- + psi/zmisc3.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/psi/zmisc3.c b/psi/zmisc3.c +index 0d357f1..9042908 100644 +--- a/psi/zmisc3.c ++++ b/psi/zmisc3.c +@@ -38,6 +38,15 @@ zcliprestore(i_ctx_t *i_ctx_p) + return gs_cliprestore(igs); + } + ++static inline bool ++eqproc_check_type(ref *r) ++{ ++ return r_has_type(r, t_array) ++ || r_has_type(r, t_mixedarray) ++ || r_has_type(r, t_shortarray) ++ || r_has_type(r, t_oparray); ++} ++ + /* .eqproc */ + /* + * Test whether two procedures are equal to depth 10. +@@ -58,8 +67,10 @@ zeqproc(i_ctx_t *i_ctx_p) + + if (ref_stack_count(&o_stack) < 2) + return_error(e_stackunderflow); +- if (!r_is_array(op - 1) || !r_is_array(op)) { +- return_error(e_typecheck); ++ if (!eqproc_check_type(op -1) || !eqproc_check_type(op)) { ++ make_false(op - 1); ++ pop(1); ++ return 0; + } + + make_array(&stack[0].proc1, 0, 1, op - 1); +-- +2.9.3 + + +From ae3fdbd05b0e654273402e7391288a091a1c0a9e Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Thu, 11 May 2017 14:07:48 +0100 +Subject: [PATCH 4/4] Bug 697892: fix check for op stack underflow. + +In the original fix, I used the wrong method to check for stack underflow, this +is using the correct method. +--- + psi/zfrsd.c | 3 +-- + psi/zmisc3.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/psi/zfrsd.c b/psi/zfrsd.c +index 2629afa..fd9872e 100644 +--- a/psi/zfrsd.c ++++ b/psi/zfrsd.c +@@ -54,8 +54,7 @@ zrsdparams(i_ctx_t *i_ctx_p) + uint i; + int code = 0; + +- if (ref_stack_count(&o_stack) < 1) +- return_error(e_stackunderflow); ++ check_op(1); + if (!r_has_type(op, t_dictionary) && !r_has_type(op, t_null)) { + return_error(e_typecheck); + } +diff --git a/psi/zmisc3.c b/psi/zmisc3.c +index 9042908..43803b5 100644 +--- a/psi/zmisc3.c ++++ b/psi/zmisc3.c +@@ -65,8 +65,7 @@ zeqproc(i_ctx_t *i_ctx_p) + ref2_t stack[MAX_DEPTH + 1]; + ref2_t *top = stack; + +- if (ref_stack_count(&o_stack) < 2) +- return_error(e_stackunderflow); ++ check_op(2); + if (!eqproc_check_type(op -1) || !eqproc_check_type(op)) { + make_false(op - 1); + pop(1); +-- +2.9.3 + diff --git a/SOURCES/ghostscript-cve-2018-10194.patch b/SOURCES/ghostscript-cve-2018-10194.patch new file mode 100644 index 0000000..88c6604 --- /dev/null +++ b/SOURCES/ghostscript-cve-2018-10194.patch @@ -0,0 +1,43 @@ +From 544b68a3436e72f138e283af26b168ac46dda4c5 Mon Sep 17 00:00:00 2001 +From: Ken Sharp +Date: Wed, 18 Apr 2018 15:46:32 +0100 +Subject: [PATCH] pdfwrite - Guard against trying to output an infinite number + +Bug #699255 " Buffer overflow on pprintg1 due to mishandle postscript file data to pdf" + +The file uses an enormous parameter to xyxhow, causing an overflow in +the calculation of text positioning (value > 1e39). + +Since this is basically a nonsense value, and PostScript only supports +real values up to 1e38, this patch follows the same approach as for +a degenerate CTM, and treats it as 0. + +Adobe Acrobat Distiller throws a limitcheck error, so we could do that +instead if this approach proves to be a problem. +--- + base/gdevpdts.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/base/gdevpdts.c b/base/gdevpdts.c +index f9321a3..fff6c17 100644 +--- a/base/gdevpdts.c ++++ b/base/gdevpdts.c +@@ -152,9 +152,14 @@ append_text_move(pdf_text_state_t *pts, floatp dw) + static int + set_text_distance(gs_point *pdist, floatp dx, floatp dy, const gs_matrix *pmat) + { +- int code = gs_distance_transform_inverse(dx, dy, pmat, pdist); ++ int code; + double rounded; + ++ if (dx > 1e38 || dy > 1e38) ++ code = gs_error_undefinedresult; ++ else ++ code = gs_distance_transform_inverse(dx, dy, pmat, pdist); ++ + if (code == gs_error_undefinedresult) { + /* The CTM is degenerate. + Can't know the distance in user space. +-- +2.14.3 + diff --git a/SOURCES/ghostscript-cve-2018-15910.patch b/SOURCES/ghostscript-cve-2018-15910.patch new file mode 100644 index 0000000..259fe43 --- /dev/null +++ b/SOURCES/ghostscript-cve-2018-15910.patch @@ -0,0 +1,47 @@ +From ebcbe0d685911ffc95f3584f6fcbf1f695959757 Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Tue, 21 Aug 2018 16:42:45 +0100 +Subject: [PATCH] Bug 699656: Handle LockDistillerParams not being a boolean + +This caused a function call commented as "Can't fail" to fail, and resulted +in memory correuption and a segfault. +--- + base/gdevpdfp.c | 2 +- + psi/iparam.c | 7 ++++--- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/base/gdevpdfp.c b/base/gdevpdfp.c +index 7e12fe1..d0f0992 100644 +--- a/base/gdevpdfp.c ++++ b/base/gdevpdfp.c +@@ -320,7 +320,7 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par + * LockDistillerParams is read again, and reset if necessary, in + * psdf_put_params. + */ +- ecode = code = param_read_bool(plist, "LockDistillerParams", &locked); ++ ecode = code = param_read_bool(plist, (param_name = "LockDistillerParams"), &locked); + if (ecode < 0) + param_signal_error(plist, param_name, ecode); + +diff --git a/psi/iparam.c b/psi/iparam.c +index 559b9b8..6f35745 100644 +--- a/psi/iparam.c ++++ b/psi/iparam.c +@@ -821,10 +821,11 @@ static int + ref_param_read_signal_error(gs_param_list * plist, gs_param_name pkey, int code) + { + iparam_list *const iplist = (iparam_list *) plist; +- iparam_loc loc; ++ iparam_loc loc = {0}; + +- ref_param_read(iplist, pkey, &loc, -1); /* can't fail */ +- *loc.presult = code; ++ ref_param_read(iplist, pkey, &loc, -1); ++ if (loc.presult) ++ *loc.presult = code; + switch (ref_param_read_get_policy(plist, pkey)) { + case gs_param_policy_ignore: + return 0; +-- +2.14.4 + diff --git a/SOURCES/ghostscript-cve-2018-16509.patch b/SOURCES/ghostscript-cve-2018-16509.patch new file mode 100644 index 0000000..d39a744 --- /dev/null +++ b/SOURCES/ghostscript-cve-2018-16509.patch @@ -0,0 +1,235 @@ +From 26d93b9a3f2a47ece821defe12e9059b4a7a3bf2 Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Fri, 24 Aug 2018 09:26:04 +0100 +Subject: [PATCH] Improve restore robustness + +Prompted by looking at Bug 699654: + +There are two variants of the restore operator in Ghostscript: one is Level 1 +(restoring VM), the other is Level 2+ (adding page device restoring to the +Level operator). + +This was implemented by the Level 2+ version restoring the device in the +graphics state, then calling the Level 1 implementation to handle actually +restoring the VM state. + +The problem was that the operand checking, and sanity of the save object was +only done by the Level 1 variant, thus meaning an invalid save object could +leave a (Level 2+) restore partially complete - with the page device part +restored, but not VM, and the page device not configured. + +To solve that, this commit splits the operand and sanity checking, and the +core of the restore operation into separate functions, so the relevant +operators can validate the operand *before* taking any further action. That +reduces the chances of an invalid restore leaving the interpreter in an +unknown state. + +If an error occurs during the actual VM restore it is essentially fatal, and the +interpreter cannot continue, but as an extra surety for security, in the event +of such an error, we'll explicitly preserve the LockSafetyParams of the device, +rather than rely on the post-restore device configuration (which won't happen +in the event of an error). +--- + psi/int.mak | 4 ++-- + psi/isave.h | 6 ++++++ + psi/zdevice2.c | 32 ++++++++++++++++++++++++++++++-- + psi/zvmem.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++--------- + 4 files changed, 85 insertions(+), 13 deletions(-) + +diff --git a/psi/int.mak b/psi/int.mak +index fbf191d..4d0f296 100644 +--- a/psi/int.mak ++++ b/psi/int.mak +@@ -1047,8 +1047,8 @@ $(PSD)pagedev.dev : $(INT_MAK) $(ECHOGS_XE) $(pagedev_) + + $(PSOBJ)zdevice2.$(OBJ) : $(PSSRC)zdevice2.c $(OP) $(math__h) $(memory__h)\ + $(dstack_h) $(estack_h)\ +- $(idict_h) $(idparam_h) $(igstate_h) $(iname_h) $(iutil_h) $(store_h)\ +- $(gxdevice_h) $(gsstate_h) ++ $(idict_h) $(idparam_h) $(igstate_h) $(iname_h) $(isave) $(iutil_h) \ ++ $(store_h) $(gxdevice_h) $(gsstate_h) + $(PSCC) $(PSO_)zdevice2.$(OBJ) $(C_) $(PSSRC)zdevice2.c + + $(PSOBJ)zmedia2.$(OBJ) : $(PSSRC)zmedia2.c $(OP) $(math__h) $(memory__h)\ +diff --git a/psi/isave.h b/psi/isave.h +index f8a6f32..0914de1 100644 +--- a/psi/isave.h ++++ b/psi/isave.h +@@ -122,4 +122,10 @@ int font_restore(const alloc_save_t * save); + express purpose of getting the library context. */ + gs_memory_t *gs_save_any_memory(const alloc_save_t *save); + ++int ++restore_check_save(i_ctx_t *i_ctx_p, alloc_save_t **asave); ++ ++int ++dorestore(i_ctx_t *i_ctx_p, alloc_save_t *asave); ++ + #endif /* isave_INCLUDED */ +diff --git a/psi/zdevice2.c b/psi/zdevice2.c +index f391da1..2ed2a3b 100644 +--- a/psi/zdevice2.c ++++ b/psi/zdevice2.c +@@ -26,6 +26,7 @@ + #include "igstate.h" + #include "iname.h" + #include "iutil.h" ++#include "isave.h" + #include "store.h" + #include "gxdevice.h" + #include "gsstate.h" +@@ -306,11 +307,25 @@ z2grestoreall(i_ctx_t *i_ctx_p) + } + return 0; + } +- ++/* This is the Level 2+ variant of restore - which adds restoring ++ of the page device to the Level 1 variant in zvmem.c. ++ Previous this restored the device state before calling zrestore.c ++ which validated operands etc, meaning a restore could error out ++ partially complete. ++ The operand checking, and actual VM restore are now in two functions ++ so they can called separately thus, here, we can do as much ++ checking as possible, before embarking on actual changes ++ */ + /* restore - */ + static int + z2restore(i_ctx_t *i_ctx_p) + { ++ alloc_save_t *asave; ++ bool saveLockSafety = gs_currentdevice_inline(igs)->LockSafetyParams; ++ int code = restore_check_save(i_ctx_p, &asave); ++ ++ if (code < 0) return code; ++ + while (gs_state_saved(gs_state_saved(igs))) { + if (restore_page_device(igs, gs_state_saved(igs))) + return push_callout(i_ctx_p, "%restore1pagedevice"); +@@ -318,7 +333,20 @@ z2restore(i_ctx_t *i_ctx_p) + } + if (restore_page_device(igs, gs_state_saved(igs))) + return push_callout(i_ctx_p, "%restorepagedevice"); +- return zrestore(i_ctx_p); ++ ++ code = dorestore(i_ctx_p, asave); ++ ++ if (code < 0) { ++ /* An error here is basically fatal, but.... ++ restore_page_device() has to set LockSafetyParams false so it can ++ configure the restored device correctly - in normal operation, that ++ gets reset by that configuration. If we hit an error, though, that ++ may not happen - at least ensure we keep the setting through the ++ error. ++ */ ++ gs_currentdevice_inline(igs)->LockSafetyParams = saveLockSafety; ++ } ++ return code; + } + + /* setgstate - */ +diff --git a/psi/zvmem.c b/psi/zvmem.c +index 4ad8f9a..d8de39d 100644 +--- a/psi/zvmem.c ++++ b/psi/zvmem.c +@@ -104,19 +104,18 @@ zsave(i_ctx_t *i_ctx_p) + static int restore_check_operand(os_ptr, alloc_save_t **, gs_dual_memory_t *); + static int restore_check_stack(const i_ctx_t *i_ctx_p, const ref_stack_t *, const alloc_save_t *, bool); + static void restore_fix_stack(i_ctx_t *i_ctx_p, ref_stack_t *, const alloc_save_t *, bool); ++ ++/* Do as many up front checks of the save object as we reasonably can */ + int +-zrestore(i_ctx_t *i_ctx_p) ++restore_check_save(i_ctx_t *i_ctx_p, alloc_save_t **asave) + { + os_ptr op = osp; +- alloc_save_t *asave; +- bool last; +- vm_save_t *vmsave; +- int code = restore_check_operand(op, &asave, idmemory); ++ int code = restore_check_operand(op, asave, idmemory); + + if (code < 0) + return code; + if_debug2m('u', imemory, "[u]vmrestore 0x%lx, id = %lu\n", +- (ulong) alloc_save_client_data(asave), ++ (ulong) alloc_save_client_data(*asave), + (ulong) op->value.saveid); + if (I_VALIDATE_BEFORE_RESTORE) + ivalidate_clean_spaces(i_ctx_p); +@@ -125,14 +124,37 @@ zrestore(i_ctx_t *i_ctx_p) + { + int code; + +- if ((code = restore_check_stack(i_ctx_p, &o_stack, asave, false)) < 0 || +- (code = restore_check_stack(i_ctx_p, &e_stack, asave, true)) < 0 || +- (code = restore_check_stack(i_ctx_p, &d_stack, asave, false)) < 0 ++ if ((code = restore_check_stack(i_ctx_p, &o_stack, *asave, false)) < 0 || ++ (code = restore_check_stack(i_ctx_p, &e_stack, *asave, true)) < 0 || ++ (code = restore_check_stack(i_ctx_p, &d_stack, *asave, false)) < 0 + ) { + osp++; + return code; + } + } ++ osp++; ++ return 0; ++} ++ ++/* the semantics of restore differ slightly between Level 1 and ++ Level 2 and later - the latter includes restoring the device ++ state (whilst Level 1 didn't have "page devices" as such). ++ Hence we have two restore operators - one here (Level 1) ++ and one in zdevice2.c (Level 2+). For that reason, the ++ operand checking and guts of the restore operation are ++ separated so both implementations can use them to best ++ effect. ++ */ ++int ++dorestore(i_ctx_t *i_ctx_p, alloc_save_t *asave) ++{ ++ os_ptr op = osp; ++ bool last; ++ vm_save_t *vmsave; ++ int code; ++ ++ osp--; ++ + /* Reset l_new in all stack entries if the new save level is zero. */ + /* Also do some special fixing on the e-stack. */ + restore_fix_stack(i_ctx_p, &o_stack, asave, false); +@@ -175,9 +197,24 @@ zrestore(i_ctx_t *i_ctx_p) + /* cause an 'invalidaccess' in setuserparams. Temporarily set */ + /* LockFilePermissions false until the gs_lev2.ps can do a */ + /* setuserparams from the restored userparam dictionary. */ ++ /* NOTE: This is safe to do here, since the restore has */ ++ /* successfully completed - this should never come before any */ ++ /* operation that can trigger an error */ + i_ctx_p->LockFilePermissions = false; + return 0; + } ++ ++int ++zrestore(i_ctx_t *i_ctx_p) ++{ ++ alloc_save_t *asave; ++ int code = restore_check_save(i_ctx_p, &asave); ++ if (code < 0) ++ return code; ++ ++ return dorestore(i_ctx_p, asave); ++} ++ + /* Check the operand of a restore. */ + static int + restore_check_operand(os_ptr op, alloc_save_t ** pasave, +@@ -198,6 +235,7 @@ restore_check_operand(os_ptr op, alloc_save_t ** pasave, + *pasave = asave; + return 0; + } ++ + /* Check a stack to make sure all its elements are older than a save. */ + static int + restore_check_stack(const i_ctx_t *i_ctx_p, const ref_stack_t * pstack, +-- +2.14.4 + diff --git a/SOURCES/ghostscript-cve-2018-16542.patch b/SOURCES/ghostscript-cve-2018-16542.patch new file mode 100644 index 0000000..605ff0a --- /dev/null +++ b/SOURCES/ghostscript-cve-2018-16542.patch @@ -0,0 +1,36 @@ +From b661fd3bf2a7a8ba375131527551bd2834ad1abf Mon Sep 17 00:00:00 2001 +From: Chris Liddell +Date: Thu, 23 Aug 2018 12:20:56 +0100 +Subject: [PATCH] Bug 699668: handle stack overflow during error handling + +When handling a Postscript error, we push the object throwing the error onto +the operand stack for the error handling procedure to access - we were not +checking the available stack before doing so, thus causing a crash. + +Basically, if we get a stack overflow when already handling an error, we're out +of options, return to the caller with a fatal error. +--- + psi/interp.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/psi/interp.c b/psi/interp.c +index 3e3aaaa..1ed7074 100644 +--- a/psi/interp.c ++++ b/psi/interp.c +@@ -665,7 +665,12 @@ again: + /* Push the error object on the operand stack if appropriate. */ + if (!ERROR_IS_INTERRUPT(code)) { + /* Replace the error object if within an oparray or .errorexec. */ +- *++osp = *perror_object; ++ osp++; ++ if (osp >= ostop) { ++ *pexit_code = gs_error_Fatal; ++ return_error(gs_error_Fatal); ++ } ++ *osp = *perror_object; + errorexec_find(i_ctx_p, osp); + } + goto again; +-- +2.14.4 + diff --git a/SOURCES/ghostscript-fix-infinite-for-loop.patch b/SOURCES/ghostscript-fix-infinite-for-loop.patch new file mode 100644 index 0000000..b4edcab --- /dev/null +++ b/SOURCES/ghostscript-fix-infinite-for-loop.patch @@ -0,0 +1,26 @@ +From 26b11a3fe34fc3c4e81e17c4fc82a674aa238d97 Mon Sep 17 00:00:00 2001 +From: Michael Vrhel +Date: Mon, 16 Dec 2013 08:32:12 -0800 +Subject: [PATCH] Fix for goof up in loop index variable. + +Fixes bug 694811 and 694848. Thanks ken for finding this. +--- + base/gdevp14.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/base/gdevp14.c b/base/gdevp14.c +index ef2a50f..bfbf694 100644 +--- a/base/gdevp14.c ++++ b/base/gdevp14.c +@@ -2247,7 +2247,7 @@ pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x, + if (overprint) { + if (blendspot) { + /* Overprint simulation of spot colorants */ +- for (k = 0; k < num_comp; ++i) { ++ for (k = 0; k < num_comp; ++k) { + int temp = + (255 - dst_ptr[k * planestride]) * dst[k]; + temp = temp >> 8; +-- +2.9.3 + diff --git a/SOURCES/ghostscript-fix-locksafe.patch b/SOURCES/ghostscript-fix-locksafe.patch new file mode 100644 index 0000000..4550cca --- /dev/null +++ b/SOURCES/ghostscript-fix-locksafe.patch @@ -0,0 +1,30 @@ +From 2d12af7be33df59db60c06e149b013be41aca68c Mon Sep 17 00:00:00 2001 +From: Ken Sharp +Date: Fri, 10 Jun 2016 09:49:02 +0100 +Subject: [PATCH] Fix .locksafe + +Apparently we need to .forceput the definition of getenve into +systemdict, at least when running GSView 5.0. + +Discovered when trying to investigate a customer bug report using +GSView 5. +--- + Resource/Init/gs_init.ps | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps +index abb9489..0083fa3 100644 +--- a/Resource/Init/gs_init.ps ++++ b/Resource/Init/gs_init.ps +@@ -2019,7 +2019,7 @@ readonly def + /LockFilePermissions //true + >> setuserparams + } +- systemdict /getenv {pop //false} put ++ systemdict /getenv {pop //false} .forceput + if + % setpagedevice has the side effect of clearing the page, but + % we will just document that. Using setpagedevice keeps the device +-- +2.9.3 + diff --git a/SOURCES/ghostscript-gdevcups-debug-uninit.patch b/SOURCES/ghostscript-gdevcups-debug-uninit.patch new file mode 100644 index 0000000..9122d1f --- /dev/null +++ b/SOURCES/ghostscript-gdevcups-debug-uninit.patch @@ -0,0 +1,11 @@ +diff -up ghostscript-9.07/cups/gdevcups.c.gdevcups-debug-uninit ghostscript-9.07/cups/gdevcups.c +--- ghostscript-9.07/cups/gdevcups.c.gdevcups-debug-uninit 2013-02-14 07:58:16.000000000 +0000 ++++ ghostscript-9.07/cups/gdevcups.c 2013-02-14 17:16:59.677951232 +0000 +@@ -830,6 +830,7 @@ cups_get_matrix(gx_device *pdev, /* I - + dmprintf4(pdev->memory, "DEBUG2: PageSize = [ %d %d ], HWResolution = [ %d %d ]\n", + cups->header.PageSize[0], cups->header.PageSize[1], + cups->header.HWResolution[0], cups->header.HWResolution[1]); ++ if (size_set) + dmprintf4(pdev->memory, "DEBUG2: HWMargins = [ %.3f %.3f %.3f %.3f ]\n", + pdev->HWMargins[0], pdev->HWMargins[1], pdev->HWMargins[2], + pdev->HWMargins[3]); diff --git a/SOURCES/ghostscript-gs_sprintf.patch b/SOURCES/ghostscript-gs_sprintf.patch new file mode 100644 index 0000000..feb2d5b --- /dev/null +++ b/SOURCES/ghostscript-gs_sprintf.patch @@ -0,0 +1,28447 @@ +diff -up ghostscript-9.07/base/fapiufst.c.gs_sprintf ghostscript-9.07/base/fapiufst.c +--- ghostscript-9.07/base/fapiufst.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/fapiufst.c 2013-05-09 17:02:39.056447042 +0100 +@@ -699,7 +699,7 @@ pack_long(LPUB8 * p, UL32 v) + static inline void + pack_float(LPUB8 * p, float v) + { +- sprintf((char *)(*p), "%f", v); ++ gs_sprintf((char *)(*p), "%f", v); + *p += strlen((const char *)*p) + 1; + } + +diff -up ghostscript-9.07/base/gdev3b1.c.gs_sprintf ghostscript-9.07/base/gdev3b1.c +--- ghostscript-9.07/base/gdev3b1.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdev3b1.c 2013-05-09 17:02:39.057447046 +0100 +@@ -538,7 +538,7 @@ att3b1_do_output_page(gx_device *dev, in + } + + ut.ut_num = WTXTSLK1; +- sprintf(ut.ut_text, ++ gs_sprintf(ut.ut_text, + "%s %d, top right (%d,%d), size (%d,%d), press '?' for help.", + flush ? "Showpage" : "Copypage", att3b1dev->page_num, xorigin, yorigin, + att3b1dev->width, att3b1dev->height); +diff -up ghostscript-9.07/base/gdev8510.c.gs_sprintf ghostscript-9.07/base/gdev8510.c +--- ghostscript-9.07/base/gdev8510.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdev8510.c 2013-05-09 17:02:39.058447051 +0100 +@@ -129,7 +129,7 @@ m8510_output_run(gx_device_printer *pdev + /* Transfer the line of data. */ + count = out_end - out; + if (count) { +- sprintf(tmp, "\033g%03d", count/8); ++ gs_sprintf(tmp, "\033g%03d", count/8); + fwrite(tmp, 1, 5, prn_stream); + fwrite(out, 1, count, prn_stream); + fwrite("\r", 1, 1, prn_stream); +diff -up ghostscript-9.07/base/gdevccr.c.gs_sprintf ghostscript-9.07/base/gdevccr.c +--- ghostscript-9.07/base/gdevccr.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevccr.c 2013-05-09 17:02:39.059447055 +0100 +@@ -207,9 +207,9 @@ static int alloc_rb( gs_memory_t *mem, c + int r; + for(r=0; rfname, i); ++ gs_sprintf(spotname, "%ss%d", pdevn->fname, i); + spot_file[i] = gp_fopen(spotname, "wb"); + if (spot_file[i] == NULL) { + code = gs_error_VMerror; +@@ -2117,7 +2117,7 @@ spotcmyk_print_page(gx_device_printer * + return code; + } + for(i = 0; i < nspot; i++) { +- sprintf(spotname, "%ss%d", pdevn->fname, i); ++ gs_sprintf(spotname, "%ss%d", pdevn->fname, i); + code = devn_write_pcx_file(pdev, spotname, 1, bpc, linelength[i]); + if (code < 0) + return code; +@@ -2451,7 +2451,7 @@ devn_write_pcx_file(gx_device_printer * + in = gp_fopen(filename, "rb"); + if (!in) + return_error(gs_error_invalidfileaccess); +- sprintf(outname, "%s.pcx", filename); ++ gs_sprintf(outname, "%s.pcx", filename); + out = gp_fopen(outname, "wb"); + if (!out) { + fclose(in); +diff -up ghostscript-9.07/base/gdevdjet.c.gs_sprintf ghostscript-9.07/base/gdevdjet.c +--- ghostscript-9.07/base/gdevdjet.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevdjet.c 2013-05-09 17:02:39.061447064 +0100 +@@ -323,9 +323,9 @@ hpjet_make_init(gx_device_printer *pdev, + else if (dev->MediaPosition_set && dev->MediaPosition >= 0) + paper_source = dev->MediaPosition; + if (paper_source >= 0) +- sprintf(buf, "%s\033&l%dH", str, paper_source); ++ gs_sprintf(buf, "%s\033&l%dH", str, paper_source); + else +- sprintf(buf, "%s", str); ++ gs_sprintf(buf, "%s", str); + } + + /* The DeskJet can compress (mode 2) */ +@@ -361,7 +361,7 @@ fs600_print_page_copies(gx_device_printe + char base_init[60]; + char init[80]; + +- sprintf(base_init, "\033*r0F\033&u%dD", dots_per_inch); ++ gs_sprintf(base_init, "\033*r0F\033&u%dD", dots_per_inch); + hpjet_make_init(pdev, init, base_init); + return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, + dots_per_inch, PCL_FS600_FEATURES, +@@ -425,7 +425,7 @@ ljet3d_print_page_copies(gx_device_print + bool tumble=dev->Tumble; + + hpjet_make_init(pdev, init, "\033&l-180u36Z\033*r0F"); +- sprintf(even_init, "\033&l180u36Z\033*r0F"); ++ gs_sprintf(even_init, "\033&l180u36Z\033*r0F"); + return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, + 300, PCL_LJ3D_FEATURES, init, even_init, tumble); + } +@@ -440,7 +440,7 @@ ljet4_print_page_copies(gx_device_printe + char base_init[60]; + char init[80]; + +- sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); ++ gs_sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); + hpjet_make_init(pdev, init, base_init); + + return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, +@@ -472,9 +472,9 @@ ljet4d_print_page_copies(gx_device_print + in duplex mode we set this parameters for each odd page + (paper tray is set by "hpjet_make_init") + */ +- sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); ++ gs_sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); + hpjet_make_init(pdev, init, base_init); +- sprintf(even_init, "\033&l180u36Z\033*r0F\033&u%dD", dots_per_inch); ++ gs_sprintf(even_init, "\033&l180u36Z\033*r0F\033&u%dD", dots_per_inch); + return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, + dots_per_inch, PCL_LJ4D_FEATURES, + init,even_init,tumble); +@@ -489,7 +489,7 @@ ljet4pjl_print_page_copies(gx_device_pri + { int dots_per_inch = (int)pdev->y_pixels_per_inch; + char real_init[60]; + +- sprintf(real_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); ++ gs_sprintf(real_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); + return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, + dots_per_inch, PCL_LJ4PJL_FEATURES, + real_init, real_init, false); +diff -up ghostscript-9.07/base/gdevijs.c.gs_sprintf ghostscript-9.07/base/gdevijs.c +--- ghostscript-9.07/base/gdevijs.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevijs.c 2013-05-09 17:02:39.063447072 +0100 +@@ -674,7 +674,7 @@ gsijs_set_margin_params(gx_device_ijs *i + } + + if (code == 0) { +- sprintf (buf, "%gx%g", ijsdev->MediaSize[0] * (1.0 / 72), ++ gs_sprintf (buf, "%gx%g", ijsdev->MediaSize[0] * (1.0 / 72), + ijsdev->MediaSize[1] * (1.0 / 72)); + code = ijs_client_set_param(ijsdev->ctx, 0, "PaperSize", + buf, strlen(buf)); +@@ -715,7 +715,7 @@ gsijs_set_margin_params(gx_device_ijs *i + m[1] = ijsdev->MediaSize[1] * (1.0 / 72) - + printable_top - printable_height; + gx_device_set_margins((gx_device *)ijsdev, m, true); +- sprintf (buf, "%gx%g", printable_left, printable_top); ++ gs_sprintf (buf, "%gx%g", printable_left, printable_top); + code = ijs_client_set_param(ijsdev->ctx, 0, "TopLeft", + buf, strlen(buf)); + } +@@ -864,7 +864,7 @@ gsijs_open(gx_device *dev) + /* Note: dup() may not be portable to all interesting IJS + platforms. In that case, this branch should be #ifdef'ed out. + */ +- sprintf(buf, "%d", fd); ++ gs_sprintf(buf, "%d", fd); + ijs_client_set_param(ijsdev->ctx, 0, "OutputFD", buf, strlen(buf)); + close(fd); + } else { +@@ -1021,9 +1021,9 @@ gsijs_output_page(gx_device *dev, int nu + } + + /* Required page parameters */ +- sprintf(buf, "%d", n_chan); ++ gs_sprintf(buf, "%d", n_chan); + gsijs_client_set_param(ijsdev, "NumChan", buf); +- sprintf(buf, "%d", ijsdev->BitsPerSample); ++ gs_sprintf(buf, "%d", ijsdev->BitsPerSample); + gsijs_client_set_param(ijsdev, "BitsPerSample", buf); + + /* This needs to become more sophisticated for DeviceN. */ +@@ -1031,12 +1031,12 @@ gsijs_output_page(gx_device *dev, int nu + ((n_chan == 3) ? (krgb_mode ? ((k_bits == 1) ? "KRGB" : "KxRGB") : "DeviceRGB") : "DeviceGray")); + gsijs_client_set_param(ijsdev, "ColorSpace", buf); + +- sprintf(buf, "%d", ijs_width); ++ gs_sprintf(buf, "%d", ijs_width); + gsijs_client_set_param(ijsdev, "Width", buf); +- sprintf(buf, "%d", ijs_height); ++ gs_sprintf(buf, "%d", ijs_height); + gsijs_client_set_param(ijsdev, "Height", buf); + +- sprintf(buf, "%gx%g", xres, yres); ++ gs_sprintf(buf, "%gx%g", xres, yres); + gsijs_client_set_param(ijsdev, "Dpi", buf); + + #ifdef KRGB_DEBUG +diff -up ghostscript-9.07/base/gdevl31s.c.gs_sprintf ghostscript-9.07/base/gdevl31s.c +--- ghostscript-9.07/base/gdevl31s.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevl31s.c 2013-05-09 17:02:39.063447072 +0100 +@@ -184,9 +184,9 @@ lj3100sw_print_page_copies(gx_device_pri + if (gdev_prn_file_is_new(pdev)) { + lj3100sw_output_section_header(prn_stream, 1, 0, 0); + lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0x1b, 12); +- ptr += sprintf(ptr, "\r\nBD"); ++ ptr += gs_sprintf(ptr, "\r\nBD"); + lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 5520); +- ptr += sprintf(ptr, "%s\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n", ++ ptr += gs_sprintf(ptr, "%s\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n", + "NJ", + "PQ", -1, + "RE", high_resolution ? 6 : 2, +@@ -198,7 +198,7 @@ lj3100sw_print_page_copies(gx_device_pri + } + + lj3100sw_output_section_header(prn_stream, 3, ppdev->NumCopies, 0); +- ptr += sprintf(ptr, "%s %d\r\n%s\r\n", ++ ptr += gs_sprintf(ptr, "%s %d\r\n%s\r\n", + "CM", 1, + "PD"); + *ptr++ = 0; +diff -up ghostscript-9.07/base/gdevp14.c.gs_sprintf ghostscript-9.07/base/gdevp14.c +--- ghostscript-9.07/base/gdevp14.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevp14.c 2013-05-09 17:02:39.065447081 +0100 +@@ -6427,7 +6427,7 @@ get_param_compressed_color_list_elem(pdf + pkeyname_list_elem->next = *pkeyname_list; + pkeyname_list_elem->key_name = keyname_buf; + *pkeyname_list = pkeyname_list_elem; +- sprintf(keyname_buf, "%s_%d", keyname, i); ++ gs_sprintf(keyname_buf, "%s_%d", keyname, i); + get_param_compressed_color_list_elem(pdev, plist, + pcomp_list->u.sub_level_ptrs[i], keyname_buf, + pkeyname_list); +@@ -6498,7 +6498,7 @@ put_param_compressed_color_list_elem(gx_ + char buff[50]; + compressed_color_list_t * sub_list_ptr; + +- sprintf(buff, "%s_%d", keyname, i); ++ gs_sprintf(buff, "%s_%d", keyname, i); + put_param_compressed_color_list_elem(pdev, plist, + &sub_list_ptr, buff, num_comps - 1); + pcomp_list->u.sub_level_ptrs[i] = sub_list_ptr; +@@ -6560,7 +6560,7 @@ get_param_spot_color_names(pdf14_clist_d + pkeyname_list_elem->next = *pkeyname_list; + pkeyname_list_elem->key_name = keyname_buf; + *pkeyname_list = pkeyname_list_elem; +- sprintf(keyname_buf, "PDF14SpotName_%d", i); ++ gs_sprintf(keyname_buf, "PDF14SpotName_%d", i); + str.size = separations->names[i].size; + str.data = separations->names[i].data; + str.persistent = false; +@@ -6596,7 +6596,7 @@ put_param_pdf14_spot_names(gx_device * p + char buff[20]; + byte * sep_name; + +- sprintf(buff, "PDF14SpotName_%d", i); ++ gs_sprintf(buff, "PDF14SpotName_%d", i); + code = param_read_string(plist, buff, &str); + switch (code) { + default: +diff -up ghostscript-9.07/base/gdevpdfb.c.gs_sprintf ghostscript-9.07/base/gdevpdfb.c +--- ghostscript-9.07/base/gdevpdfb.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfb.c 2013-05-09 17:02:39.066447085 +0100 +@@ -588,7 +588,7 @@ gdev_pdf_strip_tile_rectangle(gx_device + if (image_id) { + char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */ + +- sprintf(buf, "/R%ld Do\n", image_id); ++ gs_sprintf(buf, "/R%ld Do\n", image_id); + pprintd1(s, "%d>>stream\n", strlen(buf)); + if (pdev->PDFA != 0) + pprints1(s, "%s\nendstream\n", buf); +diff -up ghostscript-9.07/base/gdevpdf.c.gs_sprintf ghostscript-9.07/base/gdevpdf.c +--- ghostscript-9.07/base/gdevpdf.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdf.c 2013-05-09 17:02:39.067447089 +0100 +@@ -301,7 +301,7 @@ pdf_initialize_ids(gx_device_pdf * pdev) + timeoffset = any_abs(timeoffset) / 60; + tms = *localtime(&t); + +- sprintf(buf, "(D:%04d%02d%02d%02d%02d%02d%c%02d\'%02d\')", ++ gs_sprintf(buf, "(D:%04d%02d%02d%02d%02d%02d%c%02d\'%02d\')", + tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec, + timesign, timeoffset / 60, timeoffset % 60); +@@ -1277,7 +1277,7 @@ static int write_xref_section(gx_device_ + * chances of needing to write white space to pad the file out. + */ + if (!pdev->Linearise) { +- sprintf(str, "%010"PRId64" 00000 n \n", pos); ++ gs_sprintf(str, "%010"PRId64" 00000 n \n", pos); + stream_puts(pdev->strm, str); + } + if (Offsets) +@@ -1310,7 +1310,7 @@ rewrite_object(gx_device_pdf *const pdev + code = fread(&c, 1, 1, linear_params->sfile); + read++; + } while (c != '\n' && code > 0); +- sprintf(Scratch, "%d 0 obj\n", pdev->ResourceUsage[object].NewObjectNumber); ++ gs_sprintf(Scratch, "%d 0 obj\n", pdev->ResourceUsage[object].NewObjectNumber); + fwrite(Scratch, strlen(Scratch), 1, linear_params->Lin_File.file); + + code = fread(&c, 1, 1, linear_params->sfile); +@@ -1359,7 +1359,7 @@ rewrite_object(gx_device_pdf *const pdev + target++; + sscanf(target, "%d 0 R", &ID); + fwrite(source, target - source, 1, linear_params->Lin_File.file); +- sprintf(Buf, "%d 0 R", pdev->ResourceUsage[ID].NewObjectNumber); ++ gs_sprintf(Buf, "%d 0 R", pdev->ResourceUsage[ID].NewObjectNumber); + fwrite(Buf, strlen(Buf), 1, linear_params->Lin_File.file); + source = next; + } else { +@@ -1544,7 +1544,7 @@ static int pdf_linearise(gx_device_pdf * + } + #endif + /* Linearisation. Part 1, file header */ +- sprintf(Header, "%%PDF-%d.%d\n", level / 10, level % 10); ++ gs_sprintf(Header, "%%PDF-%d.%d\n", level / 10, level % 10); + fwrite(Header, strlen(Header), 1, linear_params->Lin_File.file); + if (pdev->binary_ok) + fwrite(Binary, strlen(Binary), 1, linear_params->Lin_File.file); +@@ -1556,16 +1556,16 @@ static int pdf_linearise(gx_device_pdf * + + /* Linearisation. Part 2, the Linearisation dictioanry */ + linear_params->LDictOffset = gp_ftell_64(linear_params->Lin_File.file); +- sprintf(LDict, "%d 0 obj\n<< \n", ++ gs_sprintf(LDict, "%d 0 obj\n<< \n", + LDictObj); + fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file); + + /* First page cross-reference table here (Part 3) */ + linear_params->FirstxrefOffset = gp_ftell_64(linear_params->Lin_File.file); +- sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */ ++ gs_sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */ + fwrite(Header, strlen(Header), 1, linear_params->Lin_File.file); + +- sprintf(Header, "0000000000 00000 n \n"); ++ gs_sprintf(Header, "0000000000 00000 n \n"); + + for (i = LDictObj;i <= linear_params->LastResource + 2; i++) { + fwrite(Header, 20, 1, linear_params->Lin_File.file); +@@ -1575,7 +1575,7 @@ static int pdf_linearise(gx_device_pdf * + * +1 for the linearisation dict and +1 for the primary hint stream. + */ + linear_params->FirsttrailerOffset = gp_ftell_64(linear_params->Lin_File.file); +- sprintf(LDict, "\ntrailer\n<>\nstartxref\r\n0\n%%%%EOF\n \n", ++ gs_sprintf(LDict, "\ntrailer\n<>\nstartxref\r\n0\n%%%%EOF\n \n", + linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, 0); + fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file); + +@@ -1685,7 +1685,7 @@ static int pdf_linearise(gx_device_pdf * + } + } + /* insert the primary hint stream */ +- sprintf(LDict, "%d 0 obj\n<>\nstream\n", HintStreamObj); ++ gs_sprintf(LDict, "%d 0 obj\n<>\nstream\n", HintStreamObj); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); + + HintStreamStart = gp_ftell_64(linear_params->sfile); +@@ -1999,7 +1999,7 @@ static int pdf_linearise(gx_device_pdf * + flush_hint_stream(linear_params); + HintLength = gp_ftell_64(linear_params->sfile) - HintStreamStart; + +- sprintf(LDict, "\nendstream\nendobj\n"); ++ gs_sprintf(LDict, "\nendstream\nendobj\n"); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); + /* Calculate the length of the primary hint stream */ + HintStreamLen = gp_ftell_64(linear_params->sfile) - pdev->ResourceUsage[HintStreamObj].LinearisedOffset; +@@ -2032,23 +2032,23 @@ static int pdf_linearise(gx_device_pdf * + + /* Now the file is long enough, write the xref */ + mainxref = gp_ftell_64(linear_params->sfile); +- sprintf(Header, "xref\n0 %d\n", LDictObj); ++ gs_sprintf(Header, "xref\n0 %d\n", LDictObj); + fwrite(Header, strlen(Header), 1, linear_params->sfile); + + linear_params->T = gp_ftell_64(linear_params->sfile) - 1; +- sprintf(Header, "0000000000 65535 f \n"); ++ gs_sprintf(Header, "0000000000 65535 f \n"); + fwrite(Header, strlen(Header), 1, linear_params->sfile); + + for (i = 1;i < LDictObj; i++) { + for (j = 0; j < pdev->ResourceUsageSize;j++) { + if (pdev->ResourceUsage[j].NewObjectNumber == i) { +- sprintf(Header, "%010ld 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset + HintStreamLen); ++ gs_sprintf(Header, "%010ld 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset + HintStreamLen); + fwrite(Header, 20, 1, linear_params->sfile); + } + } + } + +- sprintf(LDict, "trailer\n<>\nstartxref\n%ld\n%%%%EOF\n", ++ gs_sprintf(LDict, "trailer\n<>\nstartxref\n%ld\n%%%%EOF\n", + LDictObj, linear_params->FirstxrefOffset); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); + +@@ -2062,32 +2062,32 @@ static int pdf_linearise(gx_device_pdf * + * versions. + */ + gp_fseek_64(linear_params->sfile, linear_params->LDictOffset, SEEK_SET); +- sprintf(LDict, "%d 0 obj\n<FileLength); ++ gs_sprintf(LDict, "%d 0 obj\n<FileLength); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); + +- sprintf(LDict, "%ld", pdev->ResourceUsage[HintStreamObj].LinearisedOffset); ++ gs_sprintf(LDict, "%ld", pdev->ResourceUsage[HintStreamObj].LinearisedOffset); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); +- sprintf(LDict, " %ld]", HintStreamLen); ++ gs_sprintf(LDict, " %ld]", HintStreamLen); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); + /* Implementation Note 180 in hte PDF Reference 1.7 says that Acrobat + * gets the 'E' value wrong. So its probably not important.... + */ +- sprintf(LDict, "/O %d/E %ld",pdev->ResourceUsage[pdev->pages[0].Page->id].NewObjectNumber, linear_params->E); ++ gs_sprintf(LDict, "/O %d/E %ld",pdev->ResourceUsage[pdev->pages[0].Page->id].NewObjectNumber, linear_params->E); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); +- sprintf(LDict, "/N %d/T %ld>>\nendobj\n", pdev->next_page, linear_params->T); ++ gs_sprintf(LDict, "/N %d/T %ld>>\nendobj\n", pdev->next_page, linear_params->T); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); + + /* Return to the secondary xref and write it again filling + * in the missing offsets. + */ + gp_fseek_64(linear_params->sfile, linear_params->FirstxrefOffset, SEEK_SET); +- sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */ ++ gs_sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */ + fwrite(Header, strlen(Header), 1, linear_params->sfile); + + for (i = LDictObj;i <= linear_params->LastResource + 2; i++) { + for (j = 0; j < pdev->ResourceUsageSize;j++) { + if (pdev->ResourceUsage[j].NewObjectNumber == i) { +- sprintf(Header, "%010ld 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset); ++ gs_sprintf(Header, "%010ld 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset); + fwrite(Header, 20, 1, linear_params->sfile); + } + } +@@ -2097,14 +2097,14 @@ static int pdf_linearise(gx_device_pdf * + * in the missing values. + */ + code = gp_fseek_64(linear_params->sfile, linear_params->FirsttrailerOffset, SEEK_SET); +- sprintf(LDict, "\ntrailer\n<>\nstartxref\r\n0\n%%%%EOF\n", ++ gs_sprintf(LDict, "\ntrailer\n<>\nstartxref\r\n0\n%%%%EOF\n", + linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, (unsigned long)mainxref); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); + + code = gp_fseek_64(linear_params->sfile, pdev->ResourceUsage[HintStreamObj].LinearisedOffset, SEEK_SET); +- sprintf(LDict, "%d 0 obj\n<sfile); +- sprintf(LDict, "\n/S %10ld>>\nstream\n", SharedHintOffset); ++ gs_sprintf(LDict, "\n/S %10ld>>\nstream\n", SharedHintOffset); + fwrite(LDict, strlen(LDict), 1, linear_params->sfile); + + error: +@@ -2605,7 +2605,7 @@ pdf_close(gx_device * dev) + pprintld1(s, "/Encrypt %ld 0 R ", Encrypt_id); + } + stream_puts(s, ">>\n"); +- sprintf(xref_str, "startxref\n%"PRId64"\n%%%%EOF\n", xref); ++ gs_sprintf(xref_str, "startxref\n%"PRId64"\n%%%%EOF\n", xref); + stream_puts(s, xref_str); + } + } +diff -up ghostscript-9.07/base/gdevpdfe.c.gs_sprintf ghostscript-9.07/base/gdevpdfe.c +--- ghostscript-9.07/base/gdevpdfe.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfe.c 2013-05-09 17:02:39.067447089 +0100 +@@ -205,7 +205,7 @@ pdf_xmp_time(char *buf, int buf_length) + + time(&t); + tms = *localtime(&t); +- sprintf(buf1, ++ gs_sprintf(buf1, + "%04d-%02d-%02d", + tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday); + strncpy(buf, buf1, buf_length); +@@ -860,7 +860,7 @@ pdf_document_metadata(gx_device_pdf *pde + code = COS_WRITE_OBJECT(pres->object, pdev, resourceNone); + if (code < 0) + return code; +- sprintf(buf, "%ld 0 R", pres->object->id); ++ gs_sprintf(buf, "%ld 0 R", pres->object->id); + pdf_record_usage(pdev, pres->object->id, resource_usage_part9_structure); + + code = cos_dict_put_c_key_object(pdev->Catalog, "/Metadata", pres->object); +diff -up ghostscript-9.07/base/gdevpdfg.c.gs_sprintf ghostscript-9.07/base/gdevpdfg.c +--- ghostscript-9.07/base/gdevpdfg.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfg.c 2013-05-09 17:02:39.068447094 +0100 +@@ -674,7 +674,7 @@ pdf_write_transfer_map(gx_device_pdf *pd + gs_function_free(pfn, false, mem); + if (code < 0) + return code; +- sprintf(ids, "%s%s%ld 0 R", key, (key[0] && key[0] != ' ' ? " " : ""), id); ++ gs_sprintf(ids, "%s%s%ld 0 R", key, (key[0] && key[0] != ' ' ? " " : ""), id); + return 0; + } + static int +@@ -1255,7 +1255,7 @@ pdf_update_halftone(gx_device_pdf *pdev, + } + if (code < 0) + return code; +- sprintf(hts, "%ld 0 R", id); ++ gs_sprintf(hts, "%ld 0 R", id); + pdev->halftone_id = pis->dev_ht->id; + return code; + } +@@ -1392,7 +1392,7 @@ pdf_update_alpha(gx_device_pdf *pdev, co + if (pis->soft_mask_id == 0) + strcpy(buf, "/None"); + else +- sprintf(buf, "%ld 0 R", pis->soft_mask_id); ++ gs_sprintf(buf, "%ld 0 R", pis->soft_mask_id); + code = pdf_open_gstate(pdev, ppres); + if (code < 0) + return code; +@@ -1548,7 +1548,7 @@ pdf_prepare_drawing(gx_device_pdf *pdev, + code = pdf_open_gstate(pdev, ppres); + if (code < 0) + return code; +- sprintf(buf, "[%d %d]", phase.x, phase.y); ++ gs_sprintf(buf, "[%d %d]", phase.x, phase.y); + code = cos_dict_put_string_copy(resource_dict(*ppres), "/HTP", buf); + if (code < 0) + return code; +diff -up ghostscript-9.07/base/gdevpdfi.c.gs_sprintf ghostscript-9.07/base/gdevpdfi.c +--- ghostscript-9.07/base/gdevpdfi.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfi.c 2013-05-09 17:02:39.068447094 +0100 +@@ -1122,7 +1122,7 @@ pdf_end_and_do_image(gx_device_pdf *pdev + if (pdev->image_mask_id != gs_no_id) { + char buf[20]; + +- sprintf(buf, "%ld 0 R", pdev->image_mask_id); ++ gs_sprintf(buf, "%ld 0 R", pdev->image_mask_id); + code = cos_dict_put_string_copy((cos_dict_t *)pres->object, + pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf); + if (code < 0) +diff -up ghostscript-9.07/base/gdevpdfm.c.gs_sprintf ghostscript-9.07/base/gdevpdfm.c +--- ghostscript-9.07/base/gdevpdfm.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfm.c 2013-05-09 17:02:39.069447098 +0100 +@@ -153,9 +153,9 @@ pdfmark_make_dest(char dstr[MAX_DEST_STR + else if (pdfmark_find_key("/Action", pairs, count, &action) && + pdf_key_eq(&action, "/GoToR") + ) +- sprintf(dstr, "[%d ", page - 1); ++ gs_sprintf(dstr, "[%d ", page - 1); + else +- sprintf(dstr, "[%ld 0 R ", pdf_page_id(pdev, page)); ++ gs_sprintf(dstr, "[%ld 0 R ", pdf_page_id(pdev, page)); + len = strlen(dstr); + if (len + view_string.size > MAX_DEST_STRING) + return_error(gs_error_limitcheck); +@@ -697,7 +697,7 @@ pdfmark_put_ao_pairs(gx_device_pdf * pde + char dstr[1 + (sizeof(long) * 8 / 3 + 1) + 25 + 1]; + long page_id = pdf_page_id(pdev, pdev->next_page + 1); + +- sprintf(dstr, "[%ld 0 R /XYZ null null null]", page_id); ++ gs_sprintf(dstr, "[%ld 0 R /XYZ null null null]", page_id); + cos_dict_put_c_key_string(pcd, "/Dest", (const unsigned char*) dstr, + strlen(dstr)); + } +@@ -1470,7 +1470,7 @@ pdfmark_PS(gx_device_pdf * pdev, gs_para + if (level1_id != gs_no_id) { + char r[MAX_DEST_STRING]; + +- sprintf(r, "%ld 0 R", level1_id); ++ gs_sprintf(r, "%ld 0 R", level1_id); + code = cos_dict_put_c_key_string(cos_stream_dict(pcs), "/Level1", + (byte *)r, strlen(r)); + if (code < 0) +diff -up ghostscript-9.07/base/gdevpdfo.c.gs_sprintf ghostscript-9.07/base/gdevpdfo.c +--- ghostscript-9.07/base/gdevpdfo.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfo.c 2013-05-09 17:02:39.069447098 +0100 +@@ -700,7 +700,7 @@ cos_array_add_int(cos_array_t *pca, int + char str[sizeof(int) * 8 / 3 + 3]; /* sign, rounding, 0 terminator */ + cos_value_t v; + +- sprintf(str, "%d", i); ++ gs_sprintf(str, "%d", i); + return cos_array_add(pca, cos_string_value(&v, (byte *)str, strlen(str))); + } + int +@@ -1081,7 +1081,7 @@ cos_dict_put_c_key_int(cos_dict_t *pcd, + { + char str[sizeof(int) * 8 / 3 + 3]; /* sign, rounding, 0 terminator */ + +- sprintf(str, "%d", value); ++ gs_sprintf(str, "%d", value); + return cos_dict_put_c_key_string(pcd, key, (byte *)str, strlen(str)); + } + int +diff -up ghostscript-9.07/base/gdevpdfr.c.gs_sprintf ghostscript-9.07/base/gdevpdfr.c +--- ghostscript-9.07/base/gdevpdfr.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfr.c 2013-05-09 17:02:39.070447102 +0100 +@@ -140,7 +140,7 @@ pdf_refer_named(gx_device_pdf * pdev, co + } + if (page_number <= 0) + return code; +- sprintf(page_name_chars, "{Page%d}", page_number); ++ gs_sprintf(page_name_chars, "{Page%d}", page_number); + param_string_from_string(pnstr, page_name_chars); + pname = &pnstr; + code = pdf_find_named(pdev, pname, ppco); +@@ -452,7 +452,7 @@ pdf_replace_names(gx_device_pdf * pdev, + + size += sname - scan; + if (pco) { +- sprintf(ref, " %ld 0 R ", pco->id); ++ gs_sprintf(ref, " %ld 0 R ", pco->id); + size += strlen(ref); + } + scan = next; +@@ -480,7 +480,7 @@ pdf_replace_names(gx_device_pdf * pdev, + memcpy(sto, scan, copy); + sto += copy; + if (pco) { +- sprintf(ref, " %ld 0 R ", pco->id); ++ gs_sprintf(ref, " %ld 0 R ", pco->id); + rlen = strlen(ref); + memcpy(sto, ref, rlen); + sto += rlen; +diff -up ghostscript-9.07/base/gdevpdft.c.gs_sprintf ghostscript-9.07/base/gdevpdft.c +--- ghostscript-9.07/base/gdevpdft.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdft.c 2013-05-09 17:02:39.070447102 +0100 +@@ -63,7 +63,7 @@ pdf_make_soft_mask_dict(gx_device_pdf * + code = pdf_write_function(pdev, pparams->transfer_function, &id); + if (code < 0) + return code; +- sprintf(buf, " %ld 0 R", id); ++ gs_sprintf(buf, " %ld 0 R", id); + code = cos_dict_put_c_key_string(soft_mask_dict, "/TR", (const byte *)buf, strlen(buf)); + if (code < 0) + return code; +@@ -317,7 +317,7 @@ pdf_end_transparency_mask(gs_imager_stat + return 0; + /* We need to update the 'where_used' field, in case we substituted a resource */ + pres->where_used |= pdev->used_mask; +- sprintf(buf, "%ld 0 R", pdf_resource_id(pres)); ++ gs_sprintf(buf, "%ld 0 R", pdf_resource_id(pres)); + code = cos_dict_put_c_key_string((cos_dict_t *)pdev->pres_soft_mask_dict->object, + "/G", (const byte *)buf, strlen(buf)); + if (code < 0) +diff -up ghostscript-9.07/base/gdevpdfu.c.gs_sprintf ghostscript-9.07/base/gdevpdfu.c +--- ghostscript-9.07/base/gdevpdfu.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfu.c 2013-05-09 17:02:39.071447106 +0100 +@@ -341,14 +341,14 @@ static int write_tt_encodings(stream *s, + char Buffer[256]; + single_glyph_list_t *entry = (single_glyph_list_t *)&SingleGlyphList; + +- sprintf(Buffer, "/AdobeGlyphList mark\n"); ++ gs_sprintf(Buffer, "/AdobeGlyphList mark\n"); + stream_write(s, Buffer, strlen(Buffer)); + while (entry->Glyph) { +- sprintf(Buffer, "/%s 16#%04x\n", entry->Glyph, entry->Unicode); ++ gs_sprintf(Buffer, "/%s 16#%04x\n", entry->Glyph, entry->Unicode); + stream_write(s, Buffer, strlen(Buffer)); + entry++; + }; +- sprintf(Buffer, ".dicttomark readonly def\n"); ++ gs_sprintf(Buffer, ".dicttomark readonly def\n"); + stream_write(s, Buffer, strlen(Buffer)); + + index = 0; +@@ -425,24 +425,24 @@ int ps2write_dsc_header(gx_device_pdf * + pagecount++; + } + } +- sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", (int)urx, (int)ury); ++ gs_sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", (int)urx, (int)ury); + stream_write(s, (byte *)BBox, strlen(BBox)); +- sprintf(BBox, "%%%%HiResBoundingBox: 0 0 %.2f %.2f\n", urx, ury); ++ gs_sprintf(BBox, "%%%%HiResBoundingBox: 0 0 %.2f %.2f\n", urx, ury); + stream_write(s, (byte *)BBox, strlen(BBox)); + } + cre_date_time_len = pdf_get_docinfo_item(pdev, "/CreationDate", cre_date_time, sizeof(cre_date_time) - 1); + cre_date_time[cre_date_time_len] = 0; +- sprintf(BBox, "%%%%Creator: %s %d (%s)\n", gs_product, (int)gs_revision, ++ gs_sprintf(BBox, "%%%%Creator: %s %d (%s)\n", gs_product, (int)gs_revision, + pdev->dname); + stream_write(s, (byte *)BBox, strlen(BBox)); + stream_puts(s, "%%LanguageLevel: 2\n"); +- sprintf(BBox, "%%%%CreationDate: %s\n", cre_date_time); ++ gs_sprintf(BBox, "%%%%CreationDate: %s\n", cre_date_time); + stream_write(s, (byte *)BBox, strlen(BBox)); +- sprintf(BBox, "%%%%Pages: %d\n", pages); ++ gs_sprintf(BBox, "%%%%Pages: %d\n", pages); + stream_write(s, (byte *)BBox, strlen(BBox)); +- sprintf(BBox, "%%%%EndComments\n"); ++ gs_sprintf(BBox, "%%%%EndComments\n"); + stream_write(s, (byte *)BBox, strlen(BBox)); +- sprintf(BBox, "%%%%BeginProlog\n"); ++ gs_sprintf(BBox, "%%%%BeginProlog\n"); + stream_write(s, (byte *)BBox, strlen(BBox)); + if (pdev->params.CompressPages) { + /* When CompressEntireFile is true and ASCII85EncodePages is false, +@@ -493,7 +493,7 @@ pdfwrite_pdf_open_document(gx_device_pdf + pdev->CompressEntireFile = 0; + else { + stream_write(s, (byte *)"%!\r", 3); +- sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", width, height); ++ gs_sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", width, height); + stream_write(s, (byte *)BBox, strlen(BBox)); + if (pdev->params.CompressPages || pdev->CompressEntireFile) { + /* When CompressEntireFile is true and ASCII85EncodePages is false, +@@ -1340,7 +1340,7 @@ void + pdf_reserve_object_id(gx_device_pdf * pdev, pdf_resource_t *pres, long id) + { + pres->object->id = (id == 0 ? pdf_obj_ref(pdev) : id); +- sprintf(pres->rname, "R%ld", pres->object->id); ++ gs_sprintf(pres->rname, "R%ld", pres->object->id); + } + + /* Begin an aside (resource, annotation, ...). */ +@@ -1802,9 +1802,9 @@ void + pdf_store_default_Producer(char buf[PDF_MAX_PRODUCER]) + { + if ((gs_revision % 100) == 0) +- sprintf(buf, "(%s %1.1f)", gs_product, gs_revision / 100.0); ++ gs_sprintf(buf, "(%s %1.1f)", gs_product, gs_revision / 100.0); + else +- sprintf(buf, "(%s %1.2f)", gs_product, gs_revision / 100.0); ++ gs_sprintf(buf, "(%s %1.2f)", gs_product, gs_revision / 100.0); + } + + /* Write matrix values. */ +@@ -1851,7 +1851,7 @@ pdf_put_name_chars_1_2(stream *s, const + case '[': case ']': + case '{': case '}': + case '/': +- sprintf(hex, "#%02x", c); ++ gs_sprintf(hex, "#%02x", c); + stream_puts(s, hex); + break; + case 0: +diff -up ghostscript-9.07/base/gdevpdfv.c.gs_sprintf ghostscript-9.07/base/gdevpdfv.c +--- ghostscript-9.07/base/gdevpdfv.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdfv.c 2013-05-09 17:02:39.071447106 +0100 +@@ -157,7 +157,7 @@ pdf_pattern(gx_device_pdf *pdev, const g + + if (pcd_XObject == 0) + return_error(gs_error_VMerror); +- sprintf(key, "/R%ld", pcs_image->id); ++ gs_sprintf(key, "/R%ld", pcs_image->id); + /* This is non-obvious code. Previously we would put the image object (pcs_image) + * into the Resources dit. When we come to write out the Resources dict + * that code writes a reference (index 0 R) using the ID from the object. +@@ -201,7 +201,7 @@ pdf_pattern(gx_device_pdf *pdev, const g + { + char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */ + +- sprintf(buf, "/R%ld Do\n", pcs_image->id); ++ gs_sprintf(buf, "/R%ld Do\n", pcs_image->id); + cos_stream_add_bytes(pcos, (const byte *)buf, strlen(buf)); + } + +@@ -596,7 +596,7 @@ pdf_put_linear_shading(cos_dict_t *pscd, + if (Extend[0] | Extend[1]) { + char extend_str[1 + 5 + 1 + 5 + 1 + 1]; /* [bool bool] */ + +- sprintf(extend_str, "[%s %s]", ++ gs_sprintf(extend_str, "[%s %s]", + (Extend[0] ? "true" : "false"), + (Extend[1] ? "true" : "false")); + code = cos_dict_put_c_key_string(pscd, "/Extend", +diff -up ghostscript-9.07/base/gdevpdtb.c.gs_sprintf ghostscript-9.07/base/gdevpdtb.c +--- ghostscript-9.07/base/gdevpdtb.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdtb.c 2013-05-09 17:02:39.072447111 +0100 +@@ -345,7 +345,7 @@ pdf_base_font_alloc(gx_device_pdf *pdev, + font_name.size -= SUBSET_PREFIX_SIZE; + } + } else { +- sprintf(fnbuf, ".F%lx", (ulong)copied); ++ gs_sprintf(fnbuf, ".F%lx", (ulong)copied); + font_name.data = (byte *)fnbuf; + font_name.size = strlen(fnbuf); + } +@@ -530,7 +530,7 @@ pdf_adjust_font_name(gx_device_pdf *pdev + size = i + 1; + } + /* Create a unique name. */ +- sprintf(suffix, "%c%lx", SUFFIX_CHAR, id); ++ gs_sprintf(suffix, "%c%lx", SUFFIX_CHAR, id); + suffix_size = strlen(suffix); + data = gs_resize_string(pdev->pdf_memory, chars, size, + size + suffix_size, +diff -up ghostscript-9.07/base/gdevpdtc.c.gs_sprintf ghostscript-9.07/base/gdevpdtc.c +--- ghostscript-9.07/base/gdevpdtc.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdtc.c 2013-05-09 17:02:39.072447111 +0100 +@@ -338,7 +338,7 @@ attach_cmap_resource(gx_device_pdf *pdev + strcpy(pdfont->u.type0.Encoding_name, + (pcmap->WMode ? "/Identity-V" : "/Identity-H")); + else +- sprintf(pdfont->u.type0.Encoding_name, "%ld 0 R", ++ gs_sprintf(pdfont->u.type0.Encoding_name, "%ld 0 R", + pdf_resource_id(pcmres)); + pdfont->u.type0.CMapName.data = chars; + pdfont->u.type0.CMapName.size = size; +@@ -349,7 +349,7 @@ attach_cmap_resource(gx_device_pdf *pdev + */ + return_error(gs_error_invalidfont); + +- sprintf(pdfont->u.type0.Encoding_name, "/%s", *pcmn); ++ gs_sprintf(pdfont->u.type0.Encoding_name, "/%s", *pcmn); + pdfont->u.type0.CMapName.data = (const byte *)*pcmn; + pdfont->u.type0.CMapName.size = strlen(*pcmn); + pdfont->u.type0.cmap_is_standard = true; +diff -up ghostscript-9.07/base/gdevpdtf.c.gs_sprintf ghostscript-9.07/base/gdevpdtf.c +--- ghostscript-9.07/base/gdevpdtf.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdtf.c 2013-05-09 17:02:39.072447111 +0100 +@@ -1152,7 +1152,7 @@ pdf_convert_truetype_font(gx_device_pdf + if (code < 0) + return 0; + pdfont->u.cidfont.CIDSystemInfo_id = pdev->IdentityCIDSystemInfo_id; +- sprintf(pdfont0->u.type0.Encoding_name, "%ld 0 R", pdf_resource_id(pdev->OneByteIdentityH)); ++ gs_sprintf(pdfont0->u.type0.Encoding_name, "%ld 0 R", pdf_resource_id(pdev->OneByteIdentityH)); + /* Move ToUnicode : */ + pdfont0->res_ToUnicode = pdfont->res_ToUnicode; pdfont->res_ToUnicode = 0; + pdfont0->cmap_ToUnicode = pdfont->cmap_ToUnicode; pdfont->cmap_ToUnicode = 0; +diff -up ghostscript-9.07/base/gdevpdti.c.gs_sprintf ghostscript-9.07/base/gdevpdti.c +--- ghostscript-9.07/base/gdevpdti.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdti.c 2013-05-09 17:02:39.073447115 +0100 +@@ -1178,7 +1178,7 @@ pdf_add_resource(gx_device_pdf *pdev, co + if (code < 0) + return code; + } +- sprintf(buf, "%ld 0 R\n", pres->object->id); ++ gs_sprintf(buf, "%ld 0 R\n", pres->object->id); + if (v != NULL) { + if (v->value_type != COS_VALUE_OBJECT && + v->value_type != COS_VALUE_RESOURCE) +diff -up ghostscript-9.07/base/gdevpdtt.c.gs_sprintf ghostscript-9.07/base/gdevpdtt.c +--- ghostscript-9.07/base/gdevpdtt.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdtt.c 2013-05-09 17:02:39.074447119 +0100 +@@ -2752,7 +2752,7 @@ pdf_choose_output_glyph_hame(gx_device_p + p = (byte *)gs_alloc_string(pdev->pdf_memory, gnstr->size, "pdf_text_set_cache"); + if (p == NULL) + return_error(gs_error_VMerror); +- sprintf(buf, "g%04x", (unsigned int)(glyph & 0xFFFF)); ++ gs_sprintf(buf, "g%04x", (unsigned int)(glyph & 0xFFFF)); + memcpy(p, buf, 5); + gnstr->data = p; + } +diff -up ghostscript-9.07/base/gdevpdtw.c.gs_sprintf ghostscript-9.07/base/gdevpdtw.c +--- ghostscript-9.07/base/gdevpdtw.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpdtw.c 2013-05-09 17:02:39.074447119 +0100 +@@ -925,7 +925,7 @@ pdf_write_OneByteIdentityH(gx_device_pdf + code = cos_dict_put_string_copy(pcd, "/CMapName", "/OneByteIdentityH"); + if (code < 0) + return code; +- sprintf(buf, "%ld 0 R", pdev->IdentityCIDSystemInfo_id); ++ gs_sprintf(buf, "%ld 0 R", pdev->IdentityCIDSystemInfo_id); + code = cos_dict_put_string_copy(pcd, "/CIDSystemInfo", buf); + if (code < 0) + return code; +diff -up ghostscript-9.07/base/gdevpng.c.gs_sprintf ghostscript-9.07/base/gdevpng.c +--- ghostscript-9.07/base/gdevpng.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpng.c 2013-05-09 17:02:39.074447119 +0100 +@@ -564,7 +564,7 @@ do_png_print_page(gx_device_png * pdev, + } + /* add comment */ + strncpy(software_key, "Software", sizeof(software_key)); +- sprintf(software_text, "%s %d.%02d", gs_product, ++ gs_sprintf(software_text, "%s %d.%02d", gs_product, + (int)(gs_revision / 100), (int)(gs_revision % 100)); + text_png.compression = -1; /* uncompressed */ + text_png.key = software_key; +diff -up ghostscript-9.07/base/gdevps.c.gs_sprintf ghostscript-9.07/base/gdevps.c +--- ghostscript-9.07/base/gdevps.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevps.c 2013-05-09 17:02:39.075447124 +0100 +@@ -526,7 +526,7 @@ psw_image_write(gx_device_pswrite * pdev + const char *op; + + if (index >= 0) { +- sprintf(str, "%d%c", index / 26, index % 26 + 'A'); ++ gs_sprintf(str, "%d%c", index / 26, index % 26 + 'A'); + pprintd2(s, "%d %d ", x, y); + pprints2(s, "%s %s\n", str, imagestr); + if (s->end_status == ERRC) +@@ -556,12 +556,12 @@ psw_image_write(gx_device_pswrite * pdev + }; + + index = image_cache_lookup(pdev, id, width_bits, height, true); +- sprintf(str, "/%d%c", index / 26, index % 26 + 'A'); ++ gs_sprintf(str, "/%d%c", index / 26, index % 26 + 'A'); + stream_puts(s, str); + if (depth != 1) + pprintld1(s, " %ld", ((width_bits + 7) >> 3) * (ulong) height); + op = cached[encode]; +- sprintf(endstr, "\n%s\n", imagestr); ++ gs_sprintf(endstr, "\n%s\n", imagestr); + } + if (s->end_status == ERRC) + return_error(gs_error_ioerror); +@@ -1261,7 +1261,7 @@ psw_copy_color(gx_device * dev, + return (*dev_proc(dev, fill_rectangle)) + (dev, x, y, w, h, (bits[0] << 16) + (bits[1] << 8) + bits[2]); + } +- sprintf(op, "%d Ic", depth / 3); /* RGB */ ++ gs_sprintf(op, "%d Ic", depth / 3); /* RGB */ + code = gdev_vector_update_clip_path(vdev, NULL); + if (code < 0) + return code; +diff -up ghostscript-9.07/base/gdevpsf1.c.gs_sprintf ghostscript-9.07/base/gdevpsf1.c +--- ghostscript-9.07/base/gdevpsf1.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpsf1.c 2013-05-09 17:02:39.075447124 +0100 +@@ -646,12 +646,12 @@ write_Private(stream *s, gs_font_type1 * + gs_free_object(pfont->memory, SubrsWithMM, "free Subrs record"); + return code; + } +- sprintf(buf, "dup %d %u -| ", i, code); ++ gs_sprintf(buf, "dup %d %u -| ", i, code); + stream_puts(s, buf); + write_CharString(s, stripped, code); + gs_free_object(pfont->memory, stripped, "free Subrs copy for OtherSubrs"); + } else { +- sprintf(buf, "dup %d %u -| ", i, gdata.bits.size); ++ gs_sprintf(buf, "dup %d %u -| ", i, gdata.bits.size); + stream_puts(s, buf); + write_CharString(s, gdata.bits.data, gdata.bits.size); + } +diff -up ghostscript-9.07/base/gdevpsf2.c.gs_sprintf ghostscript-9.07/base/gdevpsf2.c +--- ghostscript-9.07/base/gdevpsf2.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevpsf2.c 2013-05-09 17:02:39.076447128 +0100 +@@ -274,7 +274,7 @@ cff_put_real(cff_writer_t *pcw, floatp f + byte b = 0xff; + const char *p; + +- sprintf(str, "%g", f); ++ gs_sprintf(str, "%g", f); + sputc(pcw->strm, CD_REAL); + for (p = str; ; ++p) { + int digit; +diff -up ghostscript-9.07/base/gdevsppr.c.gs_sprintf ghostscript-9.07/base/gdevsppr.c +--- ghostscript-9.07/base/gdevsppr.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevsppr.c 2013-05-09 17:02:39.076447128 +0100 +@@ -100,7 +100,7 @@ err_code_string(int err_code) + { + if ((err_codeESERIAL)) + { +- sprintf(err_buffer,"err_code out of range: %d",err_code); ++ gs_sprintf(err_buffer,"err_code out of range: %d",err_code); + return err_buffer; + } + return errmsg[err_code]; +diff -up ghostscript-9.07/base/gdevsun.c.gs_sprintf ghostscript-9.07/base/gdevsun.c +--- ghostscript-9.07/base/gdevsun.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevsun.c 2013-05-09 17:02:39.076447128 +0100 +@@ -392,7 +392,7 @@ if ( gs_debug['X'] ) + /* + * Install the colormap. + */ +- sprintf(xdev->cmsname, "%s-%d", CMSNAME, getpid()); ++ gs_sprintf(xdev->cmsname, "%s-%d", CMSNAME, getpid()); + pw_setcmsname(xdev->pw, xdev->cmsname); + pw_putcolormap(xdev->pw, 0, CMS_SIZE, + xdev->red, xdev->green, xdev->blue); +diff -up ghostscript-9.07/base/gdevsvg.c.gs_sprintf ghostscript-9.07/base/gdevsvg.c +--- ghostscript-9.07/base/gdevsvg.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevsvg.c 2013-05-09 17:02:39.076447128 +0100 +@@ -374,22 +374,22 @@ svg_write_header(gx_device_svg *svg) + return 1; + + /* write the initial boilerplate */ +- sprintf(line, "%s\n", XML_DECL); ++ gs_sprintf(line, "%s\n", XML_DECL); + /* svg_write(svg, line); */ + sputs(s, (byte *)line, strlen(line), &used); +- sprintf(line, "%s\n", SVG_DOCTYPE); ++ gs_sprintf(line, "%s\n", SVG_DOCTYPE); + /* svg_write(svg, line); */ + sputs(s, (byte *)line, strlen(line), &used); +- sprintf(line, "\n", ++ gs_sprintf(line, "\n\twidth='%dpt' height='%dpt'>\n", + (int)svg->MediaSize[0], (int)svg->MediaSize[1]); + sputs(s, (byte *)line, strlen(line), &used); + + /* Scale drawing so our coordinates are in pixels */ +- sprintf(line, "\n", ++ gs_sprintf(line, "\n", + 72.0 / svg->HWResolution[0], + 72.0 / svg->HWResolution[1]); + /* svg_write(svg, line); */ +@@ -430,19 +430,19 @@ svg_write_state(gx_device_svg *svg) + /* write out the new current state */ + svg_write(svg, "strokecolor != gx_no_color_index) { +- sprintf(line, " stroke='#%06x'", svg->strokecolor & 0xffffffL); ++ gs_sprintf(line, " stroke='#%06x'", svg->strokecolor & 0xffffffL); + svg_write(svg, line); + } else { + svg_write(svg, " stroke='none'"); + } + if (svg->fillcolor != gx_no_color_index) { +- sprintf(line, "#%06x", svg->fillcolor & 0xffffffL); ++ gs_sprintf(line, "#%06x", svg->fillcolor & 0xffffffL); + svg_write(svg, line); + } else { + svg_write(svg, " fill='none'"); + } + if (svg->linewidth != 1.0) { +- sprintf(line, " stroke-width='%lf'", svg->linewidth); ++ gs_sprintf(line, " stroke-width='%lf'", svg->linewidth); + svg_write(svg, line); + } + if (svg->linecap != SVG_DEFAULT_LINECAP) { +@@ -476,7 +476,7 @@ svg_write_state(gx_device_svg *svg) + } + } + if (svg->miterlimit != SVG_DEFAULT_MITERLIMIT) { +- sprintf(line, " stroke-miterlimit='%lf'", svg->miterlimit); ++ gs_sprintf(line, " stroke-miterlimit='%lf'", svg->miterlimit); + svg_write(svg, line); + } + svg_write(svg, ">\n"); +@@ -653,7 +653,7 @@ svg_dorect(gx_device_vector *vdev, fixed + svg_write(svg, "\n"); + } + +- sprintf(line, "memory, "\n"); + +- sprintf(line, " M%lf,%lf", x, y); ++ gs_sprintf(line, " M%lf,%lf", x, y); + svg_write(svg, line); + + return 0; +@@ -739,7 +739,7 @@ svg_lineto(gx_device_vector *vdev, float + svg_print_path_type(svg, type); + if_debug0m('_', svg->memory, "\n"); + +- sprintf(line, " L%lf,%lf", x, y); ++ gs_sprintf(line, " L%lf,%lf", x, y); + svg_write(svg, line); + + return 0; +@@ -766,7 +766,7 @@ svg_curveto(gx_device_vector *vdev, floa + svg_print_path_type(svg, type); + if_debug0m('_', svg->memory, "\n"); + +- sprintf(line, " C%lf,%lf %lf,%lf %lf,%lf", x1,y1, x2,y2, x3,y3); ++ gs_sprintf(line, " C%lf,%lf %lf,%lf %lf,%lf", x1,y1, x2,y2, x3,y3); + svg_write(svg, line); + + return 0; +diff -up ghostscript-9.07/base/gdevtifs.c.gs_sprintf ghostscript-9.07/base/gdevtifs.c +--- ghostscript-9.07/base/gdevtifs.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevtifs.c 2013-05-09 17:02:39.077447132 +0100 +@@ -500,7 +500,7 @@ int tiff_set_fields_for_printer(gx_devic + + strncpy(softwareValue, gs_product, maxSoftware); + softwareValue[maxSoftware - 1] = 0; +- sprintf(revs, " %1.2f", gs_revision / 100.0); ++ gs_sprintf(revs, " %1.2f", gs_revision / 100.0); + strncat(softwareValue, revs, + maxSoftware - strlen(softwareValue) - 1); + +@@ -513,7 +513,7 @@ int tiff_set_fields_for_printer(gx_devic + + time(&t); + tms = *localtime(&t); +- sprintf(dateTimeValue, "%04d:%02d:%02d %02d:%02d:%02d", ++ gs_sprintf(dateTimeValue, "%04d:%02d:%02d %02d:%02d:%02d", + tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec); + +diff -up ghostscript-9.07/base/gdevtsep.c.gs_sprintf ghostscript-9.07/base/gdevtsep.c +--- ghostscript-9.07/base/gdevtsep.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevtsep.c 2013-05-09 17:02:39.077447132 +0100 +@@ -1182,9 +1182,9 @@ tiffsep1_prn_close(gx_device * pdev) + while (*fmt != 'l' && *fmt != '%') + --fmt; + if (*fmt == 'l') +- sprintf(compname, parsed.fname, count1); ++ gs_sprintf(compname, parsed.fname, count1); + else +- sprintf(compname, parsed.fname, (int)count1); ++ gs_sprintf(compname, parsed.fname, (int)count1); + parsed.iodev->procs.delete_file(parsed.iodev, compname); + } else { + parsed.iodev->procs.delete_file(parsed.iodev, tfdev->fname); +@@ -1370,7 +1370,7 @@ create_separation_file_name(tiffsep_devi + /* Max of 10 chars in %d format */ + if (max_size < base_filename_length + 11) + return_error(gs_error_rangecheck); +- sprintf(buffer + base_filename_length, "s%d", sep_num); ++ gs_sprintf(buffer + base_filename_length, "s%d", sep_num); + } + } + if (use_sep_name) +@@ -2385,9 +2385,9 @@ tiffsep1_print_page(gx_device_printer * + while (*fmt != 'l' && *fmt != '%') + --fmt; + if (*fmt == 'l') +- sprintf(compname, parsed.fname, count1); ++ gs_sprintf(compname, parsed.fname, count1); + else +- sprintf(compname, parsed.fname, (int)count1); ++ gs_sprintf(compname, parsed.fname, (int)count1); + parsed.iodev->procs.delete_file(parsed.iodev, compname); + /* we always need an open printer (it will get deleted in tiffsep1_prn_close */ + if ((code = gdev_prn_open_printer((gx_device *)pdev, 1)) < 0) +diff -up ghostscript-9.07/base/gdevtxtw.c.gs_sprintf ghostscript-9.07/base/gdevtxtw.c +--- ghostscript-9.07/base/gdevtxtw.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevtxtw.c 2013-05-09 17:02:39.078447137 +0100 +@@ -633,16 +633,16 @@ static int escaped_Unicode (unsigned sho + { + switch (Unicode) + { +- case 0x3C: sprintf(Buf, "<"); break; +- case 0x3E: sprintf(Buf, ">"); break; +- case 0x26: sprintf(Buf, "&"); break; +- case 0x22: sprintf(Buf, """); break; +- case 0x27: sprintf(Buf, "'"); break; ++ case 0x3C: gs_sprintf(Buf, "<"); break; ++ case 0x3E: gs_sprintf(Buf, ">"); break; ++ case 0x26: gs_sprintf(Buf, "&"); break; ++ case 0x22: gs_sprintf(Buf, """); break; ++ case 0x27: gs_sprintf(Buf, "'"); break; + default: + if (Unicode >= 32 && Unicode <= 127) +- sprintf(Buf, "%c", Unicode); ++ gs_sprintf(Buf, "%c", Unicode); + else +- sprintf(Buf, "&#x%x;", Unicode); ++ gs_sprintf(Buf, "&#x%x;", Unicode); + break; + } + +@@ -665,13 +665,13 @@ static int decorated_text_output(gx_devi + x_entry = tdev->PageData.unsorted_text_list; + while (x_entry) { + next_x = x_entry->next; +- sprintf(TextBuffer, "\n", x_entry->start.x, x_entry->start.y, ++ gs_sprintf(TextBuffer, "\n", x_entry->start.x, x_entry->start.y, + x_entry->end.x, x_entry->end.y, x_entry->FontName,x_entry->size); + fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file); + xpos = x_entry->start.x; + for (i=0;iUnicode_Text_Size;i++) { + escaped_Unicode(x_entry->Unicode_Text[i], (char *)&Escaped); +- sprintf(TextBuffer, "\n", xpos, ++ gs_sprintf(TextBuffer, "\n", xpos, + x_entry->start.y, xpos + x_entry->Widths[i], x_entry->end.y, Escaped); + fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file); + xpos += x_entry->Widths[i]; +@@ -788,13 +788,13 @@ static int decorated_text_output(gx_devi + fwrite("\n", sizeof(unsigned char), 7, tdev->file); + x_entry = block_line->x_ordered_list; + while(x_entry) { +- sprintf(TextBuffer, "\n", x_entry->start.x, x_entry->start.y, ++ gs_sprintf(TextBuffer, "\n", x_entry->start.x, x_entry->start.y, + x_entry->end.x, x_entry->end.y, x_entry->FontName,x_entry->size); + fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file); + xpos = x_entry->start.x; + for (i=0;iUnicode_Text_Size;i++) { + escaped_Unicode(x_entry->Unicode_Text[i], (char *)&Escaped); +- sprintf(TextBuffer, "\n", xpos, ++ gs_sprintf(TextBuffer, "\n", xpos, + x_entry->start.y, xpos + x_entry->Widths[i], x_entry->end.y, Escaped); + fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file); + xpos += x_entry->Widths[i]; +diff -up ghostscript-9.07/base/gdevupd.c.gs_sprintf ghostscript-9.07/base/gdevupd.c +--- ghostscript-9.07/base/gdevupd.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevupd.c 2013-05-09 17:02:39.079447141 +0100 +@@ -6476,7 +6476,7 @@ upd_open_wrtrtl(upd_device *udev) + if( (B_PAGEWIDTH & upd->flags) && + ((c == 0x73) || (c == 0x53)) ) { /* esc * r # S */ + +- sprintf(cv,"%d",upd->pwidth); ++ gs_sprintf(cv,"%d",upd->pwidth); + ncv = strlen(cv); + + nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i); +@@ -6494,7 +6494,7 @@ upd_open_wrtrtl(upd_device *udev) + } else if((B_PAGELENGTH & upd->flags) && + ((c == 0x74) || (c == 0x54)) ) { /* esc * r # T */ + +- sprintf(cv,"%d",upd->pheight); ++ gs_sprintf(cv,"%d",upd->pheight); + ncv = strlen(cv); + + nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i); +@@ -6523,7 +6523,7 @@ upd_open_wrtrtl(upd_device *udev) + if( (B_RESOLUTION & upd->flags) && + ((c == 0x72) || (c == 0x52)) ) { /* esc * t # R */ + +- sprintf(cv,"%d",(int) ++ gs_sprintf(cv,"%d",(int) + ((udev->y_pixels_per_inch < udev->x_pixels_per_inch ? + udev->x_pixels_per_inch : udev->y_pixels_per_inch) + +0.5)); +@@ -6730,7 +6730,7 @@ upd_open_wrtrtl(upd_device *udev) + + if(B_PAGELENGTH & upd->flags) { /* insert new number */ + +- sprintf(cv,"%d",(int) ++ gs_sprintf(cv,"%d",(int) + (720.0 * udev->height / udev->y_pixels_per_inch + 0.5)); + ncv = strlen(cv); + +@@ -6795,7 +6795,7 @@ upd_open_wrtrtl(upd_device *udev) + + if(B_PAGEWIDTH & upd->flags) { /* insert new number */ + +- sprintf(cv,"%d",(int) ++ gs_sprintf(cv,"%d",(int) + (720.0 * udev->width / udev->x_pixels_per_inch + 0.5)); + ncv = strlen(cv); + +@@ -6890,7 +6890,7 @@ upd_open_wrtrtl(upd_device *udev) + + if(B_RESOLUTION & upd->flags) { /* insert new number */ + +- sprintf(cv,"%d",(int) ++ gs_sprintf(cv,"%d",(int) + ((udev->y_pixels_per_inch < udev->x_pixels_per_inch ? + udev->x_pixels_per_inch : udev->y_pixels_per_inch) + +0.5)); +@@ -6945,7 +6945,7 @@ It must hold: + char tmp[16]; + + if(0 < upd->strings[S_YMOVE].size) { +- sprintf(tmp,"%d",upd->pheight); ++ gs_sprintf(tmp,"%d",upd->pheight); + ny = upd->strings[S_YMOVE].size + strlen(tmp); + } else { + ny = 1 + upd->string_a[SA_WRITECOMP].data[upd->ocomp-1].size; +@@ -7006,14 +7006,14 @@ upd_wrtrtl(upd_p upd, FILE *out) + */ + if(upd->yscan != upd->yprinter) { /* Adjust Y-Position */ + if(1 < upd->strings[S_YMOVE].size) { +- sprintf((char *)upd->outbuf+ioutbuf, ++ gs_sprintf((char *)upd->outbuf+ioutbuf, + (const char *) upd->strings[S_YMOVE].data, + upd->yscan - upd->yprinter); + ioutbuf += strlen((char *)upd->outbuf+ioutbuf); + } else { + while(upd->yscan > upd->yprinter) { + for(icomp = 0; icomp < upd->ocomp; ++icomp) { +- sprintf((char *)upd->outbuf+ioutbuf, ++ gs_sprintf((char *)upd->outbuf+ioutbuf, + (const char *) upd->string_a[SA_WRITECOMP].data[icomp].data,0); + ioutbuf += strlen((char *)upd->outbuf+ioutbuf); + } +diff -up ghostscript-9.07/base/gdevwpr2.c.gs_sprintf ghostscript-9.07/base/gdevwpr2.c +--- ghostscript-9.07/base/gdevwpr2.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevwpr2.c 2013-05-09 17:02:39.080447145 +0100 +@@ -548,7 +548,7 @@ win_pr2_print_page(gx_device_printer * p + } + + if (!wdev->nocancel) { +- sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount) + 1); ++ gs_sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount) + 1); + SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PRINTING), dlgtext); + ShowWindow(wdev->hDlgModeless, SW_SHOW); + } +@@ -577,7 +577,7 @@ win_pr2_print_page(gx_device_printer * p + + if (!wdev->nocancel) { + /* inform user of progress */ +- sprintf(dlgtext, "%d%% done", (int)(y * 100L / scan_lines)); ++ gs_sprintf(dlgtext, "%d%% done", (int)(y * 100L / scan_lines)); + SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE), dlgtext); + } + /* process message loop */ +@@ -1488,9 +1488,9 @@ win_pr2_print_setup_interaction(gx_devic + + wdev->user_changed_settings = TRUE; + if (wdev->use_old_spool_name) { +- sprintf(wdev->fname, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset)); ++ gs_sprintf(wdev->fname, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset)); + } else { +- sprintf(wdev->fname, "%%printer%%%s", (char*)(devnames)+(devnames->wDeviceOffset)); ++ gs_sprintf(wdev->fname, "%%printer%%%s", (char*)(devnames)+(devnames->wDeviceOffset)); + } + + if (mode == 3) { +diff -up ghostscript-9.07/base/gdevxini.c.gs_sprintf ghostscript-9.07/base/gdevxini.c +--- ghostscript-9.07/base/gdevxini.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gdevxini.c 2013-05-09 17:02:39.080447145 +0100 +@@ -377,7 +377,7 @@ gdev_x_open(gx_device_X * xdev) + char gstr[40]; + int bitmask; + +- sprintf(gstr, "%dx%d+%d+%d", sizehints.width, ++ gs_sprintf(gstr, "%dx%d+%d+%d", sizehints.width, + sizehints.height, sizehints.x, sizehints.y); + bitmask = XWMGeometry(xdev->dpy, DefaultScreen(xdev->dpy), + xdev->geometry, gstr, xdev->borderWidth, +diff -up ghostscript-9.07/base/gp_macio.c.gs_sprintf ghostscript-9.07/base/gp_macio.c +--- ghostscript-9.07/base/gp_macio.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gp_macio.c 2013-05-09 17:02:39.080447145 +0100 +@@ -162,7 +162,7 @@ getenv(const char * env) { + convertSpecToPath(&pFile, fpath, 256); + // sprintf(fpath,"%s",fpath); + p = (char*)malloc((size_t) ( 4*strlen(fpath) + 40)); +- sprintf(p,"%s,%sGhostscript:lib,%sGhostscript:fonts", ++ gs_sprintf(p,"%s,%sGhostscript:lib,%sGhostscript:fonts", + (char *)&fpath[0],(char *)&fpath[0], + (char *)&fpath[0] ); + +@@ -402,9 +402,9 @@ gp_open_scratch_file (const gs_memory_t + } + FSMakeFSSpec(foundVRefNum, foundDirID,thepfname, &fSpec); + convertSpecToPath(&fSpec, thefname, sizeof(thefname) - 1); +- sprintf(fname,"%s",thefname); ++ gs_sprintf(fname,"%s",thefname); + } else { +- sprintf((char*)&thefname[0],"%s\0",fname); ++ gs_sprintf((char*)&thefname[0],"%s\0",fname); + memmove((char*)&thepfname[1],(char *)&thefname[0],strlen(thefname)); + thepfname[0]=strlen(thefname); + } +@@ -535,9 +535,9 @@ gp_fopen (const char * fname, const char + //(*pgsdll_callback) (GSDLL_STDOUT, thefname, strlen(fname)); + if ( strrchr(fname,':') == NULL ) + // sprintf((char *)&thefname[0],"%s%s\0",g_homeDir,fname); +- sprintf((char *)&thefname[0],"%s%s\0","",fname); ++ gs_sprintf((char *)&thefname[0],"%s%s\0","",fname); + else +- sprintf((char*)&thefname[0],"%s\0",fname); ++ gs_sprintf((char*)&thefname[0],"%s\0",fname); + + fid = fopen(thefname,mode); + +diff -up ghostscript-9.07/base/gp_mswin.c.gs_sprintf ghostscript-9.07/base/gp_mswin.c +--- ghostscript-9.07/base/gp_mswin.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gp_mswin.c 2013-05-09 17:02:39.081447150 +0100 +@@ -316,7 +316,7 @@ get_queues(void) + char buf[256]; + + free(enumbuffer); +- sprintf(buf, "EnumPrinters() failed, error code = %d", GetLastError()); ++ gs_sprintf(buf, "EnumPrinters() failed, error code = %d", GetLastError()); + MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); + return NULL; + } +@@ -423,7 +423,7 @@ gp_printfile_win32(const char *filename, + if (!gp_OpenPrinter(port, &printer)) { + char buf[256]; + +- sprintf(buf, "OpenPrinter() failed for \042%s\042, error code = %d", port, GetLastError()); ++ gs_sprintf(buf, "OpenPrinter() failed for \042%s\042, error code = %d", port, GetLastError()); + MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); + free(buffer); + return FALSE; +@@ -436,7 +436,7 @@ gp_printfile_win32(const char *filename, + if (!StartDocPrinter(printer, 1, (LPBYTE) & di)) { + char buf[256]; + +- sprintf(buf, "StartDocPrinter() failed, error code = %d", GetLastError()); ++ gs_sprintf(buf, "StartDocPrinter() failed, error code = %d", GetLastError()); + MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); + AbortPrinter(printer); + free(buffer); +@@ -457,7 +457,7 @@ gp_printfile_win32(const char *filename, + if (!EndDocPrinter(printer)) { + char buf[256]; + +- sprintf(buf, "EndDocPrinter() failed, error code = %d", GetLastError()); ++ gs_sprintf(buf, "EndDocPrinter() failed, error code = %d", GetLastError()); + MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); + AbortPrinter(printer); + return FALSE; +@@ -465,7 +465,7 @@ gp_printfile_win32(const char *filename, + if (!ClosePrinter(printer)) { + char buf[256]; + +- sprintf(buf, "ClosePrinter() failed, error code = %d", GetLastError()); ++ gs_sprintf(buf, "ClosePrinter() failed, error code = %d", GetLastError()); + MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); + return FALSE; + } +diff -up ghostscript-9.07/base/gp_wgetv.c.gs_sprintf ghostscript-9.07/base/gp_wgetv.c +--- ghostscript-9.07/base/gp_wgetv.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gp_wgetv.c 2013-05-09 17:02:39.081447150 +0100 +@@ -181,9 +181,9 @@ gp_getenv(const char *name, char *ptr, i + char key[256]; + char dotversion[16]; + +- sprintf(dotversion, "%d.%02d", (int)(gs_revision / 100), ++ gs_sprintf(dotversion, "%d.%02d", (int)(gs_revision / 100), + (int)(gs_revision % 100)); +- sprintf(key, "Software\\%s\\%s", gs_productfamily, dotversion); ++ gs_sprintf(key, "Software\\%s\\%s", gs_productfamily, dotversion); + #else + wchar_t key[256]; + wchar_t dotversion[16]; +@@ -224,7 +224,7 @@ gp_serialnumber(void) + #ifdef WINDOWS_NO_UNICODE + char key[256]; + +- sprintf(key, "Software\\Microsoft\\MSLicensing\\HardwareID"); ++ gs_sprintf(key, "Software\\Microsoft\\MSLicensing\\HardwareID"); + #else /* WINDOWS_NO_UNICODE */ + wchar_t key[256]; + +diff -up ghostscript-9.07/base/gsalloc.c.gs_sprintf ghostscript-9.07/base/gsalloc.c +--- ghostscript-9.07/base/gsalloc.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gsalloc.c 2013-05-09 17:02:39.081447150 +0100 +@@ -2045,7 +2045,7 @@ debug_dump_contents(const gs_memory_t *m + } + continue; + } +- sprintf(label, "0x%lx:", (ulong) block); ++ gs_sprintf(label, "0x%lx:", (ulong) block); + debug_indent(mem, indent); + dmputs(mem, label); + for (i = 0; i < block_size; ++i) { +diff -up ghostscript-9.07/base/gsdevice.c.gs_sprintf ghostscript-9.07/base/gsdevice.c +--- ghostscript-9.07/base/gsdevice.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gsdevice.c 2013-05-09 17:02:39.082447154 +0100 +@@ -1011,11 +1011,11 @@ gx_device_open_output_file(const gx_devi + while (*fmt != 'l' && *fmt != '%') + --fmt; + if (*fmt == 'l') +- sprintf(pfname, parsed.fname, count1); ++ gs_sprintf(pfname, parsed.fname, count1); + else +- sprintf(pfname, parsed.fname, (int)count1); ++ gs_sprintf(pfname, parsed.fname, (int)count1); + } else if (parsed.len && strchr(parsed.fname, '%')) /* filename with "%%" but no "%nnd" */ +- sprintf(pfname, parsed.fname); ++ gs_sprintf(pfname, parsed.fname); + else + pfname[0] = 0; /* 0 to use "fname", not "pfname" */ + if (pfname[0]) { +diff -up ghostscript-9.07/base/gsdparam.c.gs_sprintf ghostscript-9.07/base/gsdparam.c +--- ghostscript-9.07/base/gsdparam.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gsdparam.c 2013-05-09 17:02:39.082447154 +0100 +@@ -377,7 +377,7 @@ gdev_write_input_media(int index, gs_par + int code; + gs_param_string as; + +- sprintf(key, "%d", index); ++ gs_sprintf(key, "%d", index); + mdict.size = 4; + code = param_begin_write_dict(pdict->list, key, &mdict, false); + if (code < 0) +@@ -465,7 +465,7 @@ gdev_write_output_media(int index, gs_pa + gs_param_dict mdict; + int code; + +- sprintf(key, "%d", index); ++ gs_sprintf(key, "%d", index); + mdict.size = 4; + code = param_begin_write_dict(pdict->list, key, &mdict, false); + if (code < 0) +diff -up ghostscript-9.07/base/gsfcmap.c.gs_sprintf ghostscript-9.07/base/gsfcmap.c +--- ghostscript-9.07/base/gsfcmap.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gsfcmap.c 2013-05-09 17:02:39.082447154 +0100 +@@ -567,7 +567,7 @@ gs_cmap_ToUnicode_alloc(gs_memory_t *mem + char sid[10], *pref = "aux-"; + int sid_len, pref_len = strlen(pref); + +- sprintf(sid, "%d", id); ++ gs_sprintf(sid, "%d", id); + sid_len = strlen(sid); + name_len = pref_len + sid_len; + cmap_name = gs_alloc_string(mem, name_len, "gs_cmap_ToUnicode_alloc"); +diff -up ghostscript-9.07/base/gsicc_create.c.gs_sprintf ghostscript-9.07/base/gsicc_create.c +--- ghostscript-9.07/base/gsicc_create.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gsicc_create.c 2013-05-09 17:02:39.083447158 +0100 +@@ -451,7 +451,7 @@ save_profile(unsigned char *buffer, char + char full_file_name[50]; + FILE *fid; + +- sprintf(full_file_name,"%d)Profile_%s.icc",icc_debug_index,filename); ++ gs_sprintf(full_file_name,"%d)Profile_%s.icc",icc_debug_index,filename); + fid = fopen(full_file_name,"wb"); + fwrite(buffer,sizeof(unsigned char),buffer_size,fid); + fclose(fid); +diff -up ghostscript-9.07/base/gsicc_manage.c.gs_sprintf ghostscript-9.07/base/gsicc_manage.c +--- ghostscript-9.07/base/gsicc_manage.c.gs_sprintf 2013-05-09 17:02:39.043446986 +0100 ++++ ghostscript-9.07/base/gsicc_manage.c 2013-05-09 17:02:39.083447158 +0100 +@@ -550,8 +550,8 @@ gsicc_set_srcgtag_struct(gsicc_manager_t + srcgtag = gsicc_new_srcgtag_profile(mem); + /* Now parse through the data opening the profiles that are needed */ + /* First create the format that we should read for the key */ +- sprintf(str_format_key, "%%%ds", GSICC_SRCGTAG_MAX_KEY); +- sprintf(str_format_file, "%%%ds", FILENAME_MAX); ++ gs_sprintf(str_format_key, "%%%ds", GSICC_SRCGTAG_MAX_KEY); ++ gs_sprintf(str_format_file, "%%%ds", FILENAME_MAX); + curr_ptr = buffer_ptr; + /* Initialize that we want color management. Then if profile is not + present we know we did not want anything special done with that +@@ -1296,13 +1296,13 @@ gsicc_set_device_profile_colorants(gx_de + DEFAULT_ICC_PROCESS_LENGTH - 1; /* -1 due to no comma at end */ + name_str = (char*) gs_alloc_bytes(dev->memory, total_len+1, + "gsicc_set_device_profile_colorants"); +- sprintf(name_str, DEFAULT_ICC_PROCESS); ++ gs_sprintf(name_str, DEFAULT_ICC_PROCESS); + for (kk = 0; kk < num_comps-5; kk++) { +- sprintf(temp_str,"ICC_COLOR_%d,",kk); ++ gs_sprintf(temp_str,"ICC_COLOR_%d,",kk); + strcat(name_str,temp_str); + } + /* Last one no comma */ +- sprintf(temp_str,"ICC_COLOR_%d",kk); ++ gs_sprintf(temp_str,"ICC_COLOR_%d",kk); + strcat(name_str,temp_str); + } + str_len = strlen(name_str); +@@ -2344,7 +2344,7 @@ dump_icc_buffer(int buffersize, char fil + char full_file_name[50]; + FILE *fid; + +- sprintf(full_file_name,"%d)%s_debug.icc",global_icc_index,filename); ++ gs_sprintf(full_file_name,"%d)%s_debug.icc",global_icc_index,filename); + fid = fopen(full_file_name,"wb"); + fwrite(Buffer,sizeof(unsigned char),buffersize,fid); + fclose(fid); +diff -up ghostscript-9.07/base/gsiodisk.c.gs_sprintf ghostscript-9.07/base/gsiodisk.c +--- ghostscript-9.07/base/gsiodisk.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gsiodisk.c 2013-05-09 17:02:39.084447162 +0100 +@@ -415,7 +415,7 @@ MapFileOpen(const char * rootpath, const + + if (strlen(rootpath) + strlen(filename) >= BUFFER_LENGTH) + return NULL; +- sprintf(fullname, "%s%s", rootpath, filename); ++ gs_sprintf(fullname, "%s%s", rootpath, filename); + return gp_fopen(fullname, attributes); + } + +@@ -516,7 +516,7 @@ MapFileUnlink(const char * rootpath, con + + if (strlen(rootpath) + strlen(filename) >= BUFFER_LENGTH) + return; +- sprintf(fullname, "%s%s", rootpath, filename); ++ gs_sprintf(fullname, "%s%s", rootpath, filename); + unlink(fullname); + } + +@@ -537,8 +537,8 @@ MapFileRename(const char * rootpath, con + return; + if (strlen(rootpath) + strlen(newfilename) >= BUFFER_LENGTH) + return; +- sprintf(oldfullname, "%s%s", rootpath, oldfilename); +- sprintf(newfullname, "%s%s", rootpath, newfilename); ++ gs_sprintf(oldfullname, "%s%s", rootpath, oldfilename); ++ gs_sprintf(newfullname, "%s%s", rootpath, newfilename); + rename(oldfullname, newfullname); + } + +@@ -711,7 +711,7 @@ map_file_name_get(const char * root_name + if (d != -1) { + /* 20 characters are enough for even a 64 bit integer */ + if ((strlen(root_name) + 20) < BUFFER_LENGTH) { +- sprintf(osname, "%s%d", root_name, d); ++ gs_sprintf(osname, "%s%d", root_name, d); + return true; + } + } +diff -up ghostscript-9.07/base/gs.mak.gs_sprintf ghostscript-9.07/base/gs.mak +--- ghostscript-9.07/base/gs.mak.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gs.mak 2013-05-09 17:02:39.084447162 +0100 +@@ -239,6 +239,8 @@ LCUPSGENDIR=$(GLGENDIR) + LCUPSOBJDIR=$(GLOBJDIR) + LCUPSIGENDIR=$(GLGENDIR) + LCUPSIOBJDIR=$(GLOBJDIR) ++ ++TRIOOBJDIR=$(GLOBJDIR) + #**************** END PATCHES + + GSGEN=$(GLGENDIR)$(D) +diff -up ghostscript-9.07/base/gspmdrv.c.gs_sprintf ghostscript-9.07/base/gspmdrv.c +--- ghostscript-9.07/base/gspmdrv.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gspmdrv.c 2013-05-09 17:02:39.084447162 +0100 +@@ -345,11 +345,11 @@ write_profile(void) + { + char profile[64]; + +- sprintf(profile, "%d %d", option.img_origin.x, option.img_origin.y); ++ gs_sprintf(profile, "%d %d", option.img_origin.x, option.img_origin.y); + PrfWriteProfileString(HINI_USERPROFILE, section, "Origin", profile); +- sprintf(profile, "%d %d", option.img_size.x, option.img_size.y); ++ gs_sprintf(profile, "%d %d", option.img_size.x, option.img_size.y); + PrfWriteProfileString(HINI_USERPROFILE, section, "Size", profile); +- sprintf(profile, "%d", option.img_max); ++ gs_sprintf(profile, "%d", option.img_max); + PrfWriteProfileString(HINI_USERPROFILE, section, "Maximized", profile); + } + +@@ -489,26 +489,26 @@ init_display(int argc, char *argv[]) + find_hwnd_gs(argv[2]); + + if (!rc) { +- sprintf(name, SHARED_NAME, argv[2]); ++ gs_sprintf(name, SHARED_NAME, argv[2]); + rc = DosGetNamedSharedMem((PVOID *) & bitmap.pbmi, name, PAG_READ | PAG_WRITE); + if (rc) { +- sprintf(buf, "Failed to open: bmp shared memory \"%s\" rc = %d", argv[0], rc); ++ gs_sprintf(buf, "Failed to open: bmp shared memory \"%s\" rc = %d", argv[0], rc); + error_message(buf); + } + } + if (!rc) { +- sprintf(name, SYNC_NAME, argv[2]); ++ gs_sprintf(name, SYNC_NAME, argv[2]); + rc = DosOpenEventSem(name, &update_event_sem); + if (rc) { +- sprintf(buf, "Failed to open: update event semaphore \"%s\" rc = %d", argv[1], rc); ++ gs_sprintf(buf, "Failed to open: update event semaphore \"%s\" rc = %d", argv[1], rc); + error_message(buf); + } + } + if (!rc) { +- sprintf(name, MUTEX_NAME, argv[2]); ++ gs_sprintf(name, MUTEX_NAME, argv[2]); + rc = DosOpenMutexSem(name, &bmp_mutex_sem); + if (rc) { +- sprintf(buf, "Failed to open: bmp mutex semaphore \"%s\" rc = %d", argv[1], rc); ++ gs_sprintf(buf, "Failed to open: bmp mutex semaphore \"%s\" rc = %d", argv[1], rc); + error_message(buf); + } + } +@@ -535,19 +535,19 @@ init_bitmap(int argc, char *argv[]) + if ((rc = DosOpen(argv[2], &hf, &action, 0, FILE_NORMAL, FILE_OPEN, + OPEN_ACCESS_READONLY | OPEN_SHARE_DENYREADWRITE, 0)) + != (APIRET) 0) { +- sprintf(buf, "Error opening: %s", argv[2]); ++ gs_sprintf(buf, "Error opening: %s", argv[2]); + error_message(buf); + return rc; + } + rc = DosSetFilePtr(hf, 0, FILE_END, &length); + if (rc) { +- sprintf(buf, "failed seeking to EOF: error = %d", rc); ++ gs_sprintf(buf, "failed seeking to EOF: error = %d", rc); + error_message(buf); + return rc; + } + rc = DosSetFilePtr(hf, 0, FILE_BEGIN, &count); + if (rc) { +- sprintf(buf, "failed seeking to BOF: error = %d", rc); ++ gs_sprintf(buf, "failed seeking to BOF: error = %d", rc); + error_message(buf); + return rc; + }; +@@ -555,14 +555,14 @@ init_bitmap(int argc, char *argv[]) + /* allocate memory for bitmap */ + if ((rc = DosAllocMem((PPVOID) & bbuffer, length, PAG_READ | PAG_WRITE | PAG_COMMIT)) + != (APIRET) 0) { +- sprintf(buf, "failed allocating memory"); ++ gs_sprintf(buf, "failed allocating memory"); + error_message(buf); + return rc; + } + rc = DosRead(hf, bbuffer, length, &count); + DosClose(hf); + if (rc) { +- sprintf(buf, "failed reading bitmap, error = %u, count = %u", rc, count); ++ gs_sprintf(buf, "failed reading bitmap, error = %u, count = %u", rc, count); + error_message(buf); + return rc; + } +@@ -573,7 +573,7 @@ init_bitmap(int argc, char *argv[]) + scan_bitmap(&bitmap); + bitmap.valid = TRUE; + +- sprintf(buf, "bitmap width = %d, height = %d", bitmap.width, bitmap.height); ++ gs_sprintf(buf, "bitmap width = %d, height = %d", bitmap.width, bitmap.height); + message_box(buf, 0); + return rc; + } +@@ -805,7 +805,7 @@ make_bitmap(BMAP * pbm, ULONG left, ULON + char buf[256]; + + eid = WinGetLastError(hab); +- sprintf(buf, "make_bitmap: GpiDrawBits rc = %08x, eid = %08x", rc, eid); ++ gs_sprintf(buf, "make_bitmap: GpiDrawBits rc = %08x, eid = %08x", rc, eid); + message_box(buf, 0); + } + } +diff -up ghostscript-9.07/base/gssprintf.c.gs_sprintf ghostscript-9.07/base/gssprintf.c +--- ghostscript-9.07/base/gssprintf.c.gs_sprintf 2013-05-09 17:02:39.085447167 +0100 ++++ ghostscript-9.07/base/gssprintf.c 2013-05-09 17:02:39.084447162 +0100 +@@ -0,0 +1,60 @@ ++/* Copyright (C) 2001-2012 Artifex Software, Inc. ++ All Rights Reserved. ++ ++ This software is provided AS-IS with no warranty, either express or ++ implied. ++ ++ This software is distributed under license and may not be copied, ++ modified or distributed except as expressly authorized under the terms ++ of the license contained in the file LICENSE in this distribution. ++ ++ Refer to licensing information at http://www.artifex.com or contact ++ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, ++ CA 94903, U.S.A., +1(415)492-9861, for further information. ++*/ ++ ++ ++/* Simple interface to a sprintf/sscanf without locale */ ++#include "gssprintf.h" ++#include "trio.h" ++#include "triop.h" ++#include "triodef.h" ++#include "trionan.h" ++#include "triostr.h" ++ ++int ++gs_vsnprintf(char *buf, int n, const char *format, va_list ap) ++{ ++ return(trio_vsnprintf(buf, n, format, ap)); ++} ++ ++int ++gs_snprintf(char *buf, int n, const char *format, ...) ++{ ++ int len; ++ va_list ap; ++ ++ va_start(ap, format); ++ len = trio_vsnprintf(buf, n, format, ap); ++ va_end(ap); ++ return len; ++} ++ ++int ++gs_vsprintf(char *buf, const char *format, va_list ap) ++{ ++ return(trio_vsprintf(buf, format, ap)); ++} ++ ++int ++gs_sprintf(char *buf, const char *format, ...) ++{ ++ int len; ++ va_list ap; ++ ++ va_start(ap, format); ++ len = trio_vsprintf(buf, format, ap); ++ va_end(ap); ++ ++ return(len); ++} +diff -up ghostscript-9.07/base/gssprintf.h.gs_sprintf ghostscript-9.07/base/gssprintf.h +--- ghostscript-9.07/base/gssprintf.h.gs_sprintf 2013-05-09 17:02:39.085447167 +0100 ++++ ghostscript-9.07/base/gssprintf.h 2013-05-09 17:02:39.085447167 +0100 +@@ -0,0 +1,33 @@ ++/* Copyright (C) 2001-2012 Artifex Software, Inc. ++ All Rights Reserved. ++ ++ This software is provided AS-IS with no warranty, either express or ++ implied. ++ ++ This software is distributed under license and may not be copied, ++ modified or distributed except as expressly authorized under the terms ++ of the license contained in the file LICENSE in this distribution. ++ ++ Refer to licensing information at http://www.artifex.com or contact ++ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, ++ CA 94903, U.S.A., +1(415)492-9861, for further information. ++*/ ++ ++#ifndef gssprintf_INCLUDED ++# define gssprintf_INCLUDED ++ ++#include ++ ++int ++gs_vsnprintf(char *zBuf, int n, const char *zFormat, va_list ap); ++ ++int ++gs_snprintf(char *zBuf, int n, const char *zFormat, ...); ++ ++int ++gs_vsprintf(char *zBuf, const char *zFormat, va_list ap); ++ ++int ++gs_sprintf(char *zBuf, const char *zFormat, ...); ++ ++#endif +diff -up ghostscript-9.07/base/gxblend1.c.gs_sprintf ghostscript-9.07/base/gxblend1.c +--- ghostscript-9.07/base/gxblend1.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gxblend1.c 2013-05-09 17:02:39.085447167 +0100 +@@ -643,7 +643,7 @@ dump_planar_rgba(gs_memory_t *mem, const + info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + + /* add comment */ +- sprintf(software_text, "%s %d.%02d", gs_product, ++ gs_sprintf(software_text, "%s %d.%02d", gs_product, + (int)(gs_revision / 100), (int)(gs_revision % 100)); + text_png.compression = -1; /* uncompressed */ + text_png.key = (char *)software_key; /* not const, unfortunately */ +diff -up ghostscript-9.07/base/gxblend.c.gs_sprintf ghostscript-9.07/base/gxblend.c +--- ghostscript-9.07/base/gxblend.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gxblend.c 2013-05-09 17:02:39.085447167 +0100 +@@ -1573,7 +1573,7 @@ dump_raw_buffer(int num_rows, int width, + /* FIXME: GRAY + ALPHA + SHAPE + TAGS will be interpreted as RGB + ALPHA */ + if ((n_chan == 2) || (n_chan == 3)) { + int x; +- sprintf(full_file_name,"%02d)%s.pam",global_index,filename); ++ gs_sprintf(full_file_name,"%02d)%s.pam",global_index,filename); + fid = fopen(full_file_name,"wb"); + fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE GRAYSCALE_ALPHA\nENDHDR\n", + width, num_rows); +@@ -1583,7 +1583,7 @@ dump_raw_buffer(int num_rows, int width, + fputc(Buffer[z*plane_stride + y*rowstride + x], fid); + fclose(fid); + if (n_chan == 3) { +- sprintf(full_file_name,"%02d)%s_shape.pam",global_index,filename); ++ gs_sprintf(full_file_name,"%02d)%s_shape.pam",global_index,filename); + fid = fopen(full_file_name,"wb"); + fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n", + width, num_rows); +@@ -1595,7 +1595,7 @@ dump_raw_buffer(int num_rows, int width, + } + if ((n_chan == 4) || (n_chan == 5) || (n_chan == 6)) { + int x; +- sprintf(full_file_name,"%02d)%s.pam",global_index,filename); ++ gs_sprintf(full_file_name,"%02d)%s.pam",global_index,filename); + fid = fopen(full_file_name,"wb"); + fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", + width, num_rows); +@@ -1605,7 +1605,7 @@ dump_raw_buffer(int num_rows, int width, + fputc(Buffer[z*plane_stride + y*rowstride + x], fid); + fclose(fid); + if (n_chan > 4) { +- sprintf(full_file_name,"%02d)%s_shape.pam",global_index,filename); ++ gs_sprintf(full_file_name,"%02d)%s_shape.pam",global_index,filename); + fid = fopen(full_file_name,"wb"); + fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n", + width, num_rows); +@@ -1615,7 +1615,7 @@ dump_raw_buffer(int num_rows, int width, + fclose(fid); + } + if (n_chan == 6) { +- sprintf(full_file_name,"%02d)%s_tags.pam",global_index,filename); ++ gs_sprintf(full_file_name,"%02d)%s_tags.pam",global_index,filename); + fid = fopen(full_file_name,"wb"); + fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 1\nMAXVAL 255\nTUPLTYPE GRAYSCALE\nENDHDR\n", + width, num_rows); +@@ -1628,7 +1628,7 @@ dump_raw_buffer(int num_rows, int width, + } + #endif + max_bands = ( n_chan < 57 ? n_chan : 56); /* Photoshop handles at most 56 bands */ +- sprintf(full_file_name,"%02d)%s_%dx%dx%d.raw",global_index,filename,width,num_rows,max_bands); ++ gs_sprintf(full_file_name,"%02d)%s_%dx%dx%d.raw",global_index,filename,width,num_rows,max_bands); + fid = fopen(full_file_name,"wb"); + + for (z = 0; z < max_bands; ++z) { +diff -up ghostscript-9.07/base/gxclmem.c.gs_sprintf ghostscript-9.07/base/gxclmem.c +--- ghostscript-9.07/base/gxclmem.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gxclmem.c 2013-05-09 17:02:39.086447171 +0100 +@@ -401,7 +401,7 @@ memfile_fopen(char fname[gp_file_name_si + + /* Return the address of this memfile as a string for use in future clist_fopen calls */ + fname[0] = 0xff; /* a flag that this is a memfile name */ +- sprintf(fname+1, "%p", f); ++ gs_sprintf(fname+1, "%p", f); + + #ifdef DEBUG + tot_compressed = 0; +diff -up ghostscript-9.07/base/gxhintn.c.gs_sprintf ghostscript-9.07/base/gxhintn.c +--- ghostscript-9.07/base/gxhintn.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gxhintn.c 2013-05-09 17:02:39.086447171 +0100 +@@ -387,7 +387,7 @@ static void t1_hinter__paint_glyph(t1_hi + + for(j = beg_pole; j <= end_pole; j++) { + vd_circle(X(j), Y(j), 3, RGB(0,0,255)); +- sprintf(buf, "%d", j); ++ gs_sprintf(buf, "%d", j); + vd_text(self->pole[j].gx, self->pole[j].gy, buf, RGB(0,0,0)); + if (self->pole[j + 1].type == offcurve) + j+=2; +diff -up ghostscript-9.07/base/gxpath.c.gs_sprintf ghostscript-9.07/base/gxpath.c +--- ghostscript-9.07/base/gxpath.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gxpath.c 2013-05-09 17:02:39.086447171 +0100 +@@ -1035,7 +1035,7 @@ gx_print_segment(const gs_memory_t *mem, + double py = fixed2float(pseg->pt.y); + char out[80]; + +- sprintf(out, "0x%lx<0x%lx,0x%lx>:%u", ++ gs_sprintf(out, "0x%lx<0x%lx,0x%lx>:%u", + (ulong) pseg, (ulong) pseg->prev, (ulong) pseg->next, pseg->notes); + switch (pseg->type) { + case s_start:{ +diff -up ghostscript-9.07/base/gxpcmap.c.gs_sprintf ghostscript-9.07/base/gxpcmap.c +--- ghostscript-9.07/base/gxpcmap.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/gxpcmap.c 2013-05-09 17:02:39.087447175 +0100 +@@ -1147,10 +1147,10 @@ dump_raw_pattern(int height, int width, + is_planar = dev_proc(mdev, dev_spec_op)(mdev, gxdso_is_native_planar, NULL, 0) > 0; + max_bands = ( n_chan < 57 ? n_chan : 56); /* Photoshop handles at most 56 bands */ + if (is_planar) { +- sprintf(full_file_name,"%d)PATTERN_PLANE_%dx%dx%d.raw",global_pat_index, ++ gs_sprintf(full_file_name,"%d)PATTERN_PLANE_%dx%dx%d.raw",global_pat_index, + width,height,max_bands); + } else { +- sprintf(full_file_name,"%d)PATTERN_CHUNK_%dx%dx%d.raw",global_pat_index, ++ gs_sprintf(full_file_name,"%d)PATTERN_CHUNK_%dx%dx%d.raw",global_pat_index, + width,height,max_bands); + } + fid = fopen(full_file_name,"wb"); +diff -up ghostscript-9.07/base/lib.mak.gs_sprintf ghostscript-9.07/base/lib.mak +--- ghostscript-9.07/base/lib.mak.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/lib.mak 2013-05-09 17:02:39.088447180 +0100 +@@ -98,6 +98,9 @@ std_h=$(GLSRC)std.h $(arch_h) $(stdpre_h + + vmsmath_h=$(GLSRC)vmsmath.h + ++# declare here for use by string__h ++gssprintf_h=$(GLSRC)gssprintf.h ++ + dos__h=$(GLSRC)dos_.h + ctype__h=$(GLSRC)ctype_.h $(std_h) + dirent__h=$(GLSRC)dirent_.h $(std_h) $(gconfig__h) +@@ -110,7 +113,7 @@ math__h=$(GLSRC)math_.h $(std_h) $(vmsma + memory__h=$(GLSRC)memory_.h $(std_h) + setjmp__h=$(GLSRC)setjmp_.h + stat__h=$(GLSRC)stat_.h $(std_h) +-stdio__h=$(GLSRC)stdio_.h $(std_h) ++stdio__h=$(GLSRC)stdio_.h $(std_h) $(gssprintf_h) + string__h=$(GLSRC)string_.h $(std_h) + time__h=$(GLSRC)time_.h $(std_h) $(gconfig__h) + unistd__h=$(GLSRC)unistd_.h $(std_h) +@@ -151,6 +154,7 @@ gx_h=$(GLSRC)gx.h $(stdio__h) $(gdebug_h + $(gsio_h) $(gsmemory_h) $(gstypes_h) $(gserrors_h) + gxsync_h=$(GLSRC)gxsync.h $(gpsync_h) $(gsmemory_h) + gxclthrd_h=$(GLSRC)gxclthrd.h $(gxsync_h) ++ + # Out of order + gsmemlok_h=$(GLSRC)gsmemlok.h $(gsmemory_h) $(gxsync_h) + gsnotify_h=$(GLSRC)gsnotify.h $(gsstype_h) +@@ -320,6 +324,10 @@ $(AUX)gsutil.$(OBJ) : $(GLSRC)gsutil.c $ + $(gsrect_h) $(gsuid_h) $(gsutil_h) $(gzstate_h) $(gxdcolor_h) $(MAKEDIRS) + $(GLCCAUX) $(AUXO_)gsutil.$(OBJ) $(C_) $(GLSRC)gsutil.c + ++$(GLOBJ)gssprintf.$(OBJ) : $(GLSRC)gssprintf.c $(gssprintf_h) $(triodef_h) $(trio_h) \ ++$(triop_h) $(triostr_h) $(trionan_h) ++ $(GLCC) $(I_)$(TRIOSRCDIR)$(_I) $(GLO_)gssprintf.$(OBJ) $(C_) $(GLSRC)gssprintf.c ++ + # MD5 digest + md5_h=$(GLSRC)md5.h + # We have to use a slightly different compilation approach in order to +@@ -1309,7 +1317,7 @@ LIB10s=$(GLOBJ)gsmalloc.$(OBJ) $(GLOBJ)m + LIB11s=$(GLOBJ)gsmemory.$(OBJ) $(GLOBJ)gsmemret.$(OBJ) $(GLOBJ)gsmisc.$(OBJ) $(GLOBJ)gsnotify.$(OBJ) $(GLOBJ)gslibctx.$(OBJ) + LIB12s=$(GLOBJ)gspaint.$(OBJ) $(GLOBJ)gsparam.$(OBJ) $(GLOBJ)gspath.$(OBJ) + LIB13s=$(GLOBJ)gsserial.$(OBJ) $(GLOBJ)gsstate.$(OBJ) $(GLOBJ)gstext.$(OBJ)\ +- $(GLOBJ)gsutil.$(OBJ) ++ $(GLOBJ)gsutil.$(OBJ) $(TRIOOBJS) $(GLOBJ)gssprintf.$(OBJ) + LIB1x=$(GLOBJ)gxacpath.$(OBJ) $(GLOBJ)gxbcache.$(OBJ) $(GLOBJ)gxccache.$(OBJ) + LIB2x=$(GLOBJ)gxccman.$(OBJ) $(GLOBJ)gxchar.$(OBJ) $(GLOBJ)gxcht.$(OBJ) + LIB3x=$(GLOBJ)gxclip.$(OBJ) $(GLOBJ)gxcmap.$(OBJ) $(GLOBJ)gxcpath.$(OBJ) +diff -up ghostscript-9.07/base/md5main.c.gs_sprintf ghostscript-9.07/base/md5main.c +--- ghostscript-9.07/base/md5main.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/md5main.c 2013-05-09 17:02:39.088447180 +0100 +@@ -87,7 +87,7 @@ do_test(void) + gs_md5_append(&state, (const gs_md5_byte_t *)test[i], strlen(test[i])); + gs_md5_finish(&state, digest); + for (di = 0; di < 16; ++di) +- sprintf(hex_output + di * 2, "%02x", digest[di]); ++ gs_sprintf(hex_output + di * 2, "%02x", digest[di]); + if (strcmp(hex_output, test[i + 1])) { + printf("MD5 (\"%s\") = ", test[i]); + puts(hex_output); +diff -up ghostscript-9.07/base/mkromfs.c.gs_sprintf ghostscript-9.07/base/mkromfs.c +--- ghostscript-9.07/base/mkromfs.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/mkromfs.c 2013-05-09 17:02:39.088447180 +0100 +@@ -64,6 +64,8 @@ + * + */ + ++/* prevent gp.h redefining sprintf */ ++#define sprintf sprintf + #include "stdpre.h" + #include "stdint_.h" + #include "time_.h" +diff -up ghostscript-9.07/base/sdcparam.c.gs_sprintf ghostscript-9.07/base/sdcparam.c +--- ghostscript-9.07/base/sdcparam.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/sdcparam.c 2013-05-09 17:02:39.088447180 +0100 +@@ -200,7 +200,7 @@ s_DCT_get_quantization_tables(gs_param_l + gs_param_string str; + gs_param_float_array fa; + +- sprintf(key, "%d", i); ++ gs_sprintf(key, "%d", i); + if (QFactor == 1.0) { + code = quant_param_string(&str, DCTSIZE2, + table_ptrs[comp_info[i].quant_tbl_no]->quantval, +@@ -474,7 +474,7 @@ s_DCT_put_quantization_tables(gs_param_l + char istr[5]; /* i converted to string key */ + UINT16 values[DCTSIZE2]; + +- sprintf(istr, "%d", i); ++ gs_sprintf(istr, "%d", i); + code = quant_params(quant_tables.list, istr, DCTSIZE2, values, + pdct->QFactor); + if (code < 0) +@@ -566,7 +566,7 @@ s_DCT_put_huffman_tables(gs_param_list * + UINT8 counts[16], values[256]; + + /* Collect the Huffman parameters. */ +- sprintf(istr, "%d", i); ++ gs_sprintf(istr, "%d", i); + code = s_DCT_byte_params(huff_tables.list, istr, 0, 16, counts); + if (code < 0) + return code; +diff -up ghostscript-9.07/base/sjbig2.c.gs_sprintf ghostscript-9.07/base/sjbig2.c +--- ghostscript-9.07/base/sjbig2.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/sjbig2.c 2013-05-09 17:02:39.089447184 +0100 +@@ -65,7 +65,7 @@ s_jbig2decode_error(void *error_callback + default: type = "unknown message:"; break;; + } + if (seg_idx == -1) segment[0] = '\0'; +- else sprintf(segment, "(segment 0x%02x)", seg_idx); ++ else gs_sprintf(segment, "(segment 0x%02x)", seg_idx); + + if (state) + { +diff -up ghostscript-9.07/base/spprint.c.gs_sprintf ghostscript-9.07/base/spprint.c +--- ghostscript-9.07/base/spprint.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/spprint.c 2013-05-09 17:02:39.089447184 +0100 +@@ -83,7 +83,7 @@ pprintd1(stream * s, const char *format, + if (*fp == 0 || fp[1] != 'd') /* shouldn't happen! */ + lprintf1("Bad format in pprintd1: %s\n", format); + #endif +- sprintf(str, "%d", v); ++ gs_sprintf(str, "%d", v); + pputs_short(s, str); + return pprintf_scan(s, fp + 2); + } +@@ -115,12 +115,12 @@ pprintg1(stream * s, const char *format, + if (*fp == 0 || fp[1] != 'g') /* shouldn't happen! */ + lprintf1("Bad format in pprintg: %s\n", format); + #endif +- sprintf(str, "%f", 1.5); ++ gs_sprintf(str, "%f", 1.5); + dot = str[1]; /* locale-dependent */ +- sprintf(str, "%g", v); ++ gs_sprintf(str, "%g", v); + if (strchr(str, 'e')) { + /* Bad news. Try again using f-format. */ +- sprintf(str, (fabs(v) > 1 ? "%1.1f" : "%1.8f"), v); ++ gs_sprintf(str, (fabs(v) > 1 ? "%1.1f" : "%1.8f"), v); + } + /* Juggling locales isn't thread-safe. Posix me harder. */ + if (dot != '.') { +@@ -165,7 +165,7 @@ pprintld1(stream * s, const char *format + if (*fp == 0 || fp[1] != 'l' || fp[2] != 'd') /* shouldn't happen! */ + lprintf1("Bad format in pprintld: %s\n", format); + #endif +- sprintf(str, "%ld", v); ++ gs_sprintf(str, "%ld", v); + pputs_short(s, str); + return pprintf_scan(s, fp + 3); + } +diff -up ghostscript-9.07/base/trio.mak.gs_sprintf ghostscript-9.07/base/trio.mak +--- ghostscript-9.07/base/trio.mak.gs_sprintf 2013-05-09 17:02:39.089447184 +0100 ++++ ghostscript-9.07/base/trio.mak 2013-05-09 17:02:39.089447184 +0100 +@@ -0,0 +1,57 @@ ++# Copyright (C) 2001-2012 Artifex Software, Inc. ++# All Rights Reserved. ++# ++# This software is provided AS-IS with no warranty, either express or ++# implied. ++# ++# This software is distributed under license and may not be copied, ++# modified or distributed except as expressly authorized under the terms ++# of the license contained in the file LICENSE in this distribution. ++# ++# Refer to licensing information at http://www.artifex.com or contact ++# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, ++# CA 94903, U.S.A., +1(415)492-9861, for further information. ++# ++# makefile for trio - locale-less s(n)printf/s(n)canf ++# ++# Users of this makefile must define the following: ++# TRIO_CFLAGS - Compiler flags for building the source, ++# TRIOSRCDIR - the expat source top-level directory, ++# TIOOBJDIR - directory for object files. ++ ++# Define the name of this makefile ++TRIO_MAK=$(GLSRCDIR)$(D)trio.mak ++ ++# local aliases ++TRIOSRC=$(TRIOSRCDIR)$(D) ++TRIOOBJ=$(TRIOOBJDIR)$(D) ++TRIOO_=$(O_)$(TRIOOBJ) ++ ++TRIOCFLAGS=$(CFLAGS) $(TRIO_CFLAGS) $(D_)TRIO_EMBED_STRING$(_D) $(D_)TRIO_FEATURE_CLOSURE=0$(_D) \ ++$(D_)TRIO_FEATURE_DYNAMICSTRING=0$(_D) $(D_)TRIO_MINIMAL=0$(_D) \ ++$(D_)TRIO_FEATURE_USER_DEFINED=0$(_D) $(D_)TRIO_EXTENSION=0$(_D)\ ++$(D_)TRIO_FUNC_TO_FLOAT$(_D) $(I_)$(TRIOSRCDIR)$(_I) \ ++$(D_)TRIO_MALLOC=no_malloc$(_D) $(D_)TRIO_REALLOC=no_realloc$(_D) $(D_)TRIO_FREE=no_free$(_D) ++ ++ ++# NB: we can't use the normal $(CC_) here because msvccmd.mak ++# adds /Za which conflicts with the trio source. ++TRIOCC=$(CC) $(TRIOCFLAGS) ++ ++TRIOOBJS=$(TRIOOBJ)triostr.$(OBJ) $(TRIOOBJ)trio.$(OBJ) $(TRIOOBJ)trionan.$(OBJ) ++ ++triodef_h=$(TRIOSRC)triodef.h ++trio_h=$(TRIOSRC)trio.h ++triop_h=$(TRIOSRC)triop.h ++triostr_h=$(TRIOSRC)triostr.h ++ ++TRIOHDRS=$(triodef_h) $(trio_h) $(triop_h) $(triostr_h) ++ ++$(TRIOOBJ)triostr.$(OBJ) : $(TRIOSRC)triostr.c $(TRIOHDRS) $(TRIO_MAK) ++ $(TRIOCC) $(TRIOO_)triostr.$(OBJ) $(C_) $(TRIOSRC)triostr.c ++ ++$(TRIOOBJ)trio.$(OBJ) : $(TRIOSRC)trio.c $(TRIOHDRS) $(TRIO_MAK) ++ $(TRIOCC) $(TRIOO_)trio.$(OBJ) $(C_) $(TRIOSRC)trio.c ++ ++$(TRIOOBJ)trionan.$(OBJ) : $(TRIOSRC)trionan.c $(TRIOHDRS) $(TRIO_MAK) ++ $(TRIOCC) $(TRIOO_)trionan.$(OBJ) $(C_) $(TRIOSRC)trionan.c +diff -up ghostscript-9.07/base/unixansi.mak.gs_sprintf ghostscript-9.07/base/unixansi.mak +--- ghostscript-9.07/base/unixansi.mak.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/unixansi.mak 2013-05-09 17:02:39.089447184 +0100 +@@ -152,6 +152,8 @@ TIFFPLATFORM=unix + TIFFCONFIG_SUFFIX=.unix + LIBTIFF_NAME=tiff + ++TRIOSRCDIR=trio ++ + # Define the directory where the zlib sources are stored. + # See zlib.mak for more information. + +@@ -392,6 +394,7 @@ CC_SHARED=$(CC_) + + include $(GLSRCDIR)/unixhead.mak + include $(GLSRCDIR)/gs.mak ++include $(GLSRCDIR)/trio.mak + # psromfs.mak must precede lib.mak + include $(PSSRCDIR)/psromfs.mak + include $(GLSRCDIR)/lib.mak +diff -up ghostscript-9.07/base/unix-gcc.mak.gs_sprintf ghostscript-9.07/base/unix-gcc.mak +--- ghostscript-9.07/base/unix-gcc.mak.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/unix-gcc.mak 2013-05-09 17:02:39.089447184 +0100 +@@ -165,6 +165,8 @@ TIFFPLATFORM=unix + TIFFCONFIG_SUFFIX=.unix + LIBTIFF_NAME=tiff + ++TRIOSRCDIR=trio ++ + # Define the directory where the zlib sources are stored. + # See zlib.mak for more information. + +@@ -461,6 +463,7 @@ MAKEDIRSTOP=directories + + include $(GLSRCDIR)/unixhead.mak + include $(GLSRCDIR)/gs.mak ++include $(GLSRCDIR)/trio.mak + # psromfs.mak must precede lib.mak + include $(PSSRCDIR)/psromfs.mak + include $(GLSRCDIR)/lib.mak +diff -up ghostscript-9.07/base/winlib.mak.gs_sprintf ghostscript-9.07/base/winlib.mak +--- ghostscript-9.07/base/winlib.mak.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/winlib.mak 2013-05-09 17:02:39.090447188 +0100 +@@ -133,6 +133,7 @@ BEGINFILES=$(GLGENDIR)\ccf32.tr\ + #!include $(COMMONDIR)/pcdefs.mak + #!include $(COMMONDIR)/generic.mak + !include $(GLSRCDIR)\gs.mak ++!include $(GLSRCDIR)\trio.mak + !include $(GLSRCDIR)\lib.mak + !include $(GLSRCDIR)\freetype.mak + !if "$(UFST_BRIDGE)"=="1" +diff -up ghostscript-9.07/base/wrfont.c.gs_sprintf ghostscript-9.07/base/wrfont.c +--- ghostscript-9.07/base/wrfont.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/wrfont.c 2013-05-09 17:02:39.090447188 +0100 +@@ -72,7 +72,7 @@ WRF_wfloat(WRF_output * a_output, double + { + char buffer[32]; + +- sprintf(buffer, "%f", a_float); ++ gs_sprintf(buffer, "%f", a_float); + WRF_wstring(a_output, buffer); + } + +@@ -81,6 +81,6 @@ WRF_wint(WRF_output * a_output, long a_i + { + char buffer[32]; + +- sprintf(buffer, "%ld", a_int); ++ gs_sprintf(buffer, "%ld", a_int); + WRF_wstring(a_output, buffer); + } +diff -up ghostscript-9.07/base/write_t1.c.gs_sprintf ghostscript-9.07/base/write_t1.c +--- ghostscript-9.07/base/write_t1.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/write_t1.c 2013-05-09 17:02:39.090447188 +0100 +@@ -300,7 +300,7 @@ write_main_dictionary(gs_fapi_font * a_f + if (x) + entries++; + +- sprintf(Buffer, "/FontInfo %d dict dup begin\n", entries); ++ gs_sprintf(Buffer, "/FontInfo %d dict dup begin\n", entries); + WRF_wstring(a_output, Buffer); + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendAxisTypes_count, +@@ -330,7 +330,7 @@ write_main_dictionary(gs_fapi_font * a_f + x1 = a_fapi_font->get_float(a_fapi_font, + gs_fapi_font_feature_BlendDesignPositionsArrayValue, + i * 8 + j); +- sprintf(Buffer, "%f ", x1); ++ gs_sprintf(Buffer, "%f ", x1); + WRF_wstring(a_output, Buffer); + } + WRF_wstring(a_output, "]"); +@@ -352,12 +352,12 @@ write_main_dictionary(gs_fapi_font * a_f + x1 = a_fapi_font->get_float(a_fapi_font, + gs_fapi_font_feature_BlendDesignPositionsArrayValue, + i * 64 + j * 64); +- sprintf(Buffer, "%f ", x1); ++ gs_sprintf(Buffer, "%f ", x1); + WRF_wstring(a_output, Buffer); + x1 = a_fapi_font->get_float(a_fapi_font, + gs_fapi_font_feature_BlendDesignPositionsArrayValue, + i * 64 + j * 64 + 1); +- sprintf(Buffer, "%f ", x1); ++ gs_sprintf(Buffer, "%f ", x1); + WRF_wstring(a_output, Buffer); + WRF_wstring(a_output, "]"); + } +@@ -397,7 +397,7 @@ write_main_dictionary(gs_fapi_font * a_f + for (i = 0; i < x; i++) { + x1 = a_fapi_font->get_float(a_fapi_font, + gs_fapi_font_feature_WeightVector, i); +- sprintf(Buffer, "%f ", x1); ++ gs_sprintf(Buffer, "%f ", x1); + WRF_wstring(a_output, Buffer); + } + WRF_wstring(a_output, "] def\n"); +diff -up ghostscript-9.07/base/write_t2.c.gs_sprintf ghostscript-9.07/base/write_t2.c +--- ghostscript-9.07/base/write_t2.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/base/write_t2.c 2013-05-09 17:02:39.090447188 +0100 +@@ -70,7 +70,7 @@ write_type2_float(WRF_output * a_output, + int high = true; + char c = 0; + +- sprintf(buffer, "%f", a_float); ++ gs_sprintf(buffer, "%f", a_float); + WRF_wbyte(a_output, 30); + for (;;) { + char n = 0; +diff -up ghostscript-9.07/contrib/eplaser/gdevescv.c.gs_sprintf ghostscript-9.07/contrib/eplaser/gdevescv.c +--- ghostscript-9.07/contrib/eplaser/gdevescv.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/eplaser/gdevescv.c 2013-05-09 17:02:39.091447193 +0100 +@@ -545,7 +545,7 @@ escv_vector_dopath(gx_device_vector * vd + y = fixed2float(vs[1]) / scale.y; + + /* ���֥ѥ�����̿�� p1 */ +- (void)sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x, (int)y); ++ (void)gs_sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x, (int)y); + lputs(s, obuf); + + if (first) +@@ -556,11 +556,11 @@ escv_vector_dopath(gx_device_vector * vd + cnt = 1; + for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_line; cnt++, pseg = pseg->next); + +- (void)sprintf(obuf, ESC_GS "0;%d", cnt); ++ (void)gs_sprintf(obuf, ESC_GS "0;%d", cnt); + lputs(s, obuf); + + do { +- (void)sprintf(obuf, ";%d;%d", ++ (void)gs_sprintf(obuf, ";%d;%d", + (int)(fixed2float(vs[0]) / scale.x), + (int)(fixed2float(vs[1]) / scale.y)); + lputs(s, obuf); +@@ -577,11 +577,11 @@ escv_vector_dopath(gx_device_vector * vd + case gs_pe_curveto: + cnt = 1; + for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_curve; cnt++, pseg = pseg->next); +- (void)sprintf(obuf, ESC_GS "0;%d", cnt * 3); ++ (void)gs_sprintf(obuf, ESC_GS "0;%d", cnt * 3); + lputs(s, obuf); + + do { +- (void)sprintf(obuf, ";%d;%d;%d;%d;%d;%d", ++ (void)gs_sprintf(obuf, ";%d;%d;%d;%d;%d;%d", + (int)(fixed2float(vs[0]) / scale.x), (int)(fixed2float(vs[1]) / scale.y), + (int)(fixed2float(vs[2]) / scale.x), (int)(fixed2float(vs[3]) / scale.y), + (int)(fixed2float(vs[4]) / scale.x), (int)(fixed2float(vs[5]) / scale.y)); +@@ -637,7 +637,7 @@ escv_vector_dorect(gx_device_vector * vd + + scale = vdev->scale; + +- (void)sprintf(obuf, ESC_GS "0;%d;%d;%d;%d;0;0rrpG", ++ (void)gs_sprintf(obuf, ESC_GS "0;%d;%d;%d;%d;0;0rrpG", + (int)(fixed2float(x0) / scale.x), + (int)(fixed2float(y0) / scale.y), + (int)(fixed2float(x1) / scale.x), +@@ -1116,7 +1116,7 @@ escv_beginpage(gx_device_vector * vdev) + lputs(s, " PU=15"); + } + } else if (pdev->cassetFeed) { +- (void)sprintf(ebuf, " PU=%d", pdev->cassetFeed); ++ (void)gs_sprintf(ebuf, " PU=%d", pdev->cassetFeed); + lputs(s, ebuf); + } else { + lputs(s, " PU=AU"); +@@ -1146,14 +1146,14 @@ escv_beginpage(gx_device_vector * vdev) + + /* lp8000c not have QT */ + if (strcmp(pdev->dname, "lp8000c") == 0) { +- (void)sprintf(ebuf, " QT=1 CO=%d", pdev->NumCopies); ++ (void)gs_sprintf(ebuf, " QT=1 CO=%d", pdev->NumCopies); + } else { + if (pdev->Collate) { + /* CO is 1, when set QT */ +- (void)sprintf(ebuf, " QT=%d CO=1", pdev->NumCopies); ++ (void)gs_sprintf(ebuf, " QT=%d CO=1", pdev->NumCopies); + } else { + /* QT is 1, when not specified QT */ +- (void)sprintf(ebuf, " QT=1 CO=%d", pdev->NumCopies); ++ (void)gs_sprintf(ebuf, " QT=1 CO=%d", pdev->NumCopies); + } + } + lputs(s, ebuf); +@@ -1162,7 +1162,7 @@ escv_beginpage(gx_device_vector * vdev) + } + + if (pdev->toner_density) { +- (void)sprintf(ebuf, " DL=%d", pdev->toner_density); ++ (void)gs_sprintf(ebuf, " DL=%d", pdev->toner_density); + lputs(s, ebuf); + } + +@@ -1320,7 +1320,7 @@ escv_setlinewidth(gx_device_vector * vde + /* ESC/Page �Ǥ���������ü���ܹ���������ϣ��ĤΥ��ޥ�ɤˤʤäƤ��뤿���ݻ����Ƥ����� */ + pdev -> lwidth = width; + +- (void)sprintf(obuf, ESC_GS "%d;%d;%dlwG", ++ (void)gs_sprintf(obuf, ESC_GS "%d;%d;%dlwG", + (int)(pdev -> lwidth), + (int)(pdev -> cap), + (int)(pdev -> join)); +@@ -1341,7 +1341,7 @@ escv_setlinecap(gx_device_vector * vdev, + + if (pdev -> cap >= 3) return -1; + +- (void)sprintf(obuf, ESC_GS "%d;%d;%dlwG", ++ (void)gs_sprintf(obuf, ESC_GS "%d;%d;%dlwG", + (int)(pdev -> lwidth), + (int)(pdev -> cap), + (int)(pdev -> join)); +@@ -1372,7 +1372,7 @@ escv_setlinejoin(gx_device_vector * vdev + return -1; + } + +- (void)sprintf(obuf, ESC_GS "%d;%d;%dlwG", ++ (void)gs_sprintf(obuf, ESC_GS "%d;%d;%dlwG", + (int)(pdev -> lwidth), + (int)(pdev -> cap), + (int)(pdev -> join)); +@@ -1394,14 +1394,14 @@ escv_setmiterlimit(gx_device_vector * vd + if (pdev -> join != 3) { + /* ����Ū���ܹ��������Ԥ� */ + pdev -> join = 3; +- (void)sprintf(obuf, ESC_GS "%d;%d;%dlwG", ++ (void)gs_sprintf(obuf, ESC_GS "%d;%d;%dlwG", + (int)(pdev -> lwidth), + (int)(pdev -> cap), + (int)(pdev -> join)); + lputs(s, obuf); + } + +- (void)sprintf(obuf, ESC_GS "1;%dmlG", (int)limit); ++ (void)gs_sprintf(obuf, ESC_GS "1;%dmlG", (int)limit); + lputs(s, obuf); + + return 0; +@@ -1433,7 +1433,7 @@ escv_setfillcolor(gx_device_vector * vde + + if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ + +- (void)sprintf(obuf, /*ESC_GS "1owE"*/ ESC_GS "0;0;100spE" ESC_GS "1;0;%ldccE" ,color); ++ (void)gs_sprintf(obuf, /*ESC_GS "1owE"*/ ESC_GS "0;0;100spE" ESC_GS "1;0;%ldccE" ,color); + lputs(s, obuf); + + if (vdev->x_pixels_per_inch == 1200) { +@@ -1447,7 +1447,7 @@ escv_setfillcolor(gx_device_vector * vde + } else { /* ESC/Page-Color */ + + /* �ѥ�����ϣλ��꡿����åɥѥ�������� */ +- (void)sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE", ++ (void)gs_sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE", + (unsigned char)(color >> 16 & 0xff), + (unsigned char)(color >> 8 & 0xff), + (unsigned char)(color & 0xff)); +@@ -1477,7 +1477,7 @@ escv_setstrokecolor(gx_device_vector * v + + pdev->current_color = color; + +- (void)sprintf(obuf, /*ESC_GS "1owE"*/ ESC_GS "0;0;100spE" ESC_GS "1;1;%ldccE" , color); ++ (void)gs_sprintf(obuf, /*ESC_GS "1owE"*/ ESC_GS "0;0;100spE" ESC_GS "1;1;%ldccE" , color); + lputs(s, obuf); + + if (vdev->x_pixels_per_inch == 1200) { +@@ -1494,7 +1494,7 @@ escv_setstrokecolor(gx_device_vector * v + + pdev->current_color = color; + /* �ѥ�����ϣο����꡿����åɥѥ�������� */ +- (void)sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE" ESC_GS "2;2;1;0;0cpE", ++ (void)gs_sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE" ESC_GS "2;2;1;0;0cpE", + (unsigned char)(color >> 16 & 0xff), + (unsigned char)(color >> 8 & 0xff), + (unsigned char)(color & 0xff)); +@@ -1538,11 +1538,11 @@ escv_setdash(gx_device_vector * vdev, co + if (count) { + if (count == 1) { + #if GS_VERSION_MAJOR == 5 +- (void)sprintf(obuf, ESC_GS "1;%d;%ddlG", ++ (void)gs_sprintf(obuf, ESC_GS "1;%d;%ddlG", + (int)(pattern[0] * scale / vdev->x_pixels_per_inch + 0.5), + (int)(pattern[0] * scale / vdev->x_pixels_per_inch + 0.5)); + #else +- (void)sprintf(obuf, ESC_GS "1;%d;%ddlG", (int) pattern[0], (int) pattern[0]); ++ (void)gs_sprintf(obuf, ESC_GS "1;%d;%ddlG", (int) pattern[0], (int) pattern[0]); + #endif + lputs(s, obuf); + } else { +@@ -1554,10 +1554,10 @@ escv_setdash(gx_device_vector * vdev, co + lputs(s, ESC_GS "1"); + for (i = 0; i < count; ++i) { + #if GS_VERSION_MAJOR == 5 +- (void)sprintf(obuf, ";%d", (int)(pattern[i] * scale / vdev->x_pixels_per_inch + 0.5)); ++ (void)gs_sprintf(obuf, ";%d", (int)(pattern[i] * scale / vdev->x_pixels_per_inch + 0.5)); + + #else +- (void)sprintf(obuf, ";%d", (int) pattern[i]); ++ (void)gs_sprintf(obuf, ";%d", (int) pattern[i]); + #endif + lputs(s, obuf); + } +@@ -1608,7 +1608,7 @@ escv_moveto(gx_device_vector * vdev, + char obuf[64]; + + /* ���֥ѥ�����̿�� */ +- (void)sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x1, (int)y1); ++ (void)gs_sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x1, (int)y1); + lputs(s, obuf); + + return 0; +@@ -1622,7 +1622,7 @@ escv_lineto(gx_device_vector * vdev, + gx_device_escv *pdev = (gx_device_escv *) vdev; + char obuf[64]; + +- (void)sprintf(obuf, ESC_GS "0;1;%d;%dlnpG", (int)x1, (int)y1); ++ (void)gs_sprintf(obuf, ESC_GS "0;1;%d;%dlnpG", (int)x1, (int)y1); + lputs(s, obuf); + pdev->ispath = 1; + +@@ -1639,7 +1639,7 @@ escv_curveto(gx_device_vector * vdev, fl + char obuf[128]; + + /* �٥������� */ +- (void)sprintf(obuf, ESC_GS "0;3;%d;%d;%d;%d;%d;%dbzpG", ++ (void)gs_sprintf(obuf, ESC_GS "0;3;%d;%d;%d;%d;%d;%dbzpG", + (int)x1, (int)y1, (int)x2, (int)y2, (int)x3, (int)y3); + lputs(s, obuf); + pdev->ispath = 1; +@@ -2176,7 +2176,7 @@ escv_copy_mono(gx_device * dev, const by + if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ + + /* lputs(s, ESC_GS "1owE");*/ +- (void)sprintf(obuf, ESC_GS "1;1;%ldccE", c_color); ++ (void)gs_sprintf(obuf, ESC_GS "1;1;%ldccE", c_color); + lputs(s, obuf); + + if (vdev->x_pixels_per_inch == 1200) { +@@ -2263,7 +2263,7 @@ escv_copy_mono(gx_device * dev, const by + } else { /* ESC/Page-Color */ + + /* �ѥ�����ϣλ��꡿����åɥѥ�������� */ +- (void)sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE", ++ (void)gs_sprintf(obuf, ESC_GS "1;2;3;%d;%d;%dfpE", + (unsigned char)(c_color >> 16 & 0xff), + (unsigned char)(c_color >> 8 & 0xff), + (unsigned char)(c_color & 0xff)); +@@ -2388,7 +2388,7 @@ escv_fill_mask(gx_device * dev, + if (!gx_dc_is_pure(pdcolor)) return_error(gs_error_rangecheck); + pdev->current_color = color; + +- (void)sprintf(obuf, ESC_GS "0;0;100spE" ESC_GS "1;1;%ldccE" ,color); ++ (void)gs_sprintf(obuf, ESC_GS "0;0;100spE" ESC_GS "1;1;%ldccE" ,color); + lputs(s, obuf); + + if (vdev->x_pixels_per_inch == 1200) { +@@ -2428,7 +2428,7 @@ escv_fill_mask(gx_device * dev, + memcpy(buf + i * width_bytes, data + (data_x >> 3) + i * raster, width_bytes); + } + +- (void)sprintf(obuf, ESC_GS "%d;%d;%d;%d;0db{F", num_bytes, (int)(id & VCACHE), w, h); ++ (void)gs_sprintf(obuf, ESC_GS "%d;%d;%d;%d;0db{F", num_bytes, (int)(id & VCACHE), w, h); + lputs(s, obuf); + put_bytes(s, buf, num_bytes); + +@@ -2436,9 +2436,9 @@ escv_fill_mask(gx_device * dev, + pdev -> id_cache[id & VCACHE] = id; + } + +- (void)sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); ++ (void)gs_sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); + lputs(s, obuf); +- (void)sprintf(obuf, ESC_GS "%lddbF", id & VCACHE); ++ (void)gs_sprintf(obuf, ESC_GS "%lddbF", id & VCACHE); + lputs(s, obuf); + + return 0; +@@ -2603,7 +2603,7 @@ escv_begin_image(gx_device * dev, + if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ + + /* lputs(s, ESC_GS "1owE");*/ +- (void)sprintf(obuf, ESC_GS "1;1;%ldccE", color); ++ (void)gs_sprintf(obuf, ESC_GS "1;1;%ldccE", color); + lputs(s, obuf); + + if (vdev->x_pixels_per_inch == 1200) { +@@ -2908,7 +2908,7 @@ static void escv_write_begin(gx_device * + + if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ + +- (void)sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); ++ (void)gs_sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); + lputs(s, obuf); + + comp = 10; +@@ -2916,34 +2916,34 @@ static void escv_write_begin(gx_device * + if (bits == 1) { + if (strcmp(pdev->dname, "lp1800") == 0 || + strcmp(pdev->dname, "lp9600") == 0) { +- (void)sprintf(obuf, ESC_GS "0bcI"); ++ (void)gs_sprintf(obuf, ESC_GS "0bcI"); + }else{ +- (void)sprintf(obuf, ESC_GS "5;%d;%d;%d;%d;%dsrI", sw, sh, dw, dh, roll); ++ (void)gs_sprintf(obuf, ESC_GS "5;%d;%d;%d;%d;%dsrI", sw, sh, dw, dh, roll); + } + } else if (bits == 4) { + if (pdev -> c4map) { + pdev -> c4map = FALSE; + } +- (void)sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); ++ (void)gs_sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); + } else if (bits == 8) { + if (pdev -> c8map) { + pdev -> c8map = FALSE; + } +- (void)sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); ++ (void)gs_sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); + } else { + /* 24 bit */ +- (void)sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); ++ (void)gs_sprintf(obuf, ESC_GS "1;1;1;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); + } + + } else { /* ESC/Page-Color */ + +- (void)sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); ++ (void)gs_sprintf(obuf, ESC_GS "%dX" ESC_GS "%dY", x, y); + lputs(s, obuf); + + comp = 0; + + if (bits == 1) { +- (void)sprintf(obuf, ESC_GS "2;201;1;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); ++ (void)gs_sprintf(obuf, ESC_GS "2;201;1;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); + } else if (bits == 4) { + if (pdev -> c4map) { + /* ���顼�ޥå���Ͽ */ +@@ -2959,7 +2959,7 @@ static void escv_write_begin(gx_device * + gs_free_object(vdev->memory, tmp, "escv_write_begin(tmp4)"); + pdev -> c4map = FALSE; + } +- (void)sprintf(obuf, ESC_GS "2;203;2;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); ++ (void)gs_sprintf(obuf, ESC_GS "2;203;2;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); + } else if (bits == 8) { + if (pdev -> c8map) { + /* ���顼�ޥå���Ͽ */ +@@ -2975,10 +2975,10 @@ static void escv_write_begin(gx_device * + gs_free_object(vdev->memory, tmp, "escv_write_begin(tmp)"); + pdev -> c8map = FALSE; + } +- (void)sprintf(obuf, ESC_GS "2;204;4;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); ++ (void)gs_sprintf(obuf, ESC_GS "2;204;4;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); + } else { + /* 24 bit */ +- (void)sprintf(obuf, ESC_GS "2;102;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); ++ (void)gs_sprintf(obuf, ESC_GS "2;102;0;%d;%d;%d;%d;%d;%dscrI", comp, sw, sh, dw, dh, roll); + } + + } /* ESC/Page-Color */ +@@ -3045,12 +3045,12 @@ static void escv_write_data(gx_device *d + if(bits == 1){ + if (strcmp(pdev->dname, "lp1800") == 0 || \ + strcmp(pdev->dname, "lp9600") == 0) { +- (void)sprintf(obuf, ESC_GS "%d;1;%d;%d;0db{I", bsize, w, ras); ++ (void)gs_sprintf(obuf, ESC_GS "%d;1;%d;%d;0db{I", bsize, w, ras); + }else{ +- (void)sprintf(obuf, ESC_GS "%d;%du{I", bsize, ras); ++ (void)gs_sprintf(obuf, ESC_GS "%d;%du{I", bsize, ras); + } + }else{ +- (void)sprintf(obuf, ESC_GS "%d;%dcu{I", bsize, ras); ++ (void)gs_sprintf(obuf, ESC_GS "%d;%dcu{I", bsize, ras); + } + lputs(s, obuf); + +@@ -3077,7 +3077,7 @@ static void escv_write_data(gx_device *d + buf = tmps; + } + +- (void)sprintf(obuf, ESC_GS "%d;%dcu{I", bsize, ras); ++ (void)gs_sprintf(obuf, ESC_GS "%d;%dcu{I", bsize, ras); + lputs(s, obuf); + put_bytes(s, buf, bsize); + +diff -up ghostscript-9.07/contrib/gdevcd8.c.gs_sprintf ghostscript-9.07/contrib/gdevcd8.c +--- ghostscript-9.07/contrib/gdevcd8.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/gdevcd8.c 2013-05-09 17:02:39.092447197 +0100 +@@ -2439,7 +2439,7 @@ do_gcr(int bytecount, byte * inbyte, con + #if 0 + if ((*cyan > 0) && (*magenta > 0) && (*yellow > 0)) + { +- sprintf(output, "%3d %3d %3d %3d - ", *cyan, *magenta, *yellow, *black); ++ gs_sprintf(output, "%3d %3d %3d %3d - ", *cyan, *magenta, *yellow, *black); + debug_print_string(output, strlen(output)); + } + #endif /* 0 */ +@@ -2486,7 +2486,7 @@ do_gcr(int bytecount, byte * inbyte, con + #if 0 + if (ucr > 0) + { +- sprintf(output, "%3d %3d %3d %3d - %5d\n", *cyan, *magenta, *yellow, *black, ucr); ++ gs_sprintf(output, "%3d %3d %3d %3d - %5d\n", *cyan, *magenta, *yellow, *black, ucr); + debug_print_string(output, strlen(output)); + } + #endif /* 0 */ +diff -up ghostscript-9.07/contrib/gdevdj9.c.gs_sprintf ghostscript-9.07/contrib/gdevdj9.c +--- ghostscript-9.07/contrib/gdevdj9.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/gdevdj9.c 2013-05-09 17:02:39.092447197 +0100 +@@ -2563,7 +2563,7 @@ static int cdj970_write_header (gx_devic + + memset (startbuffer, 0, 1260); + +- sprintf (&(startbuffer[600]), "\033E\033%%-12345X@PJL JOB NAME = \"GHOST BY RENE HARSCH\"\n@PJL ENTER LANGUAGE=PCL3GUI\n"); ++ gs_sprintf (&(startbuffer[600]), "\033E\033%%-12345X@PJL JOB NAME = \"GHOST BY RENE HARSCH\"\n@PJL ENTER LANGUAGE=PCL3GUI\n"); + + fwrite (startbuffer, sizeof(char), 678, prn_stream); + +diff -up ghostscript-9.07/contrib/gdevhl12.c.gs_sprintf ghostscript-9.07/contrib/gdevhl12.c +--- ghostscript-9.07/contrib/gdevhl12.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/gdevhl12.c 2013-05-09 17:02:39.092447197 +0100 +@@ -662,7 +662,7 @@ hl1250_print_page_copies(gx_device_print + (-120, 0) compared to the one in the ljet4 driver (-180, 36) + (X, Y coordinates here are specified in 1/720-inch units). */ + +- sprintf(page_init, "\033&l-120U\033*r0F\033&u%dD%s", y_dpi, tray_pcl); ++ gs_sprintf(page_init, "\033&l-120U\033*r0F\033&u%dD%s", y_dpi, tray_pcl); + return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, + y_dpi, PCL_LJ4_FEATURES, + page_init, page_init, false); +diff -up ghostscript-9.07/contrib/gdevxes.c.gs_sprintf ghostscript-9.07/contrib/gdevxes.c +--- ghostscript-9.07/contrib/gdevxes.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/gdevxes.c 2013-05-09 17:02:39.092447197 +0100 +@@ -173,7 +173,7 @@ sixel_print_page(gx_device_printer *pdev + if ( tmp[l] == last ) { + count++; + if (count==32767) { +- run[sprintf(run, "%d", count)]='\0'; ++ run[gs_sprintf(run, "%d", count)]='\0'; + for (t=run; *t; t++)fputc( *t, prn_stream ); + fputc( last, prn_stream ); + last = '\0'; +@@ -186,7 +186,7 @@ sixel_print_page(gx_device_printer *pdev + case 0: break; + case 1: fputc( last, prn_stream ); + break; +- default:run[sprintf(run, "%d", count)]='\0'; ++ default:run[gs_sprintf(run, "%d", count)]='\0'; + for (t=run; *t; t++) fputc( *t, prn_stream ); + fputc( last, prn_stream ); + break; +@@ -203,7 +203,7 @@ sixel_print_page(gx_device_printer *pdev + case 0: break; + case 1: fputc( last, prn_stream ); + break; +- default:run[sprintf(run, "%d", count)]='\0'; ++ default:run[gs_sprintf(run, "%d", count)]='\0'; + for (t=run; *t; t++) fputc( *t, prn_stream ); + fputc( last, prn_stream ); + break; +diff -up ghostscript-9.07/contrib/gomni.c.gs_sprintf ghostscript-9.07/contrib/gomni.c +--- ghostscript-9.07/contrib/gomni.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/gomni.c 2013-05-09 17:02:39.093447201 +0100 +@@ -790,7 +790,7 @@ SetupDevice (gx_device *pgxdev, gs_param + "Devicestring"); + if (pszDeviceLib) + { +- sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib); ++ gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib); + + pDev->hmodOmni = g_module_open (pszDeviceLib, (GModuleFlags)0); + +@@ -817,7 +817,7 @@ SetupDevice (gx_device *pgxdev, gs_param + "Devicestring"); + if (pszDeviceLib) + { +- sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib); ++ gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib); + + pModule = g_module_open (pszDeviceLib, (GModuleFlags)0); + +@@ -1053,7 +1053,7 @@ SetupDevice (gx_device *pgxdev, gs_param + + if (pszDeviceLib) + { +- sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName); ++ gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName); + + if (fDebugOutput) dprintf1 ("attempting to load - %s\n", pszDeviceLib); + +@@ -1079,7 +1079,7 @@ SetupDevice (gx_device *pgxdev, gs_param + + if (pszDeviceLib) + { +- sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName); ++ gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName); + + pModule = g_module_open (pszDeviceLib, (GModuleFlags)0); + +diff -up ghostscript-9.07/contrib/japanese/dviprlib.c.gs_sprintf ghostscript-9.07/contrib/japanese/dviprlib.c +--- ghostscript-9.07/contrib/japanese/dviprlib.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/japanese/dviprlib.c 2013-05-09 17:02:39.093447201 +0100 +@@ -106,7 +106,7 @@ dviprt_read_S_cfg(dviprt_cfg_t *pcfg,dvi + goto not_cfg; + pcfg->version = rbuf[2] | ((uint)rbuf[3] << 8); + if (pcfg->version > CFG_VERSION) { +- sprintf(dviprt_message_buffer, ++ gs_sprintf(dviprt_message_buffer, + "This *.CFG file is too new version(ver.%u).\n",pcfg->version); + dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1); + return CFG_ERROR_OTHER; +@@ -129,7 +129,7 @@ dviprt_read_S_cfg(dviprt_cfg_t *pcfg,dvi + if (n >= CFG_INTEGER_TYPE_COUNT) { + ptype = "integer"; + unknown_no: +- sprintf(dviprt_message_buffer, ++ gs_sprintf(dviprt_message_buffer, + "Unknown %s type value No.%d is found.\n",ptype,n); + dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1); + return CFG_ERROR_OTHER; +@@ -346,7 +346,7 @@ dviprt_read_QR_cfg(dviprt_cfg_t *pcfg,dv + ptr++; + break; + default: +- sprintf(dviprt_message_buffer,"Unknown format %02X",type); ++ gs_sprintf(dviprt_message_buffer,"Unknown format %02X",type); + dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1); + goto ex_func; + } +@@ -587,7 +587,7 @@ dviprt_readsrc(char *fname,dviprt_cfg_t + while (*pbuf && isspace(*pbuf)) pbuf++; + if (pitem->spec_f) { + dviprt_printcfgerror(&info,NULL,0); +- sprintf(dviprt_message_buffer, ++ gs_sprintf(dviprt_message_buffer, + "Item `%s' is specified twice.\n",pitem->name); + dviprt_printmessage(dviprt_message_buffer,-1); + code = CFG_ERROR_SYNTAX; +@@ -691,7 +691,7 @@ dviprt_readsrc(char *fname,dviprt_cfg_t + code = 0; + for (pitem = dviprt_items;pitem->name;pitem++) { + if (!pitem->spec_f && pitem->req_f) { +- sprintf(dviprt_message_buffer,"%s not found.\n",pitem->name); ++ gs_sprintf(dviprt_message_buffer,"%s not found.\n",pitem->name); + dviprt_printcfgerror(&info,dviprt_message_buffer,-1); + code++; + } +@@ -749,14 +749,14 @@ dviprt_readsrc(char *fname,dviprt_cfg_t + + for (pitem = dviprt_items;pitem->type>=0;pitem++) { + if (pitem->spec_f == 0) { +- sprintf(dviprt_message_buffer,": %s:",pitem->name); ++ gs_sprintf(dviprt_message_buffer,": %s:",pitem->name); + switch (pitem->type) { + case T_INTEGER: + if (pcfg->integer[pitem->no] >= 0) { + uint v = pcfg->integer[pitem->no]; + dviprt_printmessage(fname,-1); + dviprt_printmessage(dviprt_message_buffer,-1); +- sprintf(dviprt_message_buffer," %d\n",v); ++ gs_sprintf(dviprt_message_buffer," %d\n",v); + dviprt_printmessage(dviprt_message_buffer,-1); + } + break; +@@ -802,7 +802,7 @@ dviprt_set_integer(dviprt_cfg_item_t *pi + out_of_range: + dviprt_printtokenerror(pinfo,buf,strlen(buf),ERROR_OUTOFRANGE); + dviprt_printcfgerror(pinfo,"",-1); +- sprintf(dviprt_message_buffer, ++ gs_sprintf(dviprt_message_buffer, + "(%u <= value <= %u).\n",(uint)min,(uint)max); + dviprt_printmessage(dviprt_message_buffer,-1); + return CFG_ERROR_RANGE; +@@ -1108,10 +1108,10 @@ dviprt_set_rpexpr(dviprt_cfg_item_t *pit + pitem->no != CFG_AFTER_BIT_IMAGE) { + unavailable_value: + dviprt_printcfgerror(pinfo,"",-1); +- sprintf(dviprt_message_buffer,"Variable `%c' in ",(int)*pbuf); ++ gs_sprintf(dviprt_message_buffer,"Variable `%c' in ",(int)*pbuf); + dviprt_printmessage(dviprt_message_buffer,-1); + dviprt_printmessage(pbuf,(int)(pend-pbuf)); +- sprintf(dviprt_message_buffer," cannot be used in %s.\n",pitem->name); ++ gs_sprintf(dviprt_message_buffer," cannot be used in %s.\n",pitem->name); + dviprt_printmessage(dviprt_message_buffer,-1); + return CFG_ERROR_RANGE; + } +@@ -1144,7 +1144,7 @@ dviprt_set_rpexpr(dviprt_cfg_item_t *pit + case '^': op = CFG_OP_XOR; break; + default: + dviprt_printcfgerror(pinfo,NULL,0); +- sprintf(dviprt_message_buffer,"Unknown operator %c in ",(int)*pbuf); ++ gs_sprintf(dviprt_message_buffer,"Unknown operator %c in ",(int)*pbuf); + dviprt_printmessage(dviprt_message_buffer,-1); + dviprt_printmessage(pbuf,(int)(pend-pbuf)); + dviprt_printmessage(".\n",-1); +@@ -1520,7 +1520,7 @@ dviprt_printcfgerrorheader(dviprt_cfg_i + dviprt_printmessage(fn,-1); + dviprt_printmessage(": ",-1); + if (pinfo->line_no>0) { +- sprintf(dviprt_message_buffer,"%d: ",pinfo->line_no); ++ gs_sprintf(dviprt_message_buffer,"%d: ",pinfo->line_no); + dviprt_printmessage(dviprt_message_buffer,-1); + } + } +@@ -2210,9 +2210,9 @@ dviprt_output_expr(dviprt_print *pprint, + if (cols == 0) + strcpy(fmtbuf,"%"); + else +- sprintf(fmtbuf,"%%0%d",cols); ++ gs_sprintf(fmtbuf,"%%0%d",cols); + strcat(fmtbuf,f); +- sprintf(valbuf,fmtbuf,stack[stack_p]); ++ gs_sprintf(valbuf,fmtbuf,stack[stack_p]); + cols = strlen(valbuf); + if (fmt & CFG_FMT_ISO_BIT) + valbuf[cols-1] |= 0x10; +diff -up ghostscript-9.07/contrib/japanese/gdevfmlbp.c.gs_sprintf ghostscript-9.07/contrib/japanese/gdevfmlbp.c +--- ghostscript-9.07/contrib/japanese/gdevfmlbp.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/japanese/gdevfmlbp.c 2013-05-09 17:02:39.094447206 +0100 +@@ -112,7 +112,7 @@ gdev_fmlbp_paper_size(gx_device_printer + height_inches = t; + landscape = 1; + } +- sprintf(paper, "%s;%d", ++ gs_sprintf(paper, "%s;%d", + (height_inches >= 15.9 ? PAPER_SIZE_A3 : + height_inches >= 11.8 ? + (width_inches >= 9.2 ? PAPER_SIZE_B4 : PAPER_SIZE_LEGAL) : +@@ -136,7 +136,7 @@ static void goto_xy(FILE *prn_stream,int + + fputc(CEX,prn_stream); + fputc('"',prn_stream); +- sprintf(buff,"%d",x); ++ gs_sprintf((char *)buff,"%d",x); + while (*p) + { + if (!*(p+1)) fputc((*p)+0x30,prn_stream); +@@ -146,7 +146,7 @@ static void goto_xy(FILE *prn_stream,int + } + + p=buff; +- sprintf(buff,"%d",y); ++ gs_sprintf((char *)buff,"%d",y); + while (*p) + { + if (!*(p+1)) fputc((*p)+0x40,prn_stream); +diff -up ghostscript-9.07/contrib/japanese/gdevfmpr.c.gs_sprintf ghostscript-9.07/contrib/japanese/gdevfmpr.c +--- ghostscript-9.07/contrib/japanese/gdevfmpr.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/japanese/gdevfmpr.c 2013-05-09 17:02:39.094447206 +0100 +@@ -184,13 +184,13 @@ fmpr_print_page(gx_device_printer *pdev, + } + out_beg -= (out_beg - out) % bytes_per_column; + +- sprintf(prn_buf, "\033[%da", ++ gs_sprintf(prn_buf, "\033[%da", + (out_beg - out) / bytes_per_column); + prn_puts(pdev, prn_buf); + + /* Dot graphics */ + size = out_end - out_beg + 1; +- sprintf(prn_buf, "\033Q%d W", size / bytes_per_column); ++ gs_sprintf(prn_buf, "\033Q%d W", size / bytes_per_column); + prn_puts(pdev, prn_buf); + prn_write(pdev, out_beg, size); + +diff -up ghostscript-9.07/contrib/japanese/gdevj100.c.gs_sprintf ghostscript-9.07/contrib/japanese/gdevj100.c +--- ghostscript-9.07/contrib/japanese/gdevj100.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/japanese/gdevj100.c 2013-05-09 17:02:39.094447206 +0100 +@@ -128,12 +128,12 @@ jj100_print_page(gx_device_printer *pdev + + /* Vertical tab to the appropriate position. */ + while(skip > 15) { +- sprintf(prn_buf, "\037%c", 16 + 15); ++ gs_sprintf(prn_buf, "\037%c", 16 + 15); + fputs(prn_buf, pdev->file); + skip -= 15; + } + if(skip > 0) { +- sprintf(prn_buf, "\037%c", 16 + skip); ++ gs_sprintf(prn_buf, "\037%c", 16 + skip); + fputs(prn_buf, pdev->file); + } + +@@ -170,13 +170,13 @@ jj100_print_page(gx_device_printer *pdev + out_beg -= (out_beg - out) % (bytes_per_column * 2); + + /* Dot addressing */ +- sprintf(prn_buf, "\033F%04d", ++ gs_sprintf(prn_buf, "\033F%04d", + (out_beg - out) / bytes_per_column / 2); + fputs(prn_buf, pdev->file); + + /* Dot graphics */ + size = out_end - out_beg + 1; +- sprintf(prn_buf, "\034bP,48,%04d.", size / bytes_per_column); ++ gs_sprintf(prn_buf, "\034bP,48,%04d.", size / bytes_per_column); + fputs(prn_buf, pdev->file); + fwrite(out_beg, 1, size, pdev->file); + +diff -up ghostscript-9.07/contrib/japanese/gdevlbp3.c.gs_sprintf ghostscript-9.07/contrib/japanese/gdevlbp3.c +--- ghostscript-9.07/contrib/japanese/gdevlbp3.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/japanese/gdevlbp3.c 2013-05-09 17:02:39.094447206 +0100 +@@ -81,7 +81,7 @@ lbp310PrintPage(gx_device_printer *pDev, + DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.r"); + + /* ----==== Set size ====---- */ +- sprintf(Buf, "0%ld", DataSize); ++ gs_sprintf((char *)Buf, "0%ld", DataSize); + i = (DataSize+strlen(Buf)+1)&1; + /* ----==== escape to LIPS ====---- */ + fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i); +@@ -110,7 +110,7 @@ lbp320PrintPage(gx_device_printer *pDev, + DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.&r"); + + /* ----==== Set size ====---- */ +- sprintf(Buf, "000%ld", DataSize); ++ gs_sprintf((char *)Buf, "000%ld", DataSize); + i = (DataSize+strlen(Buf)+1)&3; + /* ----==== escape to LIPS ====---- */ + fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i); +diff -up ghostscript-9.07/contrib/japanese/gdevmag.c.gs_sprintf ghostscript-9.07/contrib/japanese/gdevmag.c +--- ghostscript-9.07/contrib/japanese/gdevmag.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/japanese/gdevmag.c 2013-05-09 17:02:39.094447206 +0100 +@@ -137,8 +137,8 @@ mag_print_page(gx_device_printer *pdev, + + if (user == 0) user = "Unknown"; + strcpy(check,magic); +- sprintf(check+strlen(check),"%-18s",user); +- sprintf(check+31," Ghostscript with %s driver\x1a", pdev->dname); ++ gs_sprintf(check+strlen(check),"%-18s",user); ++ gs_sprintf(check+31," Ghostscript with %s driver\x1a", pdev->dname); + + /* check sizes of flag and pixel data. */ + pixel_bytes = 0; +diff -up ghostscript-9.07/contrib/japanese/gdevnpdl.c.gs_sprintf ghostscript-9.07/contrib/japanese/gdevnpdl.c +--- ghostscript-9.07/contrib/japanese/gdevnpdl.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/japanese/gdevnpdl.c 2013-05-09 17:02:39.094447206 +0100 +@@ -592,31 +592,31 @@ npdl_print_page_copies(gx_device_printer + /* Check paper size */ + switch (npdl_get_paper_size((gx_device *) pdev)) { + case PAPER_SIZE_POSTCARD: +- sprintf(paper_command, "PC"); ++ gs_sprintf(paper_command, "PC"); + break; + case PAPER_SIZE_A5: +- sprintf(paper_command, "A5"); ++ gs_sprintf(paper_command, "A5"); + break; + case PAPER_SIZE_A4: +- sprintf(paper_command, "A4"); ++ gs_sprintf(paper_command, "A4"); + break; + case PAPER_SIZE_A3: +- sprintf(paper_command, "A3"); ++ gs_sprintf(paper_command, "A3"); + break; + case PAPER_SIZE_B5: +- sprintf(paper_command, "B5"); ++ gs_sprintf(paper_command, "B5"); + break; + case PAPER_SIZE_B4: +- sprintf(paper_command, "B4"); ++ gs_sprintf(paper_command, "B4"); + break; + case PAPER_SIZE_LETTER: +- sprintf(paper_command, "LT"); ++ gs_sprintf(paper_command, "LT"); + break; + case PAPER_SIZE_ENV4: +- sprintf(paper_command, "ENV4"); ++ gs_sprintf(paper_command, "ENV4"); + break; + case PAPER_SIZE_BPOSTCARD: +- sprintf(paper_command, "UPPC"); ++ gs_sprintf(paper_command, "UPPC"); + break; + } + +diff -up ghostscript-9.07/contrib/lips4/gdevl4r.c.gs_sprintf ghostscript-9.07/contrib/lips4/gdevl4r.c +--- ghostscript-9.07/contrib/lips4/gdevl4r.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/lips4/gdevl4r.c 2013-05-09 17:02:39.095447210 +0100 +@@ -775,9 +775,9 @@ lips2p_image_out(gx_device_printer * pde + move_cap(pdev, prn_stream, x, y); + + Len = lips_mode3format_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height); +- sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI, ++ gs_sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI, + width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch); +- sprintf(comp_str, "%c%d;%d;%d;9;%d.r", LIPS_CSI, ++ gs_sprintf(comp_str, "%c%d;%d;%d;9;%d.r", LIPS_CSI, + Len, width / 8, (int)pdev->x_pixels_per_inch, height); + + if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) { +@@ -806,11 +806,11 @@ lips4_image_out(gx_device_printer * pdev + Len = lips_packbits_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height); + Len_rle = lips_rle_encode(lprn->TmpBuf, lprn->CompBuf2, width / 8 * height); + +- sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI, ++ gs_sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI, + width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch); + + if (Len < Len_rle) { +- sprintf(comp_str, "%c%d;%d;%d;11;%d.r", LIPS_CSI, ++ gs_sprintf(comp_str, "%c%d;%d;%d;11;%d.r", LIPS_CSI, + Len, width / 8, (int)pdev->x_pixels_per_inch, height); + if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) { + fprintf(prn_stream, "%s", comp_str); +@@ -821,7 +821,7 @@ lips4_image_out(gx_device_printer * pdev + fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream); + } + } else { +- sprintf(comp_str, "%c%d;%d;%d;10;%d.r", LIPS_CSI, ++ gs_sprintf(comp_str, "%c%d;%d;%d;10;%d.r", LIPS_CSI, + Len, width / 8, (int)pdev->x_pixels_per_inch, height); + if (Len_rle < width / 8 * height - strlen(comp_str) + strlen(raw_str)) { + fprintf(prn_stream, "%s", comp_str); +diff -up ghostscript-9.07/contrib/lips4/gdevl4v.c.gs_sprintf ghostscript-9.07/contrib/lips4/gdevl4v.c +--- ghostscript-9.07/contrib/lips4/gdevl4v.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/lips4/gdevl4v.c 2013-05-09 17:02:39.095447210 +0100 +@@ -459,17 +459,17 @@ lips4v_set_cap(gx_device * dev, int x, i + int dy = y - pdev->prev_y; + + if (dx > 0) { +- sprintf(cap, "%c%da", LIPS_CSI, dx); ++ gs_sprintf(cap, "%c%da", LIPS_CSI, dx); + lputs(s, cap); + } else if (dx < 0) { +- sprintf(cap, "%c%dj", LIPS_CSI, -dx); ++ gs_sprintf(cap, "%c%dj", LIPS_CSI, -dx); + lputs(s, cap); + } + if (dy > 0) { +- sprintf(cap, "%c%dk", LIPS_CSI, dy); ++ gs_sprintf(cap, "%c%dk", LIPS_CSI, dy); + lputs(s, cap); + } else if (dy < 0) { +- sprintf(cap, "%c%de", LIPS_CSI, -dy); ++ gs_sprintf(cap, "%c%de", LIPS_CSI, -dy); + lputs(s, cap); + } + pdev->prev_x = x; +@@ -544,10 +544,10 @@ lips4v_copy_text_char(gx_device * dev, c + if (download) { + if (ccode % 128 == 0 && ccode == pdev->count) { + /* ʸ�����å���Ͽ���̿�� */ +- sprintf(cset_sub, "%c%dx%c", LIPS_DCS, ccode / 128, LIPS_ST); ++ gs_sprintf(cset_sub, "%c%dx%c", LIPS_DCS, ccode / 128, LIPS_ST); + lputs(s, cset_sub); + /* ʸ�����å���Ͽ̿�� */ +- sprintf(cset, ++ gs_sprintf(cset, + "%c%d;1;0;0;3840;8;400;100;0;0;200;%d;%d;0;0;;;;;%d.p", + LIPS_CSI, + size + 9, cell_length, /* Cell Width */ +@@ -556,7 +556,7 @@ lips4v_copy_text_char(gx_device * dev, c + lputs(s, cset); + } else { + /* 1ʸ����Ͽ̿�� */ +- sprintf(cset, ++ gs_sprintf(cset, + "%c%d;%d;8;%d.q", LIPS_CSI, + size + 9, ccode / 128, (int)dev->x_pixels_per_inch); + lputs(s, cset); +@@ -575,13 +575,13 @@ lips4v_copy_text_char(gx_device * dev, c + /* ʸ�����åȡ����������ֹ�����̿��2 */ + if (download) { + if (pdev->current_font != ccode / 128) { +- sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128); ++ gs_sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128); + lputs(s, cset_number); + pdev->current_font = ccode / 128; + } + } else { + if (pdev->current_font != ccode / 128) { +- sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128); ++ gs_sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128); + lputs(s, cset_number); + pdev->current_font = ccode / 128; + } +@@ -592,7 +592,7 @@ lips4v_copy_text_char(gx_device * dev, c + if (pdev->color_info.depth == 8) { + sputc(s, LIPS_CSI); + lputs(s, "?10;2;"); +- sprintf(text_color, "%d", ++ gs_sprintf(text_color, "%d", + (int)(pdev->color_info.max_gray - pdev->current_color)); + } else { + int r = (pdev->current_color >> 16) * 1000.0 / 255.0; +@@ -601,7 +601,7 @@ lips4v_copy_text_char(gx_device * dev, c + + sputc(s, LIPS_CSI); + lputs(s, "?10;;"); +- sprintf(text_color, "%d;%d;%d", r, g, b); ++ gs_sprintf(text_color, "%d;%d;%d", r, g, b); + } + lputs(s, text_color); + lputs(s, "%p"); +@@ -717,16 +717,16 @@ lips4v_beginpage(gx_device_vector * vdev + lputs(s, "@PJL SET RESOLUTION = QUICK\n"); + lputs(s, l4v_file_header2); + if (pdev->toner_density) { +- sprintf(toner_d, "@PJL SET TONER-DENSITY=%d\n", ++ gs_sprintf(toner_d, "@PJL SET TONER-DENSITY=%d\n", + pdev->toner_density); + lputs(s, toner_d); + } + if (pdev->toner_saving_set) { + lputs(s, "@PJL SET TONER-SAVING="); + if (pdev->toner_saving) +- sprintf(toner_s, "ON\n"); ++ gs_sprintf(toner_s, "ON\n"); + else +- sprintf(toner_s, "OFF\n"); ++ gs_sprintf(toner_s, "OFF\n"); + lputs(s, toner_s); + } + lputs(s, l4v_file_header3); +@@ -737,7 +737,7 @@ lips4v_beginpage(gx_device_vector * vdev + return_error(gs_error_rangecheck); + + /* set reaolution (dpi) */ +- sprintf(dpi_char, "%d", dpi); ++ gs_sprintf(dpi_char, "%d", dpi); + lputs(s, dpi_char); + + if (pdev->color_info.depth == 8) +@@ -746,7 +746,7 @@ lips4v_beginpage(gx_device_vector * vdev + lputs(s, l4vcolor_file_header); + + /* username */ +- sprintf(username, "%c2y%s%c", LIPS_DCS, pdev->Username, LIPS_ST); ++ gs_sprintf(username, "%c2y%s%c", LIPS_DCS, pdev->Username, LIPS_ST); + lputs(s, username); + } + if (strcmp(pdev->mediaType, "PlainPaper") == 0) { +@@ -773,13 +773,13 @@ lips4v_beginpage(gx_device_vector * vdev + && strcmp(pdev->mediaType, LIPS_MEDIATYPE_DEFAULT) != 0)) { + /* Use ManualFeed */ + if (pdev->prev_feed_mode != 10) { +- sprintf(feedmode, "%c10q", LIPS_CSI); ++ gs_sprintf(feedmode, "%c10q", LIPS_CSI); + lputs(s, feedmode); + pdev->prev_feed_mode = 10; + } + } else { + if (pdev->prev_feed_mode != pdev->cassetFeed) { +- sprintf(feedmode, "%c%dq", LIPS_CSI, pdev->cassetFeed); ++ gs_sprintf(feedmode, "%c%dq", LIPS_CSI, pdev->cassetFeed); + lputs(s, feedmode); + pdev->prev_feed_mode = pdev->cassetFeed; + } +@@ -791,10 +791,10 @@ lips4v_beginpage(gx_device_vector * vdev + if (pdev->prev_paper_size != paper_size) { + if (paper_size == USER_SIZE) { + /* modified by shige 06/27 2003 +- sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */ ++ gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */ + /* modified by shige 11/09 2003 +- sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */ +- sprintf(paper, "%c80;%d;%dp", LIPS_CSI, ++ gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */ ++ gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, + (height * 10 > LIPS_HEIGHT_MAX_720)? + LIPS_HEIGHT_MAX_720 : (height * 10), + (width * 10 > LIPS_WIDTH_MAX_720)? +@@ -802,27 +802,27 @@ lips4v_beginpage(gx_device_vector * vdev + lputs(s, paper); + } else if (paper_size == USER_SIZE + LANDSCAPE) { + /* modified by shige 06/27 2003 +- sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */ ++ gs_sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */ + /* modified by shige 11/09 2003 +- sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */ +- sprintf(paper, "%c80;%d;%dp", LIPS_CSI, ++ gs_sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */ ++ gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, + (width * 10 > LIPS_HEIGHT_MAX_720)? + LIPS_HEIGHT_MAX_720 : (width * 10), + (height * 10 > LIPS_WIDTH_MAX_720)? + LIPS_WIDTH_MAX_720 : (height * 10)); + lputs(s, paper); + } else { +- sprintf(paper, "%c%dp", LIPS_CSI, paper_size); ++ gs_sprintf(paper, "%c%dp", LIPS_CSI, paper_size); + lputs(s, paper); + } + } else if (paper_size == USER_SIZE) { + if (pdev->prev_paper_width != width || + pdev->prev_paper_height != height) + /* modified by shige 06/27 2003 +- sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */ ++ gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */ + /* modified by shige 11/09 2003 +- sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */ +- sprintf(paper, "%c80;%d;%dp", LIPS_CSI, ++ gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */ ++ gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, + (height * 10 > LIPS_HEIGHT_MAX_720)? + LIPS_HEIGHT_MAX_720 : (height * 10), + (width * 10 > LIPS_WIDTH_MAX_720)? +@@ -832,10 +832,10 @@ lips4v_beginpage(gx_device_vector * vdev + if (pdev->prev_paper_width != width || + pdev->prev_paper_height != height) + /* modified by shige 06/27 2003 +- sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */ ++ gs_sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */ + /* modified by shige 11/09 2003 +- sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */ +- sprintf(paper, "%c80;%d;%dp", LIPS_CSI, ++ gs_sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */ ++ gs_sprintf(paper, "%c80;%d;%dp", LIPS_CSI, + (width * 10 > LIPS_HEIGHT_MAX_720)? + LIPS_HEIGHT_MAX_720 : (width * 10), + (height * 10 > LIPS_WIDTH_MAX_720)? +@@ -847,32 +847,32 @@ lips4v_beginpage(gx_device_vector * vdev + pdev->prev_paper_height = height; + + if (pdev->faceup) { +- sprintf(faceup_char, "%c11;12;12~", LIPS_CSI); ++ gs_sprintf(faceup_char, "%c11;12;12~", LIPS_CSI); + lputs(s, faceup_char); + } + /* N-up Printing Setting */ + if (pdev->first_page) { + if (pdev->nup != 1) { +- sprintf(nup_char, "%c%d1;;%do", LIPS_CSI, pdev->nup, paper_size); ++ gs_sprintf(nup_char, "%c%d1;;%do", LIPS_CSI, pdev->nup, paper_size); + lputs(s, nup_char); + } + } + /* Duplex Setting */ + if (dupset && dup) { + if (pdev->prev_duplex_mode == 0 || pdev->prev_duplex_mode == 1) { +- sprintf(duplex_char, "%c2;#x", LIPS_CSI); /* duplex */ ++ gs_sprintf(duplex_char, "%c2;#x", LIPS_CSI); /* duplex */ + lputs(s, duplex_char); + if (!tum) { + /* long edge binding */ + if (pdev->prev_duplex_mode != 2) { +- sprintf(tumble_char, "%c0;#w", LIPS_CSI); ++ gs_sprintf(tumble_char, "%c0;#w", LIPS_CSI); + lputs(s, tumble_char); + } + pdev->prev_duplex_mode = 2; + } else { + /* short edge binding */ + if (pdev->prev_duplex_mode != 3) { +- sprintf(tumble_char, "%c2;#w", LIPS_CSI); ++ gs_sprintf(tumble_char, "%c2;#w", LIPS_CSI); + lputs(s, tumble_char); + } + pdev->prev_duplex_mode = 3; +@@ -880,7 +880,7 @@ lips4v_beginpage(gx_device_vector * vdev + } + } else if (dupset && !dup) { + if (pdev->prev_duplex_mode != 1) { +- sprintf(duplex_char, "%c0;#x", LIPS_CSI); /* simplex */ ++ gs_sprintf(duplex_char, "%c0;#x", LIPS_CSI); /* simplex */ + lputs(s, duplex_char); + } + pdev->prev_duplex_mode = 1; +@@ -893,9 +893,9 @@ lips4v_beginpage(gx_device_vector * vdev + /* size unit (dpi) */ + sputc(s, LIPS_CSI); + lputs(s, "11h"); +- sprintf(unit, "%c?7;%d I", LIPS_CSI, (int)pdev->x_pixels_per_inch); ++ gs_sprintf(unit, "%c?7;%d I", LIPS_CSI, (int)pdev->x_pixels_per_inch); + lputs(s, unit); +- sprintf(page_header, "%c[0&}#%c", LIPS_ESC, LIPS_IS2); ++ gs_sprintf(page_header, "%c[0&}#%c", LIPS_ESC, LIPS_IS2); + lputs(s, page_header); /* vector mode */ + + lputs(s, "!0"); /* size unit (dpi) */ +@@ -904,10 +904,10 @@ lips4v_beginpage(gx_device_vector * vdev + sputc(s, LIPS_IS2); + + if (pdev->color_info.depth == 8) { +- sprintf(l4vmono_page_header, "!13%c$%c", LIPS_IS2, LIPS_IS2); ++ gs_sprintf(l4vmono_page_header, "!13%c$%c", LIPS_IS2, LIPS_IS2); + lputs(s, l4vmono_page_header); + } else { +- sprintf(l4vcolor_page_header, "!11%c$%c", LIPS_IS2, LIPS_IS2); ++ gs_sprintf(l4vcolor_page_header, "!11%c$%c", LIPS_IS2, LIPS_IS2); + lputs(s, l4vcolor_page_header); + } + +@@ -1010,7 +1010,7 @@ lips4v_setlinecap(gx_device_vector * vde + break; + } + /* ��ü��������̿�� */ +- sprintf(c, "}E%d%c", line_cap, LIPS_IS2); ++ gs_sprintf(c, "}E%d%c", line_cap, LIPS_IS2); + lputs(s, c); + + pdev->linecap = cap; +@@ -1050,7 +1050,7 @@ lips4v_setlinejoin(gx_device_vector * vd + break; + } + +- sprintf(c, "}F%d%c", lips_join, LIPS_IS2); ++ gs_sprintf(c, "}F%d%c", lips_join, LIPS_IS2); + lputs(s, c); + + return 0; +@@ -1486,7 +1486,7 @@ lips4v_output_page(gx_device * dev, int + if (num_copies > 255) + num_copies = 255; + if (pdev->prev_num_copies != num_copies) { +- sprintf(str, "%c%dv", LIPS_CSI, num_copies); ++ gs_sprintf(str, "%c%dv", LIPS_CSI, num_copies); + lputs(s, str); + pdev->prev_num_copies = num_copies; + } +diff -up ghostscript-9.07/contrib/pcl3/src/gdevpcl3.c.gs_sprintf ghostscript-9.07/contrib/pcl3/src/gdevpcl3.c +--- ghostscript-9.07/contrib/pcl3/src/gdevpcl3.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/contrib/pcl3/src/gdevpcl3.c 2013-05-09 17:02:39.095447210 +0100 +@@ -302,7 +302,7 @@ static void get_string_for_int(int in_va + else { + static char buffer[22]; /* Must be sufficient for an 'int' */ + +- sprintf(buffer, "%d", in_value); ++ gs_sprintf(buffer, "%d", in_value); + assert(strlen(buffer) < sizeof(buffer)); + out_value->data = (const byte *)buffer; + out_value->size = strlen(buffer); +diff -up ghostscript-9.07/cups/gdevcups.c.gs_sprintf ghostscript-9.07/cups/gdevcups.c +--- ghostscript-9.07/cups/gdevcups.c.gs_sprintf 2013-05-09 17:02:39.048447008 +0100 ++++ ghostscript-9.07/cups/gdevcups.c 2013-05-09 17:02:39.096447214 +0100 +@@ -60,6 +60,9 @@ + * cups_print_planar() - Print a page of planar pixels. + */ + ++/* prevent gp.h redefining fopen */ ++#define sprintf sprintf ++ + /* + * Include necessary headers... + */ +diff -up ghostscript-9.07/base/Makefile.in.gs_sprintf ghostscript-9.07/base/Makefile.in +--- ghostscript-9.07/base/Makefile.in.gs_sprintf 2013-05-09 17:02:46.190477741 +0100 ++++ ghostscript-9.07/base/Makefile.in 2013-05-09 17:03:22.377633508 +0100 +@@ -302,6 +302,8 @@ LCUPSISRCDIR=cups + CUPS_CC=$(CC) + + ++TRIOSRCDIR=trio ++ + # Define how to build the library archives. (These are not used in any + # standard configuration.) + +@@ -583,6 +585,7 @@ MAKEDIRSTOP= + INSTALL_CONTRIB=@INSTALL_CONTRIB@ + include $(GLSRCDIR)/unixhead.mak + include $(GLSRCDIR)/gs.mak ++include $(GLSRCDIR)/trio.mak + # psromfs.mak must precede lib.mak + include $(PSSRCDIR)/psromfs.mak + include $(GLSRCDIR)/lib.mak +diff -up ghostscript-9.07/psi/dmmain.c.gs_sprintf ghostscript-9.07/psi/dmmain.c +--- ghostscript-9.07/psi/dmmain.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/dmmain.c 2013-05-09 17:02:39.096447214 +0100 +@@ -644,8 +644,8 @@ void main(void) + argv[1] = ddevice; + argv[2] = dformat; + +- sprintf(ddevice, "-sDEVICE=display"); +- sprintf(dformat, "-dDisplayFormat=%d", display_format); ++ gs_sprintf(ddevice, "-sDEVICE=display"); ++ gs_sprintf(dformat, "-dDisplayFormat=%d", display_format); + + /* Run Ghostscript */ + if (gsapi_new_instance(&instance, NULL) < 0) +diff -up ghostscript-9.07/psi/dpmain.c.gs_sprintf ghostscript-9.07/psi/dpmain.c +--- ghostscript-9.07/psi/dpmain.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/dpmain.c 2013-05-09 17:02:39.097447219 +0100 +@@ -100,9 +100,9 @@ gs_free_dll(void) + return TRUE; + rc = DosFreeModule(gsdll.hmodule); + if (rc) { +- sprintf(buf, "DosFreeModule returns %d\n", rc); ++ gs_sprintf(buf, "DosFreeModule returns %d\n", rc); + gs_addmess(buf); +- sprintf(buf, "Unloaded GSDLL\n\n"); ++ gs_sprintf(buf, "Unloaded GSDLL\n\n"); + gs_addmess(buf); + } + return !rc; +@@ -150,7 +150,7 @@ gs_load_dll(void) + dllname = szDllName; + #ifdef DEBUG + if (debug) { +- sprintf(buf, "Trying to load %s\n", dllname); ++ gs_sprintf(buf, "Trying to load %s\n", dllname); + gs_addmess(buf); + } + #endif +@@ -172,7 +172,7 @@ gs_load_dll(void) + dllname = fullname; + #ifdef DEBUG + if (debug) { +- sprintf(buf, "Trying to load %s\n", dllname); ++ gs_sprintf(buf, "Trying to load %s\n", dllname); + gs_addmess(buf); + } + #endif +@@ -183,7 +183,7 @@ gs_load_dll(void) + dllname = shortname; + #ifdef DEBUG + if (debug) { +- sprintf(buf, "Trying to load %s\n", dllname); ++ gs_sprintf(buf, "Trying to load %s\n", dllname); + gs_addmess(buf); + } + #endif +@@ -197,21 +197,21 @@ gs_load_dll(void) + #endif + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_REVISION", + (PFN *) (&gsdll.revision))) != 0) { +- sprintf(buf, "Can't find GSAPI_REVISION, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_REVISION, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + /* check DLL version */ + if (gsdll.revision(&rv, sizeof(rv)) != 0) { +- sprintf(buf, "Unable to identify Ghostscript DLL revision - it must be newer than needed.\n"); ++ gs_sprintf(buf, "Unable to identify Ghostscript DLL revision - it must be newer than needed.\n"); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + + if (rv.revision != GS_REVISION) { +- sprintf(buf, "Wrong version of DLL found.\n Found version %ld\n Need version %ld\n", rv.revision, (long)GS_REVISION); ++ gs_sprintf(buf, "Wrong version of DLL found.\n Found version %ld\n Need version %ld\n", rv.revision, (long)GS_REVISION); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; +@@ -219,35 +219,35 @@ gs_load_dll(void) + + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_NEW_INSTANCE", + (PFN *) (&gsdll.new_instance))) != 0) { +- sprintf(buf, "Can't find GSAPI_NEW_INSTANCE, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_NEW_INSTANCE, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_DELETE_INSTANCE", + (PFN *) (&gsdll.delete_instance))) != 0) { +- sprintf(buf, "Can't find GSAPI_DELETE_INSTANCE, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_DELETE_INSTANCE, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_STDIO", + (PFN *) (&gsdll.set_stdio))) != 0) { +- sprintf(buf, "Can't find GSAPI_SET_STDIO, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_SET_STDIO, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_DISPLAY_CALLBACK", + (PFN *) (&gsdll.set_display_callback))) != 0) { +- sprintf(buf, "Can't find GSAPI_SET_DISPLAY_CALLBACK, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_SET_DISPLAY_CALLBACK, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_SET_POLL", + (PFN *) (&gsdll.set_poll))) != 0) { +- sprintf(buf, "Can't find GSAPI_SET_POLL, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_SET_POLL, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; +@@ -255,27 +255,27 @@ gs_load_dll(void) + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, + "GSAPI_INIT_WITH_ARGS", + (PFN *) (&gsdll.init_with_args))) != 0) { +- sprintf(buf, "Can't find GSAPI_INIT_WITH_ARGS, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_INIT_WITH_ARGS, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_RUN_STRING", + (PFN *) (&gsdll.run_string))) != 0) { +- sprintf(buf, "Can't find GSAPI_RUN_STRING, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_RUN_STRING, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + if ((rc = DosQueryProcAddr(gsdll.hmodule, 0, "GSAPI_EXIT", + (PFN *) (&gsdll.exit))) != 0) { +- sprintf(buf, "Can't find GSAPI_EXIT, rc = %d\n", rc); ++ gs_sprintf(buf, "Can't find GSAPI_EXIT, rc = %d\n", rc); + gs_addmess(buf); + gs_load_dll_cleanup(); + return FALSE; + } + } else { +- sprintf(buf, "Can't load Ghostscript DLL %s \nDosLoadModule rc = %d\n", ++ gs_sprintf(buf, "Can't load Ghostscript DLL %s \nDosLoadModule rc = %d\n", + szDllName, rc); + gs_addmess(buf); + gs_load_dll_cleanup(); +@@ -373,10 +373,10 @@ static int run_gspmdrv(IMAGE *img) + if (debug) + fprintf(stdout, "run_gspmdrv: starting\n"); + #endif +- sprintf(id, ID_NAME, img->pid, (ULONG)img->device); ++ gs_sprintf(id, ID_NAME, img->pid, (ULONG)img->device); + + /* Create termination queue - used to find out when gspmdrv terminates */ +- sprintf(term_queue_name, "\\QUEUES\\TERMQ_%s", id); ++ gs_sprintf(term_queue_name, "\\QUEUES\\TERMQ_%s", id); + if (DosCreateQueue(&(img->term_queue), QUE_FIFO, term_queue_name)) { + fprintf(stdout, "run_gspmdrv: failed to create termination queue\n"); + return e_limitcheck; +@@ -404,7 +404,7 @@ static int run_gspmdrv(IMAGE *img) + /* arguments are: */ + /* (1) -d (display) option */ + /* (2) id string */ +- sprintf(arg, "-d %s", id); ++ gs_sprintf(arg, "-d %s", id); + + /* because gspmdrv.exe is a different EXE type to gs.exe, + * we must use start session not DosExecPgm() */ +@@ -592,17 +592,17 @@ int display_open(void *handle, void *dev + return e_limitcheck; + } + img->pid = pppib->pib_ulppid; /* use parent (CMD.EXE) pid */ +- sprintf(id, ID_NAME, img->pid, (ULONG) img->device); ++ gs_sprintf(id, ID_NAME, img->pid, (ULONG) img->device); + + /* Create update event semaphore */ +- sprintf(name, SYNC_NAME, id); ++ gs_sprintf(name, SYNC_NAME, id); + if (DosCreateEventSem(name, &(img->sync_event), 0, FALSE)) { + fprintf(stdout, "display_open: failed to create event semaphore %s\n", name); + return e_limitcheck; + } + /* Create mutex - used for preventing gspmdrv from accessing */ + /* bitmap while we are changing the bitmap size. Initially unowned. */ +- sprintf(name, MUTEX_NAME, id); ++ gs_sprintf(name, MUTEX_NAME, id); + if (DosCreateMutexSem(name, &(img->bmp_mutex), 0, FALSE)) { + DosCloseEventSem(img->sync_event); + fprintf(stdout, "display_open: failed to create mutex semaphore %s\n", name); +@@ -612,7 +612,7 @@ int display_open(void *handle, void *dev + /* Shared memory is common to all processes so we don't want to + * allocate too much. + */ +- sprintf(name, SHARED_NAME, id); ++ gs_sprintf(name, SHARED_NAME, id); + if (DosAllocSharedMem((PPVOID) & img->bitmap, name, + 13 * 1024 * 1024, PAG_READ | PAG_WRITE)) { + fprintf(stdout, "display_open: failed allocating shared BMP memory %s\n", name); +@@ -1020,7 +1020,7 @@ main(int argc, char *argv[]) + else if (depth >= 4) + format = DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | + DISPLAY_DEPTH_4 | DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST; +- sprintf(dformat, "-dDisplayFormat=%d", format); ++ gs_sprintf(dformat, "-dDisplayFormat=%d", format); + } + nargc = argc + 1; + +diff -up ghostscript-9.07/psi/dscparse.c.gs_sprintf ghostscript-9.07/psi/dscparse.c +--- ghostscript-9.07/psi/dscparse.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/dscparse.c 2013-05-09 17:02:39.097447219 +0100 +@@ -38,7 +38,7 @@ + % %%ViewingOrientation: xx xy yx yy + */ + +-#include /* for sprintf(), not file I/O */ ++#include /* for sprintf(), not file I/O */ + #include + #include + #include +@@ -584,7 +584,7 @@ dsc_fixup(CDSC *dsc) + /* make sure all pages have a label */ + for (i=0; ipage_count; i++) { + if (strlen(dsc->page[i].label) == 0) { +- sprintf(buf, "%d", i+1); ++ gs_sprintf(buf, "%d", i+1); + if ((dsc->page[i].label = dsc_alloc_string(dsc, buf, (int)strlen(buf))) + == (char *)NULL) + return CDSC_ERROR; /* no memory */ +@@ -1178,7 +1178,7 @@ dsc_unknown(CDSC *dsc) + if (dsc->debug_print_fn) { + char line[DSC_LINE_LENGTH]; + unsigned int length = min(DSC_LINE_LENGTH-1, dsc->line_length); +- sprintf(line, "Unknown in %s section at line %d:\n ", ++ gs_sprintf(line, "Unknown in %s section at line %d:\n ", + dsc_scan_section_name[dsc->scan_section], dsc->line_count); + dsc_debug_print(dsc, line); + strncpy(line, dsc->line, length); +@@ -2669,7 +2669,7 @@ dsc_check_match_prompt(CDSC *dsc, const + strncpy(buf, dsc->line, dsc->line_length); + buf[dsc->line_length] = '\0'; + } +- sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str); ++ gs_sprintf(buf+strlen(buf), "\n%%%%Begin%.40s: / %%%%End%.40s\n", str, str); + return dsc_error(dsc, CDSC_MESSAGE_BEGIN_END, buf, (int)strlen(buf)); + } + return CDSC_RESPONSE_CANCEL; +diff -up ghostscript-9.07/psi/dwimg.c.gs_sprintf ghostscript-9.07/psi/dwimg.c +--- ghostscript-9.07/psi/dwimg.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/dwimg.c 2013-05-09 17:02:39.098447223 +0100 +@@ -36,6 +36,11 @@ + + #define STRICT + #include ++ ++ ++/* prevent gp.h redefining sprintf */ ++#define sprintf sprintf ++ + #include "stdio_.h" + + #include "dwres.h" +diff -up ghostscript-9.07/psi/dwmainc.c.gs_sprintf ghostscript-9.07/psi/dwmainc.c +--- ghostscript-9.07/psi/dwmainc.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/dwmainc.c 2013-05-09 17:02:39.098447223 +0100 +@@ -13,6 +13,8 @@ + CA 94903, U.S.A., +1(415)492-9861, for further information. + */ + ++/* prevent gp.h redefining sprintf */ ++#define sprintf sprintf + + /* dwmainc.c */ + +diff -up ghostscript-9.07/psi/dxmain.c.gs_sprintf ghostscript-9.07/psi/dxmain.c +--- ghostscript-9.07/psi/dxmain.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/dxmain.c 2013-05-09 17:02:39.098447223 +0100 +@@ -1160,7 +1160,7 @@ int main(int argc, char *argv[]) + use_gui = gtk_init_check(&argc, &argv); + + /* insert display device parameters as first arguments */ +- sprintf(dformat, "-dDisplayFormat=%d", ++ gs_sprintf(dformat, "-dDisplayFormat=%d", + DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | + DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST); + nargc = argc + 1; +diff -up ghostscript-9.07/psi/int.mak.gs_sprintf ghostscript-9.07/psi/int.mak +--- ghostscript-9.07/psi/int.mak.gs_sprintf 2013-05-09 17:02:39.018446879 +0100 ++++ ghostscript-9.07/psi/int.mak 2013-05-09 17:02:39.098447223 +0100 +@@ -651,7 +651,7 @@ $(PSOBJ)zdscpars.$(OBJ) : $(PSSRC)zdscpa + $(gsstruct_h) + $(PSCC) $(PSO_)zdscpars.$(OBJ) $(C_) $(PSSRC)zdscpars.c + +-$(PSOBJ)dscparse.$(OBJ) : $(PSSRC)dscparse.c $(dscparse_h) ++$(PSOBJ)dscparse.$(OBJ) : $(PSSRC)dscparse.c $(dscparse_h) $(stdio__h) + $(PSCC) $(PSO_)dscparse.$(OBJ) $(C_) $(PSSRC)dscparse.c + + dscparse_=$(PSOBJ)zdscpars.$(OBJ) $(PSOBJ)dscparse.$(OBJ) +diff -up ghostscript-9.07/psi/iparam.c.gs_sprintf ghostscript-9.07/psi/iparam.c +--- ghostscript-9.07/psi/iparam.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/iparam.c 2013-05-09 17:02:39.099447227 +0100 +@@ -65,7 +65,7 @@ ref_to_key(const ref * pref, gs_param_ke + int len; + byte *buf; + +- sprintf(istr, "%"PRIpsint, pref->value.intval); ++ gs_sprintf(istr, "%"PRIpsint, pref->value.intval); + len = strlen(istr); + /* GC will take care of freeing this: */ + buf = gs_alloc_string(plist->memory, len, "ref_to_key"); +diff -up ghostscript-9.07/psi/iutil2.c.gs_sprintf ghostscript-9.07/psi/iutil2.c +--- ghostscript-9.07/psi/iutil2.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/iutil2.c 2013-05-09 17:02:39.099447227 +0100 +@@ -56,7 +56,7 @@ param_read_password(gs_param_list * plis + code = param_read_long(plist, kstr, &ipass); + if (code != 0) /* error or missing */ + return code; +- sprintf((char *)ppass->data, "%ld", ipass); ++ gs_sprintf((char *)ppass->data, "%ld", ipass); + ppass->size = strlen((char *)ppass->data); + return 0; + } +diff -up ghostscript-9.07/psi/iutil.c.gs_sprintf ghostscript-9.07/psi/iutil.c +--- ghostscript-9.07/psi/iutil.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/iutil.c 2013-05-09 17:02:39.099447227 +0100 +@@ -340,10 +340,10 @@ obj_cvp(const ref * op, byte * str, uint + float value = op->value.realval; + float scanned; + +- sprintf(buf, "%g", value); ++ gs_sprintf(buf, "%g", value); + sscanf(buf, "%f", &scanned); + if (scanned != value) +- sprintf(buf, "%.9g", value); ++ gs_sprintf(buf, "%.9g", value); + ensure_dot(buf); + goto rs; + } +@@ -494,7 +494,7 @@ other: + data = (const byte *)(op->value.boolval ? "true" : "false"); + break; + case t_integer: +- sprintf(buf, "%"PRIpsint, op->value.intval); ++ gs_sprintf(buf, "%"PRIpsint, op->value.intval); + break; + case t_string: + check_read(*op); +@@ -529,7 +529,7 @@ other: + break; + } + /* Internal operator, no name. */ +- sprintf(buf, "@0x%lx", (ulong) op->value.opproc); ++ gs_sprintf(buf, "@0x%lx", (ulong) op->value.opproc); + break; + } + case t_real: +@@ -542,7 +542,7 @@ other: + if (op->value.realval == (float)0.0001) { + strcpy(buf, "0.0001"); + } else { +- sprintf(buf, "%g", op->value.realval); ++ gs_sprintf(buf, "%g", op->value.realval); + } + ensure_dot(buf); + break; +@@ -573,9 +573,9 @@ ensure_dot(char *buf) + sscanf(pe + 1, "%d", &i); + /* MSVC .net 2005 express doesn't support "%+02d" */ + if (i >= 0) +- sprintf(pe + 1, "+%02d", i); ++ gs_sprintf(pe + 1, "+%02d", i); + else +- sprintf(pe + 1, "-%02d", -i); ++ gs_sprintf(pe + 1, "-%02d", -i); + } else if (strchr(buf, '.') == NULL) { + strcat(buf, ".0"); + } +diff -up ghostscript-9.07/psi/msvc.mak.gs_sprintf ghostscript-9.07/psi/msvc.mak +--- ghostscript-9.07/psi/msvc.mak.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/msvc.mak 2013-05-09 17:02:39.099447227 +0100 +@@ -332,6 +332,10 @@ TIFFCONFIG_SUFFIX=.vc + TIFFPLATFORM=win32 + !endif + ++!ifndef TRIOSRCDIR ++TRIOSRCDIR=trio ++!endif ++ + # Define the directory where the zlib sources are stored. + # See zlib.mak for more information. + +diff -up ghostscript-9.07/psi/zbfont.c.gs_sprintf ghostscript-9.07/psi/zbfont.c +--- ghostscript-9.07/psi/zbfont.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/zbfont.c 2013-05-09 17:02:39.099447227 +0100 +@@ -109,7 +109,7 @@ zfont_encode_char(gs_font *pfont, gs_cha + + if (gspace == GLYPH_SPACE_NOGEN) + return gs_no_glyph; +- sprintf(buf, "j%ld", chr); /* 'j' is arbutrary. */ ++ gs_sprintf(buf, "j%ld", chr); /* 'j' is arbutrary. */ + code = name_ref(pfont->memory, (const byte *)buf, strlen(buf), &tname, 1); + if (code < 0) { + /* Can't propagate the error due to interface limitation, +@@ -131,7 +131,7 @@ zfont_glyph_name(gs_font *font, gs_glyph + char cid_name[sizeof(gs_glyph) * 3 + 1]; + int code; + +- sprintf(cid_name, "%lu", (ulong) index); ++ gs_sprintf(cid_name, "%lu", (ulong) index); + code = name_ref(font->memory, (const byte *)cid_name, strlen(cid_name), + &nref, 1); + if (code < 0) +diff -up ghostscript-9.07/psi/zdouble.c.gs_sprintf ghostscript-9.07/psi/zdouble.c +--- ghostscript-9.07/psi/zdouble.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/zdouble.c 2013-05-09 17:02:39.100447231 +0100 +@@ -323,7 +323,7 @@ zcvsd(i_ctx_t *i_ctx_p) + len = r_size(op - 1); + if (len > MAX_CHARS) + return_error(e_limitcheck); +- sprintf(buf, "%f", 1.5); ++ gs_sprintf(buf, "%f", 1.5); + dot = buf[1]; /* locale-dependent */ + memcpy(str, op[-1].value.bytes, len); + /* +@@ -406,7 +406,7 @@ zdcvs(i_ctx_t *i_ctx_p) + if (code < 0) + return code; + check_write_type(*op, t_string); +- sprintf(str, "%f", 1.5); ++ gs_sprintf(str, "%f", 1.5); + dot = str[1]; /* locale-dependent */ + /* + * To get fully accurate output results for IEEE double- +@@ -420,10 +420,10 @@ zdcvs(i_ctx_t *i_ctx_p) + { + double scanned; + +- sprintf(str, "%g", num); ++ gs_sprintf(str, "%g", num); + sscanf(str, "%lf", &scanned); + if (scanned != num) +- sprintf(str, "%.16g", num); ++ gs_sprintf(str, "%.16g", num); + } + len = strlen(str); + if (len > r_size(op)) +diff -up ghostscript-9.07/psi/zfapi.c.gs_sprintf ghostscript-9.07/psi/zfapi.c +--- ghostscript-9.07/psi/zfapi.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/zfapi.c 2013-05-09 17:02:39.100447231 +0100 +@@ -583,11 +583,11 @@ FAPI_FF_get_word(gs_fapi_font *ff, gs_fa + length += r_size(&string) + 1; + break; + case t_real: +- sprintf(Buffer, "%f", Element.value.realval); ++ gs_sprintf(Buffer, "%f", Element.value.realval); + length += strlen(Buffer) + 1; + break; + case t_integer: +- sprintf(Buffer, "%"PRIpsint, Element.value.intval); ++ gs_sprintf(Buffer, "%"PRIpsint, Element.value.intval); + length += strlen(Buffer) + 1; + break; + case t_operator: +@@ -823,12 +823,12 @@ FAPI_FF_get_proc(gs_fapi_font *ff, gs_fa + ptr += r_size(&string); + break; + case t_real: +- sprintf(Buf, "%f", Element.value.realval); ++ gs_sprintf(Buf, "%f", Element.value.realval); + strcpy(ptr, Buf); + ptr += strlen(Buf); + break; + case t_integer: +- sprintf(Buf, "%"PRIpsint, Element.value.intval); ++ gs_sprintf(Buf, "%"PRIpsint, Element.value.intval); + strcpy(ptr, Buf); + ptr += strlen(Buf); + break; +diff -up ghostscript-9.07/psi/zfont2.c.gs_sprintf ghostscript-9.07/psi/zfont2.c +--- ghostscript-9.07/psi/zfont2.c.gs_sprintf 2013-02-14 07:58:13.000000000 +0000 ++++ ghostscript-9.07/psi/zfont2.c 2013-05-09 17:02:39.101447236 +0100 +@@ -2666,7 +2666,7 @@ parse_font(i_ctx_t *i_ctx_p, ref *topdi + return sid; + if ((code = make_name_from_sid(i_ctx_p, &name, strings, data, sid)) < 0) { + char buf[40]; +- int len = sprintf(buf, "sid-%d", sid); ++ int len = gs_sprintf(buf, "sid-%d", sid); + + if ((code = name_ref(imemory, (unsigned char *)buf, len, &name, 1)) < 0) + return code; +diff -up ghostscript-9.07/trio/autogen.sh.gs_sprintf ghostscript-9.07/trio/autogen.sh +--- ghostscript-9.07/trio/autogen.sh.gs_sprintf 2013-05-09 17:02:39.101447236 +0100 ++++ ghostscript-9.07/trio/autogen.sh 2013-05-09 17:02:39.101447236 +0100 +@@ -0,0 +1,3 @@ ++#!/bin/sh ++autoconf ++rm -rf autom4te.cache +diff -up ghostscript-9.07/trio/CHANGES.gs_sprintf ghostscript-9.07/trio/CHANGES +--- ghostscript-9.07/trio/CHANGES.gs_sprintf 2013-05-09 17:02:39.101447236 +0100 ++++ ghostscript-9.07/trio/CHANGES 2013-05-09 17:02:39.101447236 +0100 +@@ -0,0 +1,785 @@ ++CHANGES -- trio ++ ++ ++The changes listed without a name attributed to them were most likely done by ++Bjorn Reese and/or Daniel Stenberg. ++ ++Version 1.14 - 2010/01/26 ++------------------------- ++* David Byron ++ Added trio_xstring_append_max. ++ ++* Fixed compilation problem on Cygwin due to lack of long double math ++ (reported by Matthias Andree). ++ ++* David Boyce ++ Added #undef of standard stdio function names before assigning trio functions ++ to them. ++ ++* Matthias Andree ++ Upgraded configure.in to use new macros instead of obsoleted macros. ++ ++* Matthias Andree ++ Added VPATH to Makefile.in ++ ++* Tom Honermann ++ Fixed problem with subnormal numbers which caused an infinite loop outputting ++ leading spaces. ++ ++* Adam McLaurin ++ Improved parsing performance by avoiding memset() and memcpy() on character ++ arrays. ++ ++* Gideon Smeding ++ Fixed %u scanning of signed numbers. ++ ++* Gideon Smeding ++ Fixed group scanning for non-matching input. ++ ++* Fixed missing undo of look-ahead reading for scanf functions. This does only ++ work for the scanf* and fscanf* functions, not dscanf* and cscanf* functions ++ (reported by Gideon Smeding). ++ ++* If the format string is empty, scanf does not attempt to read any input. ++ ++* Ralf Junker ++ Fixed Borland compilation for user-defined specifiers. ++ ++ ++Version 1.13 - 2008/11/09 ++------------------------- ++* Ives Aerts ++ Added the $ format for user-defined specifiers, which is ++ compatible with compiler warnings about mismatches between specifiers and ++ arguments. ++ ++* Added TRIO_DEPRECATED flag (reported by David Boyce) ++ ++* Fixed rounding adjustment for long double (reported as bug item #2136686). ++ ++* Added Makefile dependency for test target (reported as bug item #2136636). ++ ++* David Boyce ++ Fixed long long support for MSVC. ++ ++* Fixed potential problem with read after buffer end for non-zero terminated ++ strings (reported as bug item #1828465). ++ ++* Andreas Stricker ++ Added WinCE support. ++ ++* Fixed number of significant digits for %g. ++ ++ ++Version 1.12 - 2006/10/22 ++------------------------- ++* Fixed scanning of floats (reported by Bernd Ahlers). ++ ++* Fixed configure.in for GCC on Tru64 and MIPSpro on IRIX (reported by Andreas ++ Maus). ++ ++* Olli Savia ++ Added support for LynxOS. ++ ++ ++Version 1.11 - 2006/04/08 ++------------------------- ++* Mark Pickelmann ++ Fixed trio_unregister. If the first element was removed, the remaining ++ list would be removed as well. ++ ++* Fixed unintended formatting of %e that would result in non-zero numbers ++ starting with zero (reported by Mark Pickelmann and Gisli Ottarsson). ++ ++* Fixed compilation with Sun Workshop 6 (reported by Matthias Andree). ++ ++* Fixed accuracy for denormalized numbers (bug item #758327). ++ ++* Glen Davidson ++ Fixed scanning of floating-point numbers without a decimal-point (bug item ++ #1370427). ++ ++* David Byron ++ Fixed more compiler warnings. ++ ++* Fixed compilation of trio_to_long_double and TRIO_FEATURE_FLOAT (reported by ++ David Byron). ++ ++* Fixed precision of large floating-point numbers (bug item #1314524). ++ ++* Karl Bochert ++ Fixed trio_fpclassify_and_signbit to only restore the floating-point ++ precision. ++ ++* Fixed detection of need for ieee option on FreeBSD/Alpha. ++ ++* Added TRIO_SNPRINTF_ONLY compilation. ++ ++* Fixed trio_to_double by not using strtod() on Tru64/DECC because it does not ++ support hex-floats. ++ ++* Fixed crash on 64 bits machines related to a previous workaround in version ++ 1.9 for uninitialized va_list (reported by Nicolai Tufar, suggestion by ++ Douglas Gwyn). ++ ++* Patrick Jessee ++ Fixed width calculation for %g. ++ ++* Added macros for internal features. ++ ++* Jon Foster ++ Added macros for conditional compilation of many features. Documented all ++ the features. ++ ++* Karl Bochert ++ Fixed problem with Borland C++, which changes the floating-point precision ++ for certain math functions (log10() and _fpclass()). ++ ++* Karl Bochert ++ Fixed compilation warnings on Borland C++. ++ ++* Removed any occurrence of #elif because Borland C++ reports wrong line ++ numbers when they are present (reported by Karl Bochert). ++ ++* David Byron ++ Added trio_asprintfv. ++ ++* Brian Chapman ++ Fixed Mac OS X compilation. ++ ++* David Byron ++ Fixed several compiler warnings. ++ ++* Fixed printing of out-of-range arguments for %hhd and %hd. These arguments ++ can be out of range because of default integer promotion. ++ ++* Bob Friesenhahn ++ Fixed installation of header files. ++ ++* Joe Orton ++ Added SHELL to Makefile.in to avoid problems with CShells. ++ ++* Shaun Tancheff ++ Fixed regresion tests for MSVC. ++ ++* Craig Berry ++ Fixed the VMS C99 workaround. ++ ++ ++Version 1.10 - 2003/03/06 ++------------------------- ++* Rearranged some include files to accommodate large file support (reported by ++ Albert Chin-A-Young). ++ ++* Added support for SunOS 4.1.x lack of strerror, tolower, and toupper ++ (reported by Peter McCluskey). ++ ++* Fixed pedantic compilation with TRIO_MINIMAL. ++ ++* Jose Kahan ++ Moved to avoid redefinition problems. ++ ++* Fixed hex-float exponents (reported by Matthias Clasen). ++ ++* Fixed handling of negative width and precision via paramters (reported by ++ Jacob Navia). ++ ++* Nigel Hall ++ Fixed TRIO_VA_START for VMS. ++ ++* Rune Enggaard Lausen ++ Fixed compilation for Borland C++ Builder. ++ ++* Fixed precision of hex-float numbers (reported by James Antill). ++ ++* Fixed plus sign only to be added for signed numbers. ++ ++* Fixed printing of integers with value and precision of zero (reported by ++ James Antill). ++ ++* Fixed %#.o to only print one zero if the value is zero (reported by James ++ Antill). ++ ++* Rewrote check for IEEE compilation option to remove dependency on additional ++ scripts. ++ ++* Mehdi Lavasani ++ Makefile install target fixed to work with older install programs. ++ ++* Collapsed the DECC, MSVC, HP-UX, and AIX code for trio_fpclassify_and_sign() ++ with further preprocessing. ++ ++ ++Version 1.9 - 2002/10/13 ++------------------------ ++* Fixed trio_fpclassify_and_signbit on AIX 3.2 ++ ++* Added configure check for -ieee/-mieee compilation option for Alpha machines. ++ ++* Craig Berry ++ Fixed compilation on VMS. ++ ++* Albert Chin-A-Young ++ Fixed incorrect conditional expression in trio_isinf. ++ ++* Fixed the warnings about uninitialized va_list in the printfv and scanfv ++ family without the use of compiler specific pragmas (suggested by Ian ++ Pilcher). ++ ++* Fixed space flag for floating-point numbers (reported by Ian Main). ++ ++ ++Version 1.8 - 2002/07/10 ++------------------------ ++* Fixed infinite loop in multibyte handling (reported by Gisli Ottarsson). ++ ++* Added the customizable cprintf/cscanf family which enables to user to specify ++ input and output stream functions (suggested by Florian Schulze). ++ ++* Fixed trio_isinf by removing the HP-UX workaround, and instead making sure ++ that the C99 macro will adhere to the trio return values (reported by Luke ++ Dunstan). ++ ++* Alexander Lukyanov ++ Fixed boundary case for scanning and EOF. ++ ++* Jacob Navia ++ Enabled the L modifier for formatting. ++ ++* Added TRIO_MINIMAL to build trio without the string functions. ++ ++* Added the R modifier to print rounded floating-point numbers. ++ ++* Added trio_to_long_double and long double scanning (the L modifier). ++ ++* Added trio_locale_decimal_point, trio_locale_thousand_separator, ++ trio_locale_grouping to overwrite locale settings. ++ ++* Rewrote TrioWriteDouble to avoid temporary buffers and thus the danger of ++ buffer overflows (for instance %.5000f). ++ ++* Improved floating-point formatting accuracy. ++ ++* Fixed formatting of non-decimal exponents. ++ ++* Fixed thousand separator checking. ++ ++* Fixed %f scanning to get a float and %lf to get a double. ++ ++* Fixed WIN32 compilation (reported by Emmanuel Mogenet) ++ ++* Fixed regression test cases to exclude disabled features. ++ ++ ++Version 1.7 - 2002/05/07 ++------------------------ ++* Fixed trio_to_double to handle hex-floats properly. ++ ++* Fixed printing of %a-format to be like %e, not like %g. ++ ++* Fixed floating-point printing of values beyond the machine accuracy. ++ ++* Fixed %f for printing with large precision. ++ ++* Fixed the usage of C99 nan(), which caused a crash on OSF/1 (reported by ++ Georg Bolz) ++ ++* Joe Orton ++ Fixed %p on 64-bit platforms. ++ ++* Made trio compile with K&R compilers. ++ ++* Emmanuel Mogenet ++ Fixed bug in trio_asprintf. ++ ++* Emmanuel Mogenet ++ Various WIN32 fixes. ++ ++* Joe Orton ++ Fixed trio_isinf() on HP-UX, and added test cases. ++ ++* Joe Orton ++ Fixed non-portable use of $^ in Makefile. ++ ++* Joe Orton ++ Added autoconf. ++ ++* Alexander Lukyanov ++ Fixed a number of bugs in the scanning of EOF and the count specifier. ++ ++* Richard Jinks ++ Added trio_nzero ++ ++* Fixed incorrect handling of return code from TrioReadChar (reported by ++ Henrik L�f) ++ ++* Fixed parsing of character class expressions. ++ ++* Fixed trio_to_double which did not work with long fractions. ++ ++* Fixed %f for printing of large numbers. ++ ++* Fixed %#s to handle whitespaces as non-printable characters. ++ ++* Added trio_isfinite, trio_signbit, and trio_fpclassify. ++ ++* Added new test cases. ++ ++ ++Version 1.6 - 2002/01/13 ++------------------------ ++* Added dynamic string functions. ++ ++* Rewrote and extended documentation in JavaDoc (using Doxygen). ++ ++* Moved and renamed strio functions to triostr. ++ ++* Robert Collins ++ Added definition for Cygwin. ++ ++* Markus Henke ++ Added long double workaround for the HP C/iX compiler. ++ ++* Marc Verwerft ++ Improved error handling for dynamically allocated strings. ++ ++* John Fotheringham ++ Made trionan compile on OpenVMS. ++ ++* Added 'd' and 'D' as exponent letters when using TRIO_MICROSOFT. ++ ++* Fixed uninitial memory read for the parameter modifiers. ++ ++ ++Version 1.5 - 2001/09/08 ++------------------------ ++* Merged with libxml changes. ++ ++* Moved NaN and Inf handling to separate file to enable reuse in other ++ projects. ++ ++* Igor Zlatkovic ++ Fixed TrioGenerateNan for MSVC. ++ ++* Fixed lots of preprocessor macros and internal data structure names. ++ ++ ++Version 1.4 - 2001/06/03 ++------------------------ ++* Added hex-float (%a and %A) for scanning. ++ ++* Added wide character arguments (%ls, %ws, %S, %lc, %wc, and %C) for both ++ printf and scanf. ++ ++* Added mutex callbacks for user-specified specifiers to enable applications to ++ add thread-safety. These are registered with trio_register, where the ++ namespace is set to either ":enter" to lock a mutex, or ":leave" to unlock a ++ mutex. ++ ++* Added equivalence class expressions for scanning. For example, %[[=a=]] scans ++ for all letters in the same equivalence class as the letter 'a' as defined ++ by the locale. ++ ++* Changed character class expressions for scanning. The expressions must now ++ be embedded withing an extra set of brackets, e.g. %[[:alpha:]]. This was ++ done to adhere to the syntax of UNIX98 regular expressions. ++ ++* Added the possibility to specify standard support (TRIO_C99 etc.) as compiler ++ options. ++ ++* Fixed conversion of hex-float in StrToDouble. ++ ++* Fixed formatting of hex-float numbers. ++ ++* Stan Boehm ++ Fixed crash on QNX, which happend because some buffers on the stack were too ++ big. ++ ++* Fixed default precision for %f and %g (reported by Jose Ortiz) ++ ++* Howard Kapustein ++ Added the I8, I16, I32, and I64 modifiers. ++ ++* Jose Ortiz ++ Fixed rounding problem for %e. ++ ++* Jose Ortiz ++ Fixed various problems with the xlC and Sun C++ compilers. ++ ++ ++Version 1.3 - 2001/05/16 ++------------------------ ++* trio's treatment of the field width when the %e code was used was not ++ correct (reported by Gisli Ottarsson). It turns out the fraction part should ++ be zero-padded by default and the exponent part should be zero-prefixed if ++ it is only one digit. At least that's how the GNU and Sun libc's work. The ++ trio floating point output looks identical to them now. ++ ++* Fixed group scanning with modifiers. ++ ++* Fixed compilation for 64-bit Digital Unix. ++ ++* Igor Zlatkovic ++ Fixed compilation of dprintf, which uses read/write, for MSVC. ++ ++* Fixed various compilation problems on Digital Unix (mainly associated with ++ va_list). ++ ++ ++Version 1.2 - 2001/04/11 ++------------------------ ++* Added autoconf integration. If compiled with HAVE_CONFIG_H the following ++ happens. Firstly, is included. Secondly, trio will only be ++ compiled if WITH_TRIO is defined herein. Thirdly, if TRIO_REPLACE_STDIO is ++ defined, only stdio functions that have not been detected by autoconf, i.e. ++ those not defined by HAVE_PRINTF or similar, will be replaced by trio ++ functions (suggested by Daniel Veillard). ++ ++* Fixed '%m.nf' output. Previously trio did not treat the width properly ++ in all cases (reported by Gisli Ottarsson). ++ ++* Added explicit promotion for the scanfv family. ++ ++* Fixed more C++ compilation warnings. ++ ++ ++Version 1.1 - 2001/02/25 ++------------------------ ++* Added explicit promotion for the printfv familiy. A float must be specified ++ by %hf. ++ ++* Fixed positionals for printfv (reported by Gisli Ottarsson). ++ ++* Fixed an integer to pointer conversion problem on the SGI MIPS C compiler ++ (reported by Gisli Ottarsson). ++ ++* Fixed ANSI C++ warnings (type casting, and namespace is a reserved keyword). ++ ++* Added \n to all examples in the documentation to prevent confusion. ++ ++* Fixed StrSubstringMax ++ ++ ++Version 1.0 - 2000/12/10 ++------------------------ ++* Bumped Version number. ++ ++ ++Version 0.25 - 2000/12/09 ++------------------------- ++* Wrote more documentation. ++ ++* Improved NaN support and added NaN to regression test. ++ ++* Fixed C99 support. ++ ++* Added missing getter/setter functions. ++ ++ ++Version 0.24 - 2000/12/02 ++------------------------- ++* Added callback functionality for the user-defined specifier (<>). All ++ the necessary functions are defined in triop.h header file. See the ++ documentation for trio_register for further detail. ++ ++* Wrote initial documentation on the callback functionality. ++ ++* Added the printfv and scanfv family of functions, which takes a pointer ++ array rather than variadic arguments. Each pointer in the array must point ++ to the associated data (requested by Bruce Korb). ++ ++* As indicated in version 0.21 the extension modifiers (<>) have now been ++ completely removed. ++ ++* Added skipping of thousand-separators in floating-point number scanning. ++ ++ ++Version 0.23 - 2000/10/21 ++------------------------- ++* Added width to scanning of floating-point numbers. ++ ++* Wrote more documentation on trio_printf. ++ ++* Fixed problem with trailing zeroes after decimal-point. ++ ++ ++Version 0.22 - 2000/08/06 ++------------------------- ++* Added LC_CTYPE locale dependent character class expressions to scan lists. ++ Included are [:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:], ++ [:lower:], [:print:], [:punct:], [:space:], [:upper:], [:xdigit:] ++ ++* Added C escapes to alternative string formatting and scanning. ++ ++* Added StrSubstringMax. ++ ++* Wrote a little more documentation. ++ ++* Fixed scanf return values. ++ ++* Fixed a sign error for non-ascii characters. ++ ++ ++Version 0.21 - 2000/07/19 ++------------------------- ++* Converted the documentation to TeX. With latex2man the documentation can ++ automatically be converted into man pages. ++ ++* Added trio_scanf, trio_vscanf, trio_fscanf, and trio_vfscanf. ++ ++* Added trio_dprintf, trio_vdprintf, trio_dscanf, and trio_vdscanf. These ++ functions can be used to write and read directly to pipes and sockets (the ++ assume blocking sockets). Stdio buffering is surpassed, so the functions are ++ async-safe. However, reading from stdin (STDIN_FILENO) or writing to stdout ++ (STDOUT_FILENO) reintroduces the buffering. ++ ++* Paul Janzen ++ Added trio_asprintf and trio_vasprintf, which are compatible with the GNU ++ and BSD interfaces. ++ ++* Added scanlist ranges for group scanning (%[]). ++ ++* Added width for scanning (missing for floating-point numbers though). ++ ++* Added variable size modifier (&) to handle system defined types of unknown ++ size. This modifier makes certain assumptions about the integer sizes, which ++ may not be valid on any machine. Consequently, the modifier will remain ++ undocumented, as it may be removed later. ++ ++* Added \777 and \xFF to alternative string scanning (%#s) ++ ++* Added the TRIO_REPLACE_STDIO check in the header. ++ ++* Improved performance of the multibyte character parsing. ++ ++* Fixed positionals (%n$) which had stopped working. ++ ++* Fixed hh and ll modifiers to allow exactly two letters and no more. ++ ++* Fixed ANSI C++ warnings. Also fixed the compiler warning about casting ++ between integer and pointer (this has been annoying me for ages). ++ ++* Fixed snprintf and vsnprintf with zero buffer size. ++ ++* Fixed NAN problems (reported by Keith Briggs). ++ ++* Fixed parsing of multibyte characters. The format string was not correctly ++ advanced in case of a multibyte character. ++ ++* Renamed many of the internal functions to have more consistant names. ++ ++* Removed the and modifiers. They are not really worth ++ including. The other <> modifiers may disappear as well. ++ ++ ++Version 0.20 - 2000/06/05 ++------------------------- ++* Added intmax_t and ptrdiff_t support. ++ ++* Added support for LC_NUMERIC grouping. ++ ++* Added double-dot notation for the conversion base. The style is now ++ %width.precision.base, where any argument can be a number, an asterix ++ indicating a parameter, or be omitted entirely. For example, %*..2i is ++ to specify binary numbers without precision, and with width as a parameter ++ on the va_list. ++ ++* Added sticky modifier (!), which makes subsequent specifiers of the same ++ type reuse the current modifiers. Inspired by a suggestion from Gary Porter. ++ ++* Added group scanning (%[]). Scanlist ranges and multibyte sequences are not ++ supported yet. ++ ++* Added count scanning (%n). ++ ++* Changed the number scanning to accept thousand separators and any base. ++ ++* Fixed positional for parameters. It is possible to write something like ++ %3$*1$.*2$d (which happens to be the same as %*.*d). ++ ++* Fixed precision of integers. ++ ++* Fixed parameter flags. Before trio could only handle one parameter flag per ++ specifier, although two (three with double-dot base) were possible. ++ ++* Fixed isinf() for those platforms where it is unimplemented. ++ ++ ++Version 0.18 - 2000/05/27 ++------------------------- ++* Rewrote the entire floating-point formatting function (Danny Dulai had ++ reported several errors and even supplied some patches, which unfortunately ++ were lost due to the refactoring). ++ ++* Removed the use of strlen() in the declaration of a stack array. This ++ caused problems on some compilers (besides it isn't really ANSI C compliant ++ anyways). Using some arbitrarily chosen maximum value; should examine if ++ some standard defines an upper limit on the length of decimal-point and ++ thousands-separator (sizeof(wchar_t) perhaps?) ++ ++* Changed the parsing of the format string to be multibyte aware. ++ ++ ++Version 0.17 - 2000/05/19 ++------------------------- ++* Added INF, -INF, and NAN for floating-point numbers. ++ ++* Fixed %#.9g -- alternative with precision. ++ ++* Ken Gibson ++ Fixed printing of negative hex numbers ++ ++* Joerg (last name unknown) ++ Fixed convertion of non-ASCII characters ++ ++ ++Version 0.16 - 1999/08/06 ++------------------------- ++* Changed the constness of the second argument of StrFloat and StrDouble. The ++ lack of parameter overloading in C is the reason for the strange use of ++ constness in strtof and strtod. ++ ++* Cleaned up constness. ++ ++ ++Version 0.15 - 1999/07/23 ++------------------------- ++* Fixed the internal representation of numbers from signed to unsigned. Signed ++ numbers posed a problem for large unsigned numbers (reported by Tero) ++ ++* Fixed a tiny bug in trio_vsprintfcat ++ ++* Changed the meaning of the max argument of StrAppendMax to be consistant ++ with StrFormatAppendMax. Now it is the maximal size of the entire target ++ buffer, not just the appended size. This makes it easier to avoid buffer ++ overflows (requested by Tero) ++ ++ ++Version 0.14 - 1999/05/16 ++------------------------- ++* Added size_t support (just waiting for a C99 compliant compiler to add ++ ptrdiff_t and intmax_t) ++ ++* Rewrote TrioOutStreamDouble so it does not use the libc sprintf to emulate ++ floating-point anylonger. ++ ++* Fixed width, precision, and adjustment for numbers and doubles. ++ ++ ++Version 0.13 - 1999/05/06 ++------------------------- ++* Fixed zero padding for %d. Now %d will only zero pad if explicitly requested ++ to do so with the 0 flag (reported by Tero). ++ ++* Fixed an incorrect while() condition in TrioGetString (reported by Tero). ++ ++ ++Version 0.12 - 1999/04/19 ++------------------------- ++* Fixed incorrect zero padding of pointers ++ ++* Added StrHash with STRIO_HASH_PLAIN ++ ++* Added StrFormatDateMax ++ ++ ++Version 0.11 - 1999/03/25 ++------------------------- ++* Made it compile under cygwin ++ ++* Fixed a bug were TrioPreprocess would return an error if no formatting chars ++ were found (reported by Tero). ++ ++ ++Version - 1999/03/19 ++-------------------- ++* Added trio_strerror and TRIO_ERROR_NAME. ++ ++* Changed the error codes to be positive (as errno) ++ ++* Fixed two reads of uninitialized memory reported by Purify ++ ++* Added binary specifiers 'b' and 'B' (like SCO.) ThousandSeparator can be ++ used to separate nibbles (4 bit) ++ ++* Renamed all Internal* functions to Trio*, which seems like a better ++ namespace (even though it is of no practical interest because these ++ functions are not visible beyond the scope of this file.) ++ ++ ++Version - 1999/03/12 ++-------------------- ++* Added hex-float format for StrToDouble ++ ++* Double references and gaps in the arguments are not allowed (for the %n$ ++ format) and in both cases an error code is returned. ++ ++* Added StrToDouble (and StrToFloat) ++ ++ ++Version - 1999/03/08 ++-------------------- ++* Added InStream and OutStream to the trio_T structure. ++ ++* Started work on TrioScan. ++ ++* Return values for errors changed. Two macros to unpack the error code has ++ been added to the header. ++ ++* Shortshort (hh) flag added. ++ ++* %#s also quotes the quote-char now. ++ ++* Removed the 'errorInFormat' boolean, which isn't used anymore after the ++ functions bail out with an error instead. ++ ++ ++Version - 1999/03/04 ++-------------------- ++* More than MAX_PARAMETERS parametes will now cause the TrioPreprocess() ++ function to return error. ++ ++* Unknown flags and/or specifiers cause errors too. ++ ++* Added trio_snprintfcat and trio_vsnprintfcat and the defined name ++ StrFormatAppendMax. They append a formatted string to the end of a string. ++ ++* Define MAX_PARAMETERS to 128 at all times instead of using NL_ARGMAX when ++ that exists. ++ ++* Added platform fixes for Amiga as suggested by Tero J�nk� ++ ++ ++Version - 1999/01/31 ++-------------------- ++* vaprintf did add a zero byte even when it had failed. ++ ++* Cleaned up the code for locale handling and thousand separator ++ ++* Added trio_aprintf() and trio_vaprintf(). They return an allocated string. ++ ++* Added thousands separator for numbers ++ ++* Added floating point support for *printf ++ ++ ++Version - 1998/10/20 ++-------------------- ++* StrMatchCase() called StrMatch() instead of itself recursively ++ ++* Rewrote the implementation of *printf and *scanf and put all the code in ++ this file. Extended qualifiers and qualifiers from other standards were ++ added. ++ ++* Added StrSpanFunction, StrToLong, and StrToUnsignedLong ++ ++ ++Version - 1998/05/23 ++-------------------- ++* Made the StrEqual* functions resistant to NULL pointers ++ ++* Turns out strdup() is no standard at all, and some platforms (I seem to ++ recall HP-UX) has problems with it. Made our own StrDuplicate() instead. ++ ++* Added StrFormat() and StrFormatMax() to serve as sprintf() and snprintf() ++ respectively. +diff -up ghostscript-9.07/trio/compare.c.gs_sprintf ghostscript-9.07/trio/compare.c +--- ghostscript-9.07/trio/compare.c.gs_sprintf 2013-05-09 17:02:39.101447236 +0100 ++++ ghostscript-9.07/trio/compare.c 2013-05-09 17:02:39.101447236 +0100 +@@ -0,0 +1,53 @@ ++#include "trio.h" ++ ++#define compare(format, value) printf("FORMAT: %s\n", format); printf("TRIO: "); trio_printf(format,value); printf("\nLIBC: "); \ ++printf(format,value); printf("\n\n"); ++ ++int main() ++{ ++ compare("\"%e\"",2.342E+02); ++ compare("\"%10.4e\"",-2.342E-02); ++ compare("\"%11.4e\"",-2.342E-02); ++ compare("\"%12.4e\"",-2.342E-02); ++ compare("\"%13.4e\"",-2.342E-02); ++ compare("\"%14.4e\"",-2.342E-02); ++ compare("\"%15.4e\"",-2.342E-02); ++ compare("\"%16.4e\"",-2.342E-02); ++ compare("\"%16.4e\"",-2.342E-22); ++ compare("\"%G\"",-2.342E-02); ++ compare("\"%G\"",3.1415e-6); ++ compare("%016e", 3141.5); ++ compare("%16e", 3141.5); ++ compare("%-16e", 3141.5); ++ compare("%010.3e", 3141.5); ++ ++ compare("*%5f*", 3.3); ++ compare("*%5f*", 3.0); ++ compare("*%5f*", .999999E-4); ++ compare("*%5f*", .99E-3); ++ compare("*%5f*", 3333.0); ++ ++ compare("*%5g*", 3.3); ++ compare("*%5g*", 3.0); ++ compare("*%5g*", .999999E-4); ++ compare("*%5g*", .99E-3); ++ compare("*%5g*", 3333.0); ++ compare("*%5g*", 0.01); ++ ++ compare("*%5.g*", 3.3); ++ compare("*%5.g*", 3.0); ++ compare("*%5.g*", .999999E-4); ++ compare("*%5.g*", 1.0E-4); ++ compare("*%5.g*", .99E-3); ++ compare("*%5.g*", 3333.0); ++ compare("*%5.g*", 0.01); ++ ++ compare("*%5.2g*", 3.3); ++ compare("*%5.2g*", 3.0); ++ compare("*%5.2g*", .999999E-4); ++ compare("*%5.2g*", .99E-3); ++ compare("*%5.2g*", 3333.0); ++ compare("*%5.2g*", 0.01); ++ ++ return 0; ++} +diff -up ghostscript-9.07/trio/configure.in.gs_sprintf ghostscript-9.07/trio/configure.in +--- ghostscript-9.07/trio/configure.in.gs_sprintf 2013-05-09 17:02:39.101447236 +0100 ++++ ghostscript-9.07/trio/configure.in 2013-05-09 17:02:39.101447236 +0100 +@@ -0,0 +1,54 @@ ++dnl ++dnl Configuration for trio ++dnl ++ ++AC_INIT ++AC_CONFIG_SRCDIR([triodef.h]) ++AC_PREREQ(2.55) dnl autoconf 2.55 was released in 2002 ++ ++AC_PROG_CC ++ifdef([AC_PROG_CC_STDC], [AC_PROG_CC_STDC]) ++AC_LANG([C]) ++ ++AC_PROG_INSTALL ++AC_PROG_RANLIB ++ ++dnl ++dnl Alpha floating-point compiler option. ++dnl ++ ++AC_MSG_CHECKING(for IEEE compilation options) ++AC_CACHE_VAL(ac_cv_ieee_option, [ ++ AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[ ++ #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && (defined(VMS) || defined(__VMS))) ++ # error "Option needed" ++ typedef int option_needed[-1]; ++ #endif ++ ]]]), ++ ac_cv_ieee_option="/IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE", ++ AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[ ++ #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__))) && !(defined(VMS) || defined(__VMS)) && !defined(_CFE)) ++ # error "Option needed" ++ typedef int option_needed[-1]; ++ #endif ++ ]]]), ++ ac_cv_ieee_option="-ieee", ++ AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[ ++ #if !(defined(__alpha) && (defined(__GNUC__) && (defined(__osf__) || defined(__linux__)))) ++ # error "Option needed" ++ typedef int option_needed[-1]; ++ #endif ++ ]]]), ++ ac_cv_ieee_option="-mieee", ++ ac_cv_ieee_option="none" ++ ) ++ ) ++ ) ++]) ++AC_MSG_RESULT($ac_cv_ieee_option) ++if test $ac_cv_ieee_option != none; then ++ CFLAGS="${CFLAGS} ${ac_cv_ieee_option}" ++fi ++ ++AC_CONFIG_FILES([Makefile]) ++AC_OUTPUT +diff -up ghostscript-9.07/trio/doc/doc_dynamic.h.gs_sprintf ghostscript-9.07/trio/doc/doc_dynamic.h +--- ghostscript-9.07/trio/doc/doc_dynamic.h.gs_sprintf 2013-05-09 17:02:39.102447240 +0100 ++++ ghostscript-9.07/trio/doc/doc_dynamic.h 2013-05-09 17:02:39.102447240 +0100 +@@ -0,0 +1,31 @@ ++/************************************************************************* ++ * ++ * $Id: doc_dynamic.h,v 1.1 2001/12/27 17:29:20 breese Exp $ ++ * ++ * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ++ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND ++ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. ++ * ++ ************************************************************************/ ++ ++/** @addtogroup DynamicStrings Dynamic String Functions. ++Dynamic string functions. ++ ++@b SYNOPSIS ++ ++@verbatim ++cc ... -ltrio -lm ++ ++#include ++@endverbatim ++ ++@b DESCRIPTION ++ ++*/ +diff -up ghostscript-9.07/trio/doc/doc.h.gs_sprintf ghostscript-9.07/trio/doc/doc.h +--- ghostscript-9.07/trio/doc/doc.h.gs_sprintf 2013-05-09 17:02:39.102447240 +0100 ++++ ghostscript-9.07/trio/doc/doc.h 2013-05-09 17:02:39.102447240 +0100 +@@ -0,0 +1,172 @@ ++/************************************************************************* ++ * ++ * $Id: doc.h,v 1.20 2006/08/18 11:32:08 breese Exp $ ++ * ++ * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ++ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND ++ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. ++ * ++ ************************************************************************/ ++ ++/** ++@mainpage ++ ++@author Bj�rn Reese ++@author Daniel Stenberg ++ ++@section intro Introduction ++ ++Trio is a fully matured and stable set of printf and string functions ++designed be used by applications with focus on portability or with the ++need for additional features that are not supported by standard stdio ++implementation. ++ ++There are several cases where you may want to consider using trio: ++ ++@li Portability across heterogeneous platforms. ++@li Embedded systems without stdio support. ++@li Extendability of unsupported features. ++@li Your native version does not do everything you need. ++ ++When you write applications that must be portable to a wide range of ++platforms you often have to deal with inadequate implementations of the ++stdio library functions. Most notably is the lack of secure formatting ++functions, such as snprintf, or the lack of parameter reordering commonly ++used for the internationalization of applications, such as the $ ++modifier. Sometimes the feature you need is simply not present in stdio. ++So you end up spending much effort on determining which platforms supports ++what, and to write your own versions of various features. This is where ++trio can help you. Trio is a platform-independent implementation of the ++stdio printf and scanf functions and the string library functions. ++ ++The functionality described in the stdio standards is a compromise, and ++does unfortunately not include a mechanism to extend the functionality for ++an individual application. Oftentimes an application has the need for an ++extra feature, and the application code can become much more clear and ++readable by using an extension mechanism. Trio supports a range of useful ++extensions such as user-defined specifiers, passing of arguments in arrays, ++localized string scanning, thousand-separators, and arbitrary integer bases. ++ ++Trio fully implements the C99 (ISO/IEC 9899:1999) and UNIX98 (the Single ++Unix Specification, Version 2) standards, as well as many features from ++other implemenations, e.g. the GNU libc and BSD4. ++ ++@section examples Examples ++ ++@subsection ex1 Binary Numbers ++Output an integer as a binary number using a trio extension. ++@verbatim ++ trio_printf("%..2i\n", number); ++@endverbatim ++ ++@subsection ex2 Thousand-separator ++Output a number with thousand-separator using a trio extension. ++@verbatim ++ trio_printf("%'f\n", 12345.6); ++@endverbatim ++The thousand-separator described by the locale is used. ++ ++@subsection ex3 Fixed Length Array and Sticky Modifier ++Output an fixed length array of floating-point numbers. ++@verbatim ++ double array[] = {1.0, 2.0, 3.0}; ++ printf("%.2f %.2f %.2f\n", array[0], array[1], array[2]); ++@endverbatim ++The same with two trio extensions (arguments are passed in an array, and ++the first formatting specifier sets the sticky option so we do not have ++to type all the formatting modifiers for the remaining formatting specifiers) ++@verbatim ++ trio_printfv("%!.2f %f %f\n", array); ++@endverbatim ++Another, and more powerful, application of being able to pass arguments in ++an array is the creation of the printf/scanf statement at run-time, where ++the formatting string, and thus the argument list, is based on an external ++configuration file. ++ ++@subsection ex4 Localized scanning ++Parse a string consisting of one or more upper-case alphabetic characters ++followed by one or more numeric characters. ++@verbatim ++ sscanf(buffer, "%[A-Z]%[0-9]", alphabetic, numeric); ++@endverbatim ++The same but with locale using a trio extension. ++@verbatim ++ trio_sscanf(buffer, "%[[:upper:]]%[[:digit:]]", alphabetic, numeric); ++@endverbatim ++ ++@section legal Legal Issues ++Trio is distributed under the following license, which allows practically ++anybody to use it in almost any kind of software, including proprietary ++software, without difficulty. ++ ++"Copyright (C) 1998-2001 Bjorn Reese and Daniel Stenberg. ++ ++Permission to use, copy, modify, and distribute this software for any ++purpose with or without fee is hereby granted, provided that the above ++copyright notice and this permission notice appear in all copies. ++ ++THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ++WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ++MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND ++CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER." ++ ++@section contribution Contribution ++ ++@subsection contribute Contribute ++We appreciate any type of contribution, from ideas over improvements to ++error corrections. ++ ++The project space contains references to bug and feature tracking, ++mailing-list, and the CVS repository. We prefer communication via the ++mailing-list, but do not require you to be subscribed, because trio is a ++small project. ++ ++The project space is located at http://sourceforge.net/projects/ctrio/ ++ ++@subsection contributors Contributors ++We have received contributions from the following persons (in alphabetic ++order sorted by surname) ++ ++@li Craig Berry ++@li Karl Bochert ++@li Stan Boehm ++@li David Byron ++@li Brian Chapman ++@li Robert Collins ++@li Danny Dulai ++@li Bob Friesenhahn ++@li Jon Foster ++@li John Fotheringham ++@li Markus Henke ++@li Ken Gibson ++@li Paul Janzen ++@li Patrick Jessee ++@li Richard Jinks ++@li Tero J�nk� ++@li Howard Kapustein ++@li Rune Enggaard Lausen ++@li Mehdi Lavasani ++@li Alexander Lukyanov ++@li Andreas Maus ++@li Mikey Menezes ++@li Emmanuel Mogenet ++@li Jacob Navia ++@li Jose Ortiz ++@li Joe Orton ++@li Gisli Ottarsson ++@li Mark Pickelmann ++@li Olli Savia ++@li Shaun Tancheff ++@li Marc Werwerft ++@li Igor Zlatkovic ++ ++Please let us know, and accept our apology, if we have omitted anybody. ++ ++*/ +diff -up ghostscript-9.07/trio/doc/doc_printf.h.gs_sprintf ghostscript-9.07/trio/doc/doc_printf.h +--- ghostscript-9.07/trio/doc/doc_printf.h.gs_sprintf 2013-05-09 17:02:39.102447240 +0100 ++++ ghostscript-9.07/trio/doc/doc_printf.h 2013-05-09 17:02:39.102447240 +0100 +@@ -0,0 +1,532 @@ ++/************************************************************************* ++ * ++ * $Id: doc_printf.h,v 1.5 2008/10/12 12:09:51 breese Exp $ ++ * ++ * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ++ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND ++ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. ++ * ++ ************************************************************************/ ++ ++/** @addtogroup Printf Formatted Printing Functions. ++Variations of formatted printing functions. ++ ++@b SYNOPSIS ++ ++@verbatim ++cc ... -ltrio -lm ++ ++#include ++@endverbatim ++ ++@b DESCRIPTION ++ ++This documentation is incomplete. ++The documentation of the printf family in [C99] and [UNIX98] also applies ++to the trio counterparts. ++ ++All these functions outputs a string which is formatted according to the ++@p format string and the consecutive arguments. The @p format string is ++described in the Formatting section below. ++ ++@ref trio_printf, @ref trio_vprintf, and @ref trio_printfv writes the ++output to the standard output stream (stdout). ++ ++@ref trio_fprintf, @ref trio_vfprintf, and @ref trio_fprintfv writes the ++output to a given output stream. ++ ++@ref trio_dprintf, @ref trio_vdprintf, and @ref trio_dprintfv writes the ++output to a file descriptor (this includes, for example, sockets). ++ ++@ref trio_sprintf, @ref trio_vsprintf, and @ref trio_sprintfv writes the ++output into @p buffer. ++ ++@ref trio_snprintf, @ref trio_vsnprintf, and @ref trio_snprintfv writes @p ++max - 1 characters into @p buffer followed by a terminating zero character. ++If @p max is 1, then @p buffer will be an empty string. If @p max is 0, ++then @p buffer is left untouched, and can consequently be NULL. The number ++of characters that would have been written to @p buffer, had there been ++sufficient space, is returned. ++ ++@ref trio_snprintfcat appends the formatted text at the end of @p buffer. ++ ++@ref trio_asprintf, @ref trio_vasprintf, and @ref trio_asprintfv allocates ++and returns an allocated string in @p buffer containing the formatted text. ++ ++@b FORMATTING ++ ++The @p format string can contain normal text and conversion indicators. ++The normal text can be any character except the nil character (\000 = ++'\0') and the percent character (\045 = '%'). Conversion indicators ++consists of an indication character (%), followed by zero or more conversion ++modifiers, and exactly one conversion specifier. ++ ++@b Modifiers ++ ++Some modifiers exhibit the same behaviour for all specifiers, other modifiers ++indicate different behaviours for different specifiers, and other modifiers ++are only applicable to certain specifiers. The relationship is described for ++each modifier. The number 9 is used to denotes an arbitrary integer. ++ ++@em Positional ( @c 9$ ) [UNIX98] ++ ++Normally the arguments supplied to these functions are interpreted ++incrementially from left to right. Arguments can be referenced specifically in ++the format string. The modifier n$ selects the nth argument. The first ++argument is referred as 1$. If this modifier is used, it must be the first ++modifier after the indication character. n$ can also be used for argument ++width, precision, and base. ++ ++The performance penalty of using positionals is almost neglible (contrary to ++most other printf implementations). ++ ++@li @em Reference @em Mix. ++Mixing normal and positional specifiers is allowed [TRIO]. For example, ++@verbatim ++ trio_printf("%d %3$d %2$d\n", 1, 2, 3); ++@endverbatim ++results in ++@verbatim ++ 1 3 2 ++@endverbatim ++Arguments for the printf family are passed on the stack. On most platforms it ++is not possible to determine the size of individual stack elements, so it is ++essential that the format string corresponds exactly to the passed arguments. ++If this is not the case, incorrect values may be put into the result. ++ ++@li @em Reference @em Gap. ++For the same reason it is also essential that the format string does not ++contain any "gaps" in the positional arguments. For example, ++@verbatim ++ trio_printf("%1$d %3$d\n", 1, 2, 3); ++@endverbatim ++is NOT allowed. The format string parser has no knowledge about whether the ++second argument is, say, an integer or a long double (which have different ++sizes). ++@verbatim ++@endverbatim ++[UNIX98] describes this as unspecified behaviour. [TRIO] will detect reference ++gaps and return an error. ++ ++@li @em Double @em Reference. ++It is also not allowed to reference an argument twice or more. For example, ++@verbatim ++ trio_printf("%1$d %1$lf\n", 1); ++@endverbatim ++is NOT allowed, because it references the first argument as two differently ++sized objects. ++@verbatim ++@endverbatim ++[UNIX98] describes this as unspecified behaviour. [TRIO] will detect double ++references and return an error. ++ ++The following two statements are equivalent ++@verbatim ++ trio_printf("|%d %s\n|", 42, "meanings"); ++ |42 meanings| ++ ++ trio_printf("|%1$d %2$s|\n", 42, "meanings"); ++ |42 meanings| ++@endverbatim ++ ++@em Width ( @c 9 ) ++ ++Specifies the minimum width of a field. If the fields has less characters than ++specified by the width, the field will be left adjusted and padded by spaces. ++The adjustment and padding can be changed by the Alignment ( @c - ) and ++Padding ( @c 0 ) modifiers. ++ ++The width is specified as a number. If an asterix ( @c * ) is used instead, the ++width will be read from the argument list. ++ ++Prefixes, such as 0x for hexadecimal integers, are part of width. ++@verbatim ++ trio_printf("|%10i|\n", 42); ++ | 42| ++@endverbatim ++ ++@em Precision ( @c .9 ) ++ ++The precision has different semantics for the various data types. ++The precision specifies the maximum number of printed characters for strings, ++the number of digits after the decimal-point for floating-point numbers, ++the number of significant digits for the @c g (and @c G) representation of ++floating-point numbers, the minimum number of printed digits for integers. ++@verbatim ++ trio_printf("|%10.8i|%.8i|\n", 42, 42); ++ | 00000042|00000042| ++@endverbatim ++ ++@em Base ( @c ..9 ) [TRIO] ++ ++Sets the base that the associated integer must be converted to. The base can ++be between 2 and 36 (both included). ++@verbatim ++ trio_printf("|%10.8.2i|%10..2i|%..2i|\n", 42, 42, 42); ++ | 00101010| 101010|101010| ++ ++ trio_printf("|%*.8.*i|\n", 10, 2, 42); ++ | 00101010| ++@endverbatim ++ ++@em Padding ( @c 0 ) ++ ++Integer and floating point numbers are prepended by zeros. The number of ++leading zeros are determined by the precision. If precision is not present, ++width is used instead. ++ ++@em Short ( @c h ) ++ ++Integer arguments are read as an ( @c unsigned ) @c short @c int. String ++and character arguments are read as @c char @c * and @c char respectively. ++ ++@em Short @em short ( @c hh ) [C99, GNU] ++ ++The argument is read as an ( @c unsigned ) @c char. ++ ++@em Fixed @em Size ( @c I ) [MSVC] ++ ++The argument is read as a fixed sized integer. The modifier is followed by ++a number, which specifies the number of bits in the integer, and can be one ++of the following ++ ++@li @c I8 ++@li @c I16 ++@li @c I32 ++@li @c I64 (if 64-bits integers are supported) ++ ++Works only for integers (i, u, d, o, x, X) ++ ++@em Largest ( @c j ) [C99] ++ ++The argument is read as an @c intmax_t / @c uintmax_t, which is defined to ++be the largest signed/unsigned integer. ++ ++@em Long ( @c l ) ++ ++An integral argument is read as an ( @c unsigned ) @c long @c int. A string ++argument is read as a @c wchar_t @c *, and output as a multi-byte character ++sequence. ++ ++@em Long @em long ( @c ll ) [C99, UNIX98, GNU] ++ ++The argument is read as an ( @c unsigned ) @c long @c long @c int. ++ ++@em Long @em double ( @c L ) [C99, UNIX98, GNU] ++ ++The argument is read as a @c long @c double. ++ ++@em ptrdiff_t ( @c t ) [C99] ++ ++The argument is read as a @c ptrdiff_t, which is defined to be the signed ++integer type of the result of subtracting two pointers. ++ ++@em Quad ( @c q ) [BSD, GNU] ++ ++Corresponds to the long long modifier ( @c ll ). ++ ++@em Wide ( @c w ) [MISC] ++ ++For a string argument this is equivalent to using the long modifier ( @c l ). ++ ++@em size_t ( @c z ) [C99] ++ ++The argument is read as a @c size_t, which is defined to be the type ++returned by the @c sizeof operator. ++ ++@em size_t ( @c Z ) [GNU] ++ ++Corresponds to the size_t modifier ( @c z ). ++ ++@em Alternative ( @c # ) ++ ++Prepend radix indicator for hexadecimal, octal, and binary integer numbers ++and for pointers. ++Always add a decimal-point for floating-point numbers. ++Escape non-printable characters for strings. ++ ++@em Spacing ( ) ++ ++Prepend leading spaces when necessary. ++ ++@em Sign ( @c + ) ++ ++Always prepend a sign to numbers. Normally only the negative sign is prepended ++to a number. With this modifier the positive sign may also be prepended. ++ ++@em Alignment ( @c - ) ++ ++The output will be left-justified in the field specified by the width. ++ ++@em Argument ( @c * ) ++ ++Width, precision, or base is read from the argument list, rather than from ++the formatting string. ++ ++@em Quote / @em Grouping ( @c ' ) [MISC] ++ ++Groups integers and the integer-part of floating-point numbers according to ++the locale. Quote strings and characters. ++ ++@em Sticky ( @c ! ) [TRIO] ++ ++The modifiers listed for the current specifier will be reused by subsequent ++specifiers of the same group. ++The following specifier groups exists ++@li Integer ( @c i, @c u, @c d, @c o, @c x, @c X ) ++@li Floating-point ( @c f, @c F, @c e, @c E, @c g, @c G, @c a, @c A ) ++@li Character ( @c c ) ++@li String ( @c s ) ++@li Pointer ( @c p ) ++@li Count ( @c n ) ++@li Errno ( @c m ) ++@li Group ( @c [] ) ++ ++The sticky modifiers are active until superseeded by other sticky modifiers, ++or the end of the format string is reached. ++Local modifiers overrides sticky modifiers for the given specifier only. ++@verbatim ++ trio_printf("|%!08#x|%04x|%x|\n", 42, 42, 42); ++ |0x00002a|0x2a|0x00002a| ++@endverbatim ++ ++@b Specifiers ++ ++@em Percent ( @c % ) ++ ++Produce a percent ( @c % ) character. This is used to quote the indication ++character. No modifiers are allowed. ++The full syntax is @c %%. ++@verbatim ++ trio_printf("Percent is %%\n"); ++ Percent is % ++@endverbatim ++ ++@em Hex @em floats ( @c a, @c A ) [C99] ++ ++Output a hexadecimal (base 16) representation of a floating point number. The ++number is automatically preceeded by @c 0x ( or @c 0X ). The exponent is ++@c p ( or @c P ). ++@verbatim ++ trio_printf("|%a|%A|\n", 3.1415, 3.1415e20); ++ |0x3.228bc|0X3.228BCP+14| ++@endverbatim ++ ++@em Binary @em numbers ( @c b, @c B ) [MISC - SCO UnixWare 7] ++ ++DEPRECATED: Use Base modifier @c %..2i instead. ++ ++@em Character ( @c c ) ++ ++Output a single character. ++ ++@li Quote ( @c ' ) [TRIO]. ++Quote the character. ++ ++@em Decimal ( @c d ) ++ ++Output a decimal (base 10) representation of a number. ++ ++@li Grouping ( @c ' ) [TRIO]. ++The number is separated by the locale thousand separator. ++@verbatim ++ trio_printf("|%'ld|\n", 1234567); ++ |1,234,567| ++@endverbatim ++ ++@em Floating-point ( @c e, @c E) ++ ++Output a decimal floating-point number. ++The style is @c [-]9.99e[-]9, where ++@li @c [-]9.99 is the mantissa (as described for the @c f, @c F specifier), and ++@li @c e[-]9 is the exponent indicator (either @c e or @c E, depending on the ++floating-point specifier), followed by an optional sign and the exponent ++ ++If the precision is wider than the maximum number of digits that can be ++represented by the floating-point unit, then the number will be adequately ++rounded. For example, assuming DBL_DIG is 15 ++@verbatim ++ trio_printf("|%.18e|\n", (1.0 / 3.0)); ++ |3.333333333333333000e-01| ++@endverbatim ++ ++@em Floating-point ( @c f, @c F ) ++ ++Output a decimal floating-point number. ++The style is @c [-]9.99, where ++@li @c [-] is an optional sign (either @c + or @c -), ++@li @c 9 is the integer-part (possibly interspersed with thousand-separators), ++@li @c . is the decimal-point (depending on the locale), and ++@li @c 99 is the fractional-part. ++ ++If more digits are needed to output the number, than can be represented with ++the accuracy of the floating-point unit, then the number will be adequately ++rounded. For example, assuming that DBL_DIG is 15 ++@verbatim ++ trio_printf("|%f|\n", (2.0 / 3.0) * 1E18); ++ |666666666666666700.000000| ++@endverbatim ++ ++The following modifiers holds a special meaning for this specifier ++@li Alternative ( @c # ) [C99]. ++Add decimal point. ++@li Grouping ( @c ' ) [TRIO]. ++Group integer part of number into thousands (according to locale). ++ ++@em Floating-point ( @c g, @c G) ++ ++Output a decimal floating-point representation of a number. The format of ++either the @c f, @c F specifier or the @c e, @c E specifier is used, whatever ++produces the shortest result. ++ ++@em Integer ( @c i ) ++ ++Output a signed integer. Default base is 10. ++ ++@em Errno ( @c m ) [GNU] ++ ++@em Count ( @c n ) ++ ++Insert into the location pointed to by the argument, the number of octets ++written to the output so far. ++ ++@em Octal ( @c o ) ++ ++Output an octal (base 8) representation of a number. ++ ++@em Pointer ( @c p ) ++ ++Ouput the address of the argument. The address is printed as a hexadecimal ++number. If the argument is the NULL pointer the text @c (nil) will be used ++instead. ++@li Alternative ( @c # ) [TRIO]. ++Prepend 0x ++ ++@em String ( @c s, @c S ) ++ ++Output a string. The argument must point to a zero terminated string. If the ++argument is the NULL pointer the text @c (nil) will be used instead. ++@c S is equivalent to @c ls. ++@li Alternative ( @c # ) [TRIO]. ++Escape non-printable characters. ++ ++Non-printable characters are converted into C escapes, or hexadecimal numbers ++where no C escapes exists for the character. The C escapes, the hexadecimal ++number, and all backslashes are prepended by a backslash ( @c \ ). ++The supported C escapes are ++@li @c \a (\007) = alert ++@li @c \b (\010) = backspace ++@li @c \f (\014) = formfeed ++@li @c \n (\012) = newline ++@li @c \r (\015) = carriage return ++@li @c \t (\011) = horizontal tab ++@li @c \v (\013) = vertical tab ++ ++@verbatim ++ trio_printf("|One %s Three|One %'s Three|\n", "Two", "Two"); ++ |One Two Three|One "Two" Three| ++ ++ trio_printf("|Argument missing %s|\n", NULL); ++ |Argument missing (nil)| ++ ++ trio_printf("|%#s|\n", "\007 \a."); ++ |\a \a.| ++@endverbatim ++ ++@em Unsigned ( @c u ) ++ ++Output an unsigned integer. Default base is 10. ++ ++@em Hex ( @c x, @c X ) ++ ++Output a hexadecimal (base 16) representation of a number. ++ ++@li Alternative ( @c # ). ++Preceed the number by @c 0x ( or @c 0X ). The two characters are counted ++as part of the width. ++ ++@em User-defined ( @c <> ) ++ ++Invoke user-defined formatting. ++See @ref trio_register for further information. ++ ++@b RETURN @b VALUES ++ ++All functions returns the number of outputted characters. If an error occured ++then a negative error code is returned [TRIO]. Note that this is a deviation ++from the standard, which simply returns -1 (or EOF) and errno set ++appropriately. ++The error condition can be detected by checking whether the function returns ++a negative number or not, and the number can be parsed with the following ++macros. The error codes are primarily intended as debugging aide for the ++developer. ++ ++@li TRIO_EINVAL: Invalid argument. ++@li TRIO_ETOOMANY: Too many arguments. ++@li TRIO_EDBLREF: Double argument reference. ++@li TRIO_EGAP: Argument reference gap. ++@li TRIO_ENOMEM: Out of memory. ++@li TRIO_ERANGE: Invalid range. ++@li TRIO_ERRNO: The error is specified by the errno variable. ++ ++Example: ++@verbatim ++ int rc; ++ ++ rc = trio_printf("%r\n", 42); ++ if (rc < 0) { ++ if (TRIO_ERROR_CODE(rc) != TRIO_EOF) { ++ trio_printf("Error: %s at position %d\n", ++ TRIO_ERROR_NAME(rc), ++ TRIO_ERROR_POSITION(rc)); ++ } ++ } ++@endverbatim ++ ++@b SEE @b ALSO ++ ++@e trio_scanf, @e trio_register. ++ ++@b NOTES ++ ++The printfv family uses an array rather than the stack to pass arguments. ++This means that @c short @c int and @c float values will not be handled by ++the default argument promotion in C. Instead, these values must be explicitly ++converted with the Short (h) modifier in both cases. ++ ++Example: ++@verbatim ++ void *array[2]; ++ float float_number = 42.0; ++ short short_number = 42; ++ ++ array[0] = &float_number; ++ array[1] = &short_number; ++ ++ trio_printfv("%hf %hd\n", array); /* CORRECT */ ++ trio_printfv("%f %d\n", array); /* WRONG */ ++@endverbatim ++ ++@b CONFORMING @b TO ++ ++Throughout this document the following abbreviations have been used to ++indicate what standard a feature conforms to. If nothing else is indicated ++ANSI C (C89) is assumed. ++ ++@li [C89] ANSI X3.159-1989 ++@li [C99] ISO/IEC 9899:1999 ++@li [UNIX98] The Single UNIX Specification, Version 2 ++@li [BSD] 4.4BSD ++@li [GNU] GNU libc ++@li [MSVC] Microsoft Visual C ++@li [MISC] Other non-standard sources ++@li [TRIO] Extensions specific for this package ++ ++*/ +diff -up ghostscript-9.07/trio/doc/doc_register.h.gs_sprintf ghostscript-9.07/trio/doc/doc_register.h +--- ghostscript-9.07/trio/doc/doc_register.h.gs_sprintf 2013-05-09 17:02:39.102447240 +0100 ++++ ghostscript-9.07/trio/doc/doc_register.h 2013-05-09 17:02:39.102447240 +0100 +@@ -0,0 +1,384 @@ ++/************************************************************************* ++ * ++ * $Id: doc_register.h,v 1.3 2008/10/12 12:09:51 breese Exp $ ++ * ++ * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ++ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND ++ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. ++ * ++ ************************************************************************/ ++ ++/** @addtogroup UserDefined User-defined Formatted Printing Functions. ++Functions for using customized formatting specifiers. ++ ++@b SYNOPSIS ++ ++@verbatim ++cc ... -ltrio -lm ++ ++#include ++#include ++@endverbatim ++ ++@b DESCRIPTION ++ ++This documentation is incomplete. ++ ++@b User-defined @b Specifier ++ ++The user-defined specifier consists of a start character (\074 = '<'), an ++optional namespace string followed by a namespace separator (\072 = ':'), ++a format string, an optional skipping separator (\174 = '|'), and an end ++character (\076 = '>'). ++ ++The namespace string can consist of alphanumeric characters, and is used to ++define a named reference (see below). The namespace is case-sensitive. If no ++namespace is specified, then we use an unnamed reference (see below). ++ ++The format can consist of any character except the end character ('>'), the ++namespace separator (':'), the skipping separator ('|'), and the nil character ++(\000). ++ ++Any modifier can be used together with the user-defined specifier. ++ ++There are two formats for invoking a user-defined specifier. The first format ++is an extension of the normal printf/scanf formatting. It uses the percent ++character (\045 = '%') followed by optional qualifiers and a specifier. For ++example: ++ ++@verbatim ++ trio_printf("%\n", my_handle, my_data); ++@endverbatim ++ ++Some C compilers can issue a warning if there is a mismatch between specifiers ++and arguments. Unfortunately, these warnings does not work with the first ++format for user-defined specifiers. Therefore the second format has been ++introduced. The second format can only be applied to user-defined specifiers. ++ ++The second format starts with a dollar character (\044 = '$') instead of the ++percent character, and is followed by optional qualifiers and the user-defined ++specifier. If the specifier contains a pipe character (\174 = '|'), then ++everything between the pipe character and the end character ('>') is ignored. ++The ignored part can be used to list the normal specifiers that the C compiler ++uses to determine mismatches. For example: ++ ++@verbatim ++ trio_printf("$\n", my_handle, my_data); ++@endverbatim ++ ++@b Registering ++ ++A user-defined specifier must be registered before it can be used. ++Unregistered user-defined specifiers are ignored. The @ref trio_register ++function is used to register a user-defined specifier. It takes two argument, ++a callback function and a namespace, and it returns a handle. The handle must ++be used to unregister the specifier later. ++ ++The following example registers a user-define specifier with the "my_namespace" ++namespace: ++ ++@verbatim ++ my_handle = trio_register(my_callback, "my_namespace"); ++@endverbatim ++ ++There can only be one user-defined specifier with a given namespace. There ++can be an unlimited number (subject to maximum length of the namespace) of ++different user-defined specifiers. ++ ++Passing NULL as the namespace argument results in an anonymous reference. ++There can be an unlimited number of anonymous references. ++ ++@b REFERENCES ++ ++There are two ways that a registered callback can be called. Either the ++user-defined specifier must contain the registered namespace in the format ++string, or the handle is passed as an argument to the formatted printing ++function. ++ ++If the namespace is used, then a user-defined pointer must be passed as an ++argument: ++ ++@verbatim ++ trio_printf("%\n", my_data); ++@endverbatim ++ ++If the handle is used, then the user-defined specifier must not contain a ++namespace. Instead the handle must be passed as an argument, followed by a ++user-defined pointer: ++ ++@verbatim ++ trio_printf("%\n", my_handle, my_data); ++@endverbatim ++ ++The two examples above are equivalent. ++ ++There must be exactly one user-defined pointer per user-defined specifier. ++This pointer can be used within the callback function with the ++@ref trio_get_argument getter function (see below). ++ ++The format string is optional. It can be used within the callback function ++with the @ref trio_get_format getter function. ++ ++@b Anonymous @b References ++Anonymous references are specified by passing NULL as the namespace. ++ ++The handle must be passed as an argument followed by a user-defined pointer. ++No namespace can be specified. ++ ++@verbatim ++ anon_handle = trio_register(callback, NULL); ++ trio_printf("%\n", anon_handle, my_data); ++@endverbatim ++ ++@b Restrictions ++ ++@li The length of the namespace string cannot exceed 63 characters. ++@li The length of the user-defined format string cannot exceed 255 characters. ++@li User-defined formatting cannot re-define existing specifiers. ++This restriction was imposed because the existing formatting specifiers have ++a well-defined behaviour, and any re-definition would apply globally to an ++application (imagine a third-party library changing the behaviour of a ++specifier that is crusial to your application). ++ ++@b CALLBACK @b FUNCTION ++ ++The callback function will be called if a matching user-defined specifier ++is found within the formatting string. The callback function takes one input ++parameter, an opaque reference which is needed by the private functions. It ++returns an @c int, which is currently ignored. The prototype is ++ ++@verbatim ++ int (*trio_callback_t)(void *ref); ++@endverbatim ++ ++See the Example section for full examples. ++ ++@b PRINTING @b FUNCTIONS ++ ++The following printing functions must only be used inside a callback function. ++These functions will print to the same output medium as the printf function ++which invoked the callback function. For example, if the user-defined ++specifier is used in an sprintf function, then these print functions will ++output their result to the same string. ++ ++@b Elementary @b Printing ++ ++There are a number of function to print elementary data types. ++ ++@li @ref trio_print_int Print a signed integer. For example: ++@verbatim ++ trio_print_int(42); ++@endverbatim ++@li @ref trio_print_uint Print an unsigned integer. ++@li @ref trio_print_double Print a floating-point number. ++@li @ref trio_print_string Print a string. For example: ++@verbatim ++ trio_print_string("Hello World"); ++ trio_print_string(trio_get_format()); ++@endverbatim ++@li @ref trio_print_pointer Print a pointer. ++ ++@b Formatted @b Printing ++ ++The functions @ref trio_print_ref, @ref trio_vprint_ref, and ++@ref trio_printv_ref outputs a formatted string just like its printf ++equivalents. ++ ++@verbatim ++ trio_print_ref(ref, "There are %d towels\n", 42); ++ trio_print_ref(ref, "%\n", recursive_writer, trio_get_argument(ref)); ++@endverbatim ++ ++@b GETTER @b AND @b SETTER @b FUNCTIONS ++ ++The following getter and setter functions must only be used inside a callback ++function. They can either operate on the modifiers or on special data. ++ ++@b Modifiers ++ ++The value of a modifier, or a boolean indication of its presence or absence, ++can be found or set with the getter and setter functions. ++The generic prototypes of the these getter and setter functions are ++ ++@verbatim ++ int trio_get_???(void *ref); ++ void trio_set_???(void *ref, int); ++@endverbatim ++ ++where @c ??? refers to a modifier. For example, to get the width of the ++user-defined specifier use ++ ++@verbatim ++ int width = trio_get_width(ref); ++@endverbatim ++ ++@b Special @b Data ++ ++Consider the following user-defined specifier, in its two possible referencing ++presentations. ++ ++@verbatim ++ trio_printf("%\n", namespace_writer, argument); ++ trio_printf("%\n", argument); ++@endverbatim ++ ++@ref trio_get_format will get the @p format string, and ++@ref trio_get_argument} will get the @p argument parameter. ++There are no associated setter functions. ++ ++@b EXAMPLES ++ ++The following examples show various types of user-defined specifiers. Although ++each specifier is demonstrated in isolation, they can all co-exist within the ++same application. ++ ++@b Time @b Example ++ ++Print the time in the format "HOUR:MINUTE:SECOND" if "time" is specified inside ++the user-defined specifier. ++ ++@verbatim ++ static int time_print(void *ref) ++ { ++ const char *format; ++ time_t *data; ++ char buffer[256]; ++ ++ format = trio_get_format(ref); ++ if ((format) && (strcmp(format, "time") == 0)) { ++ data = trio_get_argument(ref); ++ if (data == NULL) ++ return -1; ++ strftime(buffer, sizeof(buffer), "%H:%M:%S", localtime(data)); ++ trio_print_string(ref, buffer); ++ } ++ return 0; ++ } ++@endverbatim ++ ++@verbatim ++ int main(void) ++ { ++ void *handle; ++ time_t now = time(NULL); ++ ++ handle = trio_register(time_print, "my_time"); ++ ++ trio_printf("%