--- Begin Message ---
Package: catdoc
Version: 0.94.2-1
Severity: important
Tags: patch
On amd64 using xls2csv negative numbers are exported as huge positive numbers
I believe the real problem is in xls.parse.c:format_rk
which should be:
#include <stdio.h>
....
if ( *(rec) & 0x02 )
{
int32_t ival=getlong((unsigned char *)rec,0);
value=(double)(ival>>2);
}
But there are many typecast issues, I tried to handle some of them:
Patch:
diff -w -Naur catdoc-0.94.2/src/analyze.c catdoc-0.94.2.mine/src/analyze.c
--- catdoc-0.94.2/src/analyze.c 2006-02-24 18:44:06.000000000 +0100
+++ catdoc-0.94.2.mine/src/analyze.c 2009-11-03 14:42:35.000000000 +0100
@@ -39,18 +39,18 @@
}
catdoc_read(buffer,4,1,f);
buffer[4]=0;
- if (strncmp(buffer,write_sign,2)==0) {
+ if (strncmp((char *) buffer,write_sign,2)==0) {
printf("[Windows Write file. Some garbage expected]\n");
get_unicode_char=get_8bit_char;
return process_file(f,LONG_MAX);
- } else if (strncmp(buffer,rtf_sign,4)==0) {
+ } else if (strncmp((char *) buffer,rtf_sign,4)==0) {
return parse_rtf(f);
- } else if (strncmp(buffer,old_word_sign,2)==0) {
- fread(buffer+4,1,124,f);
+ } else if (strncmp((char *)buffer,old_word_sign,2)==0) {
+ fread((char *) buffer+4,1,124,f);
return parse_word_header(buffer,f,128,0);
}
fread(buffer+4,1,4,f);
- if (strncmp(buffer,ole_sign,8)==0) {
+ if (strncmp((char *) buffer,ole_sign,8)==0) {
if ((new_file=ole_init(f, buffer, 8)) != NULL) {
set_ole_func();
while((ole_file=ole_readdir(new_file)) != NULL) {
@@ -71,7 +71,7 @@
}
} else {
set_std_func();
- copy_out(f,buffer);
+ copy_out(f,(char *) buffer);
return 0;
}
diff -w -Naur catdoc-0.94.2/src/numutils.c catdoc-0.94.2.mine/src/numutils.c
--- catdoc-0.94.2/src/numutils.c 2006-02-24 18:44:06.000000000 +0100
+++ catdoc-0.94.2.mine/src/numutils.c 2009-11-03 14:42:35.000000000 +0100
@@ -5,25 +5,32 @@
/* This file is part of catdoc project */
/* (c) Victor Wagner 1996-2003, (c) Alex Ott 2003 */
/*****************************************************************/
+#include <stdint.h>
+#include <stdio.h>
/********************************************************************/
/* Reads 2-byte LSB int from buffer at given offset platfom-indepent
* way
*********************************************************************/
-unsigned int getshort(unsigned char *buffer,int offset) {
- return (unsigned short int)buffer[offset]|((unsigned short
int)buffer[offset+1]<<8);
+uint32_t getshort(unsigned char *buffer,int offset) {
+ // fprintf(stderr," GS %d:
%d,%d=%d\n",offset,(uint16_t)buffer[offset],(uint16_t)buffer[offset+1]<<8,(uint16_t)buffer[offset]|((uint16_t)buffer[offset+1]<<8));
+ return (uint16_t)buffer[offset]|((uint16_t)buffer[offset+1]<<8);
}
+
/********************************************************************/
/* Reads 4-byte LSB int from buffer at given offset almost platfom-indepent
* way
*********************************************************************/
-long int getlong(unsigned char *buffer,int offset) {
- return (long)buffer[offset]|((long)buffer[offset+1]<<8L)
- |((long)buffer[offset+2]<<16L)|((long)buffer[offset+3]<<24L);
+int32_t getlong(unsigned char *buffer,int offset) {
+ int32_t res = ((long)buffer[offset])|((long)buffer[offset+1]<<8L)
|((long)buffer[offset+2]<<16L)|((long)buffer[offset+3]<<24L);
+ fprintf(stderr," LL %d: %d,%d,%d,%d=%d
res=%d\n",offset,(long)buffer[offset],((long)buffer[offset+1]<<8L),((long)buffer[offset+2]<<16L),(long)buffer[offset+3]<<24L,
+
((long)buffer[offset])|((long)buffer[offset+1]<<8L)|((long)buffer[offset+2]<<16L)|(long)buffer[offset+3]<<24L,res
);
+ return (res);
}
-unsigned long int getulong(unsigned char *buffer,int offset) {
- return (unsigned long)buffer[offset]|((unsigned
long)buffer[offset+1]<<8L)
+uint32_t getulong(unsigned char *buffer,int offset) {
+ uint32_t res = ((unsigned long)buffer[offset])|((unsigned
long)buffer[offset+1]<<8L)
|((unsigned long)buffer[offset+2]<<16L)|((unsigned
long)buffer[offset+3]<<24L);
+ return res;
}
diff -w -Naur catdoc-0.94.2/src/ole.c catdoc-0.94.2.mine/src/ole.c
--- catdoc-0.94.2/src/ole.c 2006-02-25 16:28:14.000000000 +0100
+++ catdoc-0.94.2.mine/src/ole.c 2009-11-03 14:42:35.000000000 +0100
@@ -97,7 +97,7 @@
if ( ret != BBD_BLOCK_SIZE ) {
return NULL;
}
- if (strncmp(oleBuf,ole_sign,8) != 0) {
+ if (strncmp((char *)oleBuf,(char *) ole_sign,8) != 0) {
return NULL;
}
sectorSize = 1<<getshort(oleBuf,0x1e);
diff -w -Naur catdoc-0.94.2/src/pptparse.c catdoc-0.94.2.mine/src/pptparse.c
--- catdoc-0.94.2/src/pptparse.c 2006-02-24 18:44:06.000000000 +0100
+++ catdoc-0.94.2.mine/src/pptparse.c 2009-11-03 14:42:35.000000000 +0100
@@ -152,7 +152,7 @@
text_len=reclen/2;
for(i=0; i < text_len; i++) {
catdoc_read(buf,2,1,input);
- u=(unsigned short)getshort(buf,0);
+ u=(unsigned short)getshort((unsigned char
*)buf,0);
if(u!=0x0d)
fputs(convert_char(u),stdout);
else
diff -w -Naur catdoc-0.94.2/src/xls.h catdoc-0.94.2.mine/src/xls.h
--- catdoc-0.94.2/src/xls.h 2006-02-24 18:44:06.000000000 +0100
+++ catdoc-0.94.2.mine/src/xls.h 2009-11-03 14:42:35.000000000 +0100
@@ -34,7 +34,7 @@
char *format_rk(char *rec,short int format_code);
char *gettypename(long rectype);
void parse_sst(char *sstbuf,int bufsize);
-void process_item (int rectype, int reclen, char *rec);
+void process_item (unsigned int rectype, unsigned int reclen, char *rec);
unsigned char **allocate(int row,int col);
char *copy_unicode_string(unsigned char **src);
char convert8to8(char *src,int count);
diff -w -Naur catdoc-0.94.2/src/xlsparse.c catdoc-0.94.2.mine/src/xlsparse.c
--- catdoc-0.94.2/src/xlsparse.c 2006-02-24 18:44:06.000000000 +0100
+++ catdoc-0.94.2.mine/src/xlsparse.c 2009-11-03 14:42:35.000000000 +0100
@@ -16,6 +16,8 @@
#include "float.h"
#include <math.h>
#include <time.h>
+#include <stdio.h>
+
#ifndef HAVE_STRFTIME
#include "../compat/strftime.h"
#endif
@@ -33,7 +35,7 @@
void CleanUpFormatIdxUsed(void);
void do_table(FILE *input,char *filename) {
- long rectype;
+ unsigned int rectype;
long reclen,build_year=0,build_rel=0,offset=0;
int eof_flag=0;
int itemsread=1;
@@ -84,7 +86,7 @@
exit(1);
}
while(itemsread){
- char buffer[2];
+ unsigned char buffer[2];
rectype = 0;
itemsread = catdoc_read(buffer, 2, 1, input);
if (catdoc_eof(input)) {
@@ -109,7 +111,7 @@
}
}
/* fprintf(stderr,"Rectype 0x%04X reclen=%d\n",rectype, reclen); */
- process_item(rectype,reclen,rec);
+ process_item(rectype,reclen, (char *)rec);
if (rectype == MSEOF) {
eof_flag=1;
} else {
@@ -121,16 +123,16 @@
unsigned char **sst=NULL;/* Shared string table parsed into array of strings in
output encoding*/
int sstsize = 0; /*Number of strings in SST*/
-unsigned char *sstBuffer=NULL; /*Unparsed sst to accumulate all its parts*/
+char *sstBuffer=NULL; /*Unparsed sst to accumulate all its parts*/
int sstBytes = 0; /*Size of SST Data, already accumulated in the buffer */
-int codepage=1251; /*default*/
-int prev_rectype=0;
+unsigned int codepage=1251; /*default*/
+unsigned int prev_rectype=0;
/* holds a pointer to formula value, becouse value itself would be in
* next biff record
*/
unsigned char **saved_reference = NULL;
-void process_item (int rectype, int reclen, char *rec) {
+void process_item (unsigned int rectype, unsigned int reclen, char *rec) {
if (rectype != CONTINUE && prev_rectype == SST) {
/* we have accumulated unparsed SST, and now encountered
* another record, which indicates that SST is ended */
@@ -150,7 +152,7 @@
case 0x42: {
if (source_charset) break;
- codepage=getshort(rec,0);
+ codepage=getshort((unsigned char *)rec,0);
/*fprintf(stderr,"CODEPAGE %d\n",codepage); */
if (codepage!=1200) {
const char *cp = charset_from_codepage(codepage);
@@ -159,8 +161,8 @@
break;
}
case FORMAT: {
- int format_code;
- format_code=getshort(rec,0);
+ unsigned int format_code;
+ format_code=getshort((unsigned char *)rec,0);
SetFormatIdxUsed(format_code);
/* this debug code prints format string */
/*
@@ -214,40 +216,42 @@
return;
}
case LABEL: {
- int row,col;
+ unsigned int row,col;
unsigned char **pcell;
unsigned char *src=(unsigned char *)rec+6;
saved_reference=NULL;
- row = getshort(rec,0);
- col = getshort(rec,2);
+ row = getshort((unsigned char *) rec,0);
+ col = getshort((unsigned char *) rec,2);
/* fprintf(stderr,"LABEL!\n"); */
pcell=allocate(row,col);
- *pcell=copy_unicode_string(&src);
+ *pcell=(unsigned char *)copy_unicode_string(&src);
break;
}
- case BLANK: { int row,col;unsigned char **pcell;
- row = getshort(rec,0);
- col = getshort(rec,2);
+ case BLANK: {
+ unsigned int row, col;
+ unsigned char **pcell;
+ row = getshort((unsigned char *) rec,0);
+ col = getshort((unsigned char *) rec,2);
pcell=allocate(row,col);
*pcell=NULL;
break;
}
case MULBLANK: {
- int row, startcol,endcol;
+ unsigned int row, startcol,endcol;
unsigned char **pcell;
- row = getshort(rec,0);
- startcol = getshort(rec,2);
- endcol=getshort(rec,reclen-2);
+ row = getshort((unsigned char *)rec,0);
+ startcol = getshort((unsigned char *)rec,2);
+ endcol=getshort((unsigned char *)rec,reclen-2);
pcell=allocate(row,endcol);
*pcell=NULL;
break;
}
case CONSTANT_STRING: {
- int row = getshort(rec,0);
- int col = getshort(rec,2);
+ unsigned int row = getshort((unsigned char *) rec,0);
+ unsigned int col = getshort((unsigned char *) rec,2);
unsigned char **pcell;
- int string_no=getshort(rec,6);
+ int string_no=getshort((unsigned char *) rec,6);
if (!sst) {
fprintf(stderr,"CONSTANT_STRING before SST parsed\n");
exit(1);
@@ -260,14 +264,15 @@
fprintf(stderr,"string index out of boundary\n");
exit(1);
} else if (sst[string_no] !=NULL) {
- int len;
+ size_t len;
char *outptr;
- len=strlen(sst[string_no]);
- outptr=*pcell=malloc(len+1);
- strcpy(outptr,sst[string_no]);
+ len=strlen((char *) sst[string_no]);
+ outptr= ((char *) malloc(len+1));
+ *pcell = (unsigned char *) outptr;
+ strcpy((char *) outptr,(char *)sst[string_no]);
} else {
*pcell=malloc(1);
- strcpy(*pcell,"");
+ strcpy((char *) *pcell,"");
}
break;
}
@@ -275,61 +280,61 @@
case 0x103:
case 0x303:
case NUMBER: {
- int row,col;
+ unsigned int row,col;
unsigned char **pcell;
saved_reference=NULL;
- row = getshort(rec,0)-startrow;
- col = getshort(rec,2);
+ row = getshort((unsigned char *)rec,0)-startrow;
+ col = getshort((unsigned char *)rec,2);
pcell=allocate(row,col);
- *pcell=strdup(format_double(rec,6,getshort(rec,4)));
+ *pcell=(unsigned char *)
strdup(format_double(rec,6,getshort((unsigned char *) rec,4)));
break;
}
case INTEGER_CELL: {
- int row,col;
+ unsigned int row,col;
unsigned char **pcell;
- row = getshort(rec,0)-startrow;
- col = getshort(rec,2);
+ row = getshort((unsigned char *) rec,0)-startrow;
+ col = getshort((unsigned char *) rec,2);
pcell=allocate(row,col);
- *pcell=strdup(format_int(getshort(rec,7),getshort(rec,4)));
+ *pcell=(unsigned char *) strdup(format_int(getshort((unsigned
char *)rec,7),getshort((unsigned char *) rec,4)));
break;
}
case RK: {
- int row,col,format_code;
+ unsigned int row,col,format_code;
unsigned char **pcell;
saved_reference=NULL;
- row = getshort(rec,0)-startrow;
- col = getshort(rec,2);
+ row = getshort((unsigned char *) rec,0)-startrow;
+ col = getshort((unsigned char *) rec,2);
pcell=allocate(row,col);
- format_code = getshort(rec,4);
- *pcell=strdup(format_rk(rec+6,format_code));
+ format_code = getshort((unsigned char *) rec,4);
+ *pcell= (unsigned char *) strdup(format_rk(rec+6,format_code));
break;
}
case MULRK: {
- int row,col,startcol,endcol,offset,format_code;
+ unsigned int row,col,startcol,endcol,offset,format_code;
unsigned char **pcell;
- row = getshort(rec,0)-startrow;
- startcol = getshort(rec,2);
- endcol = getshort(rec,reclen-2);
+ row = getshort((unsigned char *) rec,0)-startrow;
+ startcol = getshort((unsigned char *) rec,2);
+ endcol = getshort((unsigned char *) rec,reclen-2);
saved_reference=NULL;
for (offset=4,col=startcol;col<=endcol;offset+=6,col++) {
pcell=allocate(row,col);
- format_code=getshort(rec,offset);
- *pcell=strdup(format_rk(rec+offset+2,format_code));
+ format_code=getshort((unsigned char *) rec,offset);
+ *pcell=(unsigned char
*)strdup(format_rk(rec+offset+2,format_code));
}
break;
}
case FORMULA: {
- int row,col;
+ unsigned int row,col;
unsigned char **pcell;
saved_reference=NULL;
- row = getshort(rec,0)-startrow;
- col = getshort(rec,2);
+ row = getshort((unsigned char *) rec,0)-startrow;
+ col = getshort((unsigned char *) rec,2);
pcell=allocate(row,col);
if (((unsigned char)rec[12]==0xFF)&&(unsigned
char)rec[13]==0xFF) {
/* not a floating point value */
@@ -337,17 +342,17 @@
/*boolean*/
char buf[2]="0";
buf[0]+=rec[9];
- *pcell=strdup(buf);
+ *pcell= (unsigned char *) strdup(buf);
} else if (rec[6]==2) {
/*error*/
char buf[6]="ERROR";
- *pcell=strdup(buf);
+ *pcell=(unsigned char *) strdup(buf);
} else if (rec[6]==0) {
saved_reference=pcell;
}
} else {
- int format_code=getshort(rec,4);
- *pcell=strdup(format_double(rec,6,format_code));
+ int format_code=getshort((unsigned char *) rec,4);
+ *pcell= (unsigned char *)
strdup(format_double(rec,6,format_code));
}
break;
}
@@ -357,7 +362,7 @@
fprintf(stderr,"String record without preceeding string
formula\n");
break;
}
- *saved_reference=copy_unicode_string(&src);
+ *saved_reference= (unsigned char *) copy_unicode_string(&src);
break;
}
case BOF: {
@@ -370,7 +375,7 @@
case XF:
case 0x43: /*from perl module Spreadsheet::ParseExecel */
{
- short int formatIndex = getshort(rec,2);
+ short int formatIndex = getshort((unsigned char *)
rec,2);
/* we are interested only in format index here */
if (formatTableIndex >= formatTableSize) {
formatTable=realloc(formatTable,
@@ -487,7 +492,7 @@
*src+=start_offset;
len = count;
*dest=0;l=0;
- for (s=*src,d=dest,i=0;i<count;i++,s+=charsize) {
+ for (s=(char *) *src,d=dest,i=0;i<count;i++,s+=charsize) {
/* fprintf(stderr,"l=%d len=%d count=%d
charsize=%d\n",l,len,count,charsize); */
if ( (charsize == 1 && (*s == 1 || *s == 0)) ||
(charsize == 2 && (*s == 1 || *s == 0) &&
*(s+1) != 4)) {
@@ -499,7 +504,7 @@
continue;
}
if ( charsize == 2 ){
- u=(unsigned short)getshort(s,0);
+ u=(unsigned short)getshort((unsigned char *)s,0);
c=convert_char(u);
/* fprintf(stderr,"char=%02x
%02x\n", *s, *(s+1)); */
} else {
@@ -523,7 +528,7 @@
l+=dl;
}
}
- *src=s+to_skip;
+ *src=(unsigned char *)(s+to_skip);
return dest;
}
@@ -583,9 +588,10 @@
static char FormatIdxUsed[NUMOFDATEFORMATS];
void CleanUpFormatIdxUsed() {
- int i;
- for (i=0;i<NUMOFDATEFORMATS; i++);
- FormatIdxUsed[i]=0;
+ unsigned int i;
+ for (i=0;i<NUMOFDATEFORMATS; i++) {
+ FormatIdxUsed[i]=(char)0;
+ }
}
/*
@@ -713,7 +719,8 @@
if ( *(rec) & 0x02 )
{
- value=(double)(getlong(rec,0)>>2);
+ int32_t ival=getlong((unsigned char *)rec,0);
+ value=(double)(ival>>2);
}
else {
union { char cc[8];
@@ -759,7 +766,7 @@
unsigned char *barrier=(unsigned char *)sstbuf+bufsize; /*pointer to
end of buffer*/
unsigned char **parsedString;/*pointer into parsed array*/
- sstsize = getlong(sstbuf+4,0);
+ sstsize = getlong((unsigned char *)sstbuf+4,0);
sst=malloc(sstsize*sizeof(char *));
if (sst == NULL) {
@@ -767,10 +774,10 @@
exit(1);
}
memset(sst,0,sstsize*sizeof(char *));
- for (i=0,parsedString=sst,curString=sstbuf+8;
+ for (i=0,parsedString=sst,curString= (unsigned char *)(sstbuf+8);
i<sstsize && curString<barrier; i++,parsedString++) {
/* fprintf(stderr,"copying %d string\n",i); */
- *parsedString = copy_unicode_string(&curString);
+ *parsedString = (unsigned char *) copy_unicode_string(&curString);
}
/* fprintf(stderr,"end sst i=%d sstsize=%d\n",i,sstsize); */
-- System Information:
Debian Release: 5.0.3
APT prefers stable
APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.26-2-amd64 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE= (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages catdoc depends on:
ii libc6 2.7-18 GNU C Library: Shared libraries
catdoc recommends no packages.
Versions of packages catdoc suggests:
ii tk8.3 [wish] 8.3.5-14 Tk toolkit for Tcl and X11, v8.3 -
-- no debconf information
--- End Message ---