Package: pcf2bdf
Version: 1.04-2
Severity: normal
Tags: patch
User: [EMAIL PROTECTED]
Usertags: origin-ubuntu ubuntu-patch hardy
I was trying to use pcf2bdf to look at
/usr/share/fonts/X11/misc/unifont.pcf.gz (on Ubuntu, but I don't *think*
it matters), and found that it crashes as follows:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Program received signal SIGABRT, Aborted.
0xb7f98410 in __kernel_vsyscall ()
(gdb) bt
#0 0xb7f98410 in __kernel_vsyscall ()
#1 0xb7d38f35 in raise () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7d3a8b1 in abort () from /lib/tls/i686/cmov/libc.so.6
#3 0xb7f496a0 in __gnu_cxx::__verbose_terminate_handler () from
/usr/lib/libstdc++.so.6
#4 0xb7f46f25 in ?? () from /usr/lib/libstdc++.so.6
#5 0xb7f46f62 in std::terminate () from /usr/lib/libstdc++.so.6
#6 0xb7f4708a in __cxa_throw () from /usr/lib/libstdc++.so.6
#7 0xb7f476be in operator new () from /usr/lib/libstdc++.so.6
#8 0xb7f4779d in operator new[] () from /usr/lib/libstdc++.so.6
#9 0x08049f15 in main (argc=2, argv=0xbf8e6e84) at pcf2bdf.cc:708
(gdb) up
#1 0xb7d38f35 in raise () from /lib/tls/i686/cmov/libc.so.6
(gdb) up
#2 0xb7d3a8b1 in abort () from /lib/tls/i686/cmov/libc.so.6
(gdb) up
#3 0xb7f496a0 in __gnu_cxx::__verbose_terminate_handler () from
/usr/lib/libstdc++.so.6
(gdb) up
#4 0xb7f46f25 in ?? () from /usr/lib/libstdc++.so.6
(gdb) up
#5 0xb7f46f62 in std::terminate () from /usr/lib/libstdc++.so.6
(gdb) up
#6 0xb7f4708a in __cxa_throw () from /usr/lib/libstdc++.so.6
(gdb) up
#7 0xb7f476be in operator new () from /usr/lib/libstdc++.so.6
(gdb) up
#8 0xb7f4779d in operator new[] () from /usr/lib/libstdc++.so.6
(gdb) up
#9 0x08049f15 in main (argc=2, argv=0xbf8e6e84) at pcf2bdf.cc:708
708 check_memory((metrics = new metric_t[nMetrics]));
(gdb) p nMetrics
$1 = -29611
Comparing the implementation of PCF reading in pcf2bdf.cc with that in
libxfont/src/bitmap/pcfread.c, I found that the latter reads logically
int16-typed values into int variables, whereas the former reads
logically int16-typed variables into int16 variables. This means that
pcf2bdf.cc will deal with 16-bit signed overflow differently from
pcfread.c.
I think the best approach is simply to return int from the int16 reading
functions and allow the usual C arithmetic conversion rules to take care
of things when assigning the result to an int16. In the case of the
metric count, this is in fact assigned to an int32 even though the file
format only allocates two bytes for it in this particular case (it's
four bytes elsewhere), and so this change is enough to make these large
compressed metrics tables work in my tests.
Thanks,
--
Colin Watson [EMAIL PROTECTED]
Index: pcf2bdf.cc
===================================================================
--- pcf2bdf.cc.orig
+++ pcf2bdf.cc
@@ -262,26 +262,29 @@
}
-int16 make_int16(int a, int b)
-{
- int16 value;
- value = (int16)(a & 0xff) << 8;
- value |= (int16)(b & 0xff);
+/* These all return int rather than int16 in order to handle values
+ * between 32768 and 65535 more gracefully.
+ */
+int make_int16(int a, int b)
+{
+ int value;
+ value = (a & 0xff) << 8;
+ value |= (b & 0xff);
return value;
}
-int16 read_int16_big(void)
+int read_int16_big(void)
{
int a = read8();
int b = read8();
return make_int16(a, b);
}
-int16 read_int16_little(void)
+int read_int16_little(void)
{
int a = read8();
int b = read8();
return make_int16(b, a);
}
-int16 read_int16(void)
+int read_int16(void)
{
if (format.is_little_endien())
return read_int16_little();