Package: mscompress Version: 0.3-3.1 Severity: important Tags: patch
Due to some assumptions about the signedness of char, mscompress and msexpand fail to work at all on PowerPC (and probably other architectures where char is unsigned by default, like ARM). While fixing this, I noticed that it is also incredibly slow as it's doing unbuffered IO. The attached patch fixes this, as well. -- System Information: Debian Release: squeeze/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: i386 (i686) Kernel: Linux 2.6.32-5-686 (SMP w/1 CPU core) Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages mscompress depends on: ii libc6 2.11.2-6 Embedded GNU C Library: Shared lib mscompress recommends no packages. mscompress suggests no packages. -- no debconf information
diff -u mscompress-0.3/ChangeLog mscompress-new/ChangeLog --- mscompress-0.3/ChangeLog 2000-04-15 07:35:16.000000000 -0400 +++ mscompress-new/ChangeLog 2010-10-17 22:53:34.000000000 -0400 @@ -1,3 +1,9 @@ +2010-10-17 Julian Squires <jul...@cipht.net> + + * Fix platforms where char is unsigned, which caused arguments to + be ignored and output files to be truncated. + * Use buffered IO to massively improve performance. + --0.3 Autoconf Solaris getopt.h diff -u mscompress-0.3/mscompress.c mscompress-new/mscompress.c --- mscompress-0.3/mscompress.c 2000-04-15 09:15:38.000000000 -0400 +++ mscompress-new/mscompress.c 2010-10-17 23:00:24.000000000 -0400 @@ -140,18 +140,18 @@ } int -getbyte (int f) +getbyte (FILE *f) { unsigned char b; /* Is there a better way? */ - if (read (f, &b, sizeof (b)) != 1) + if (fread (&b, sizeof (b), 1, f) != 1) return -1; return b; } int -compress (int in, char *inname, int out, char *outname) +compress (FILE *in, char *inname, FILE *out, char *outname) { int ch, i, run, len, match, size, mask; char buf[17]; @@ -170,7 +170,7 @@ } - if (fstat (in, &st) < 0) + if (fstat (fileno(in), &st) < 0) { perror (inname); return -1; @@ -190,27 +190,27 @@ #endif /* Write header to the output file */ - if (write (out, &magic1, sizeof (magic1)) != sizeof (magic1)) + if (fwrite (&magic1, sizeof (magic1), 1, out) != 1) { perror (outname); free (buffer); return -1; } - if (write (out, &magic2, sizeof (magic2)) != sizeof (magic2)) + if (fwrite (&magic2, sizeof (magic2), 1, out) != 1) { perror (outname); free (buffer); return -1; } - if (write (out, &magic3, sizeof (magic3)) != sizeof (magic3)) + if (fwrite (&magic3, sizeof (magic3), 1, out) != 1) { perror (outname); free (buffer); return -1; } - if (write (out, &filesize, sizeof (filesize)) != sizeof (filesize)) + if (fwrite (&filesize, sizeof (filesize), 1, out) != 1) { perror (outname); free (buffer); @@ -268,7 +268,7 @@ } if (!((mask += mask) & 0xFF)) { - if (write (out, buf, size) != size) + if (fwrite (buf, sizeof(unsigned char), size, out) != size) { perror (outname); free (buffer); @@ -283,7 +283,7 @@ while (len > 0); if (size > 1) - if (write (out, buf, size) != size) + if (fwrite (buf, sizeof(unsigned char), size, out) != size) { perror (outname); free (buffer); @@ -309,9 +309,9 @@ void main (int argc, char **argv) { - int in, out; + FILE *in, *out; char *argv0; - char c; + int c; char name[0x100]; argv0 = argv[0]; @@ -350,8 +350,8 @@ continue; } - in = open (argv[0], O_RDONLY); - if (in < 0) + in = fopen (argv[0], "rb"); + if (in == NULL) { perror (argv[0]); exit (1); @@ -360,16 +360,16 @@ strcpy (name, argv[0]); strcat (name, "_"); - out = open (name, O_WRONLY | O_CREAT | O_EXCL, 0644); - if (out < 0) + out = fopen (name, "wxb"); + if (out == NULL) { perror (name); exit (1); } compress (in, argv[0], out, name); - close (in); - close (out); + fclose (in); + fclose (out); argc--; argv++; diff -u mscompress-0.3/msexpand.c mscompress-new/msexpand.c --- mscompress-0.3/msexpand.c 2000-04-15 09:15:45.000000000 -0400 +++ mscompress-new/msexpand.c 2010-10-17 22:47:31.000000000 -0400 @@ -36,18 +36,18 @@ #define F 16 int -getbyte (int f) +getbyte (FILE *f) { unsigned char b; /* Is there a better way? */ - if (read (f, &b, sizeof (b)) != 1) + if (fread (&b, sizeof (b), 1, f) != 1) return -1; return b; } int -expand (int in, char *inname, int out, char *outname) +expand (FILE *in, char *inname, FILE *out, char *outname) { int bits, ch, i, j, len, mask; unsigned char *buffer; @@ -58,7 +58,7 @@ unsigned short reserved; unsigned int filesize; - if (read (in, &magic1, sizeof (magic1)) != sizeof (magic1)) + if (fread (&magic1, sizeof (magic1), 1, in) != 1) { perror (inname); return -1; @@ -70,19 +70,19 @@ if (magic1 == 0x44445A53L) #endif { - if (read (in, &magic2, sizeof (magic2)) != sizeof (magic2)) + if (fread (&magic2, sizeof (magic2), 1, in) != 1) { perror (inname); return -1; } - if (read (in, &reserved, sizeof (reserved)) != sizeof (reserved)) + if (fread (&reserved, sizeof (reserved), 1, in) != 1) { perror (inname); return -1; } - if (read (in, &filesize, sizeof (filesize)) != sizeof (filesize)) + if (fread (&filesize, sizeof (filesize), 1, in) != 1) { perror (inname); return -1; @@ -104,19 +104,19 @@ if (magic1 == 0x4A41574BL) #endif { - if (read (in, &magic2, sizeof (magic2)) != sizeof (magic2)) + if (fread (&magic2, sizeof (magic2), 1, in) != 1) { perror (inname); return -1; } - if (read (in, &magic3, sizeof (magic3)) != sizeof (magic3)) + if (fread (&magic3, sizeof (magic3), 1, in) != 1) { perror (inname); return -1; } - if (read (in, &reserved, sizeof (reserved)) != sizeof (reserved)) + if (fread (&reserved, sizeof (reserved), 1, in) != 1) { perror (inname); return -1; @@ -136,15 +136,14 @@ } else { - fprintf (stderr, "%s: This is not a MS-compressed file\n", inname); + fprintf (stderr, "%s: This is not an MS-compressed file\n", inname); return -1; } - buffer = malloc (N); if (!buffer) { - fprintf (stderr, "%s:No memory\n", inname); + fprintf (stderr, "%s: No memory\n", inname); return -1; } @@ -170,7 +169,7 @@ while (len--) { buffer[i] = buffer[j]; - if (write (out, &buffer[i], 1) != 1) + if (fwrite (&buffer[i], sizeof (unsigned char), 1, out) != 1) { perror (outname); return -1; @@ -187,7 +186,7 @@ if (ch == -1) break; buffer[i] = ch; - if (write (out, &buffer[i], 1) != 1) + if (fwrite (&buffer[i], sizeof (unsigned char), 1, out) != 1) { perror (outname); return -1; @@ -218,9 +217,9 @@ void main (int argc, char **argv) { - int in, out; + FILE *in, *out; char *argv0; - char c; + int c; char name[0x100]; argv0 = argv[0]; @@ -247,7 +246,7 @@ { if (isatty (STDIN_FILENO)) usage (argv0); - if (expand (STDIN_FILENO, "STDIN", STDOUT_FILENO, "STDOUT") < 0) + if (expand (stdin, "STDIN", stdout, "STDOUT") < 0) exit (1); exit (0); } @@ -262,8 +261,8 @@ continue; } - in = open (argv[0], O_RDONLY); - if (in < 0) + in = fopen (argv[0], "rb"); + if (in == NULL) { perror (argv[0]); exit (1); @@ -272,16 +271,16 @@ strcpy (name, argv[0]); name[strlen (name) - 1] = 0; - out = open (name, O_WRONLY | O_CREAT | O_EXCL, 0644); - if (out < 0) + out = fopen (name, "wxb"); + if (out == NULL) { perror (name); exit (1); } expand (in, argv[0], out, name); - close (in); - close (out); + fclose (in); + fclose (out); argc--; argv++;