The attached patch fixes the stability problems experienced with Sword and 
ciphered and locked modules.

To see unpatched Sword crash, just run

mod2imp GerHfa2002              and
mod2imp GerHfaLex2002

without the correct unlock key.

The patch works against 1.5.9 and does the following:
-fix one unchecked pointer access in zverse.cpp, based on Joachim's suggestion 
with small improvements such as one removed strlen()
-allow the return value of the zip uncompression code to be used correctly. 
Now uncompression will detect that it has corrupt data (when deciphering with 
a wrong key) and return an empty string in that case.

This seems to finally fix the stability issues for me.

I would be very glad if the patch could be applied to HEAD and a bugfix 
release of Sword (1.5.9.1 or something, including Daniel's large compile and 
automake fixes) be released, otherwise our users cannot profit from it 
easily.

Martin
Index: src/modules/common/zverse.cpp
===================================================================
--- src/modules/common/zverse.cpp	(Revision 2017)
+++ src/modules/common/zverse.cpp	(Arbeitskopie)
@@ -237,6 +237,7 @@
 		unsigned long len = 0;
 		compressor->Buf(0, &len);
 		cacheBuf = (char *)calloc(len + 1, 1);
+		cacheBuf[0]='\0'; //just in case len==0
 		memcpy(cacheBuf, compressor->Buf(), len);
 
 		cacheTestament = testmt;
@@ -257,13 +258,11 @@
 
 void zVerse::zReadText(char testmt, long start, unsigned short size, SWBuf &inBuf) {
 	inBuf = "";
-	inBuf.setFillByte(0);
-	inBuf.setSize(size+1);
-	if (size > 0) {
-		if (cacheBuf)
-			strncpy(inBuf.getRawData(), &(cacheBuf[start]), size);
+	if ( (size > 0) && cacheBuf && ((start+size) <= strlen(cacheBuf)) ){ //TODO: optimize this, remove strlen
+		inBuf.setFillByte(0);
+		inBuf.setSize(size+1);
+		strncpy(inBuf.getRawData(), &(cacheBuf[start]), size);
 	}
-	inBuf.setSize(strlen(inBuf.c_str()));
 }
 
 
Index: src/modules/common/zipcomprs.cpp
===================================================================
--- src/modules/common/zipcomprs.cpp	(Revision 2017)
+++ src/modules/common/zipcomprs.cpp	(Arbeitskopie)
@@ -79,7 +79,7 @@
 	if (len)
 	{
 		//printf("Doing compress\n");
-		if (compress((Bytef*)zbuf, &zlen, (const Bytef*)buf, len)!=Z_OK)
+		if (compress((Bytef*)zbuf, &zlen, (const Bytef*)buf, len) != Z_OK)
 		{
 			printf("ERROR in compression\n");
 		}
@@ -89,7 +89,7 @@
 	}
 	else
 	{
-		fprintf(stderr, "No buffer to compress\n");
+		fprintf(stderr, "ERROR: no buffer to compress\n");
 	}
 	delete [] zbuf;
 	free (buf);
@@ -144,15 +144,18 @@
 		unsigned long blen = zlen*20;	// trust compression is less than 1000%
 		char *buf = new char[blen]; 
 		//printf("Doing decompress {%s}\n", zbuf);
-		if (uncompress((Bytef*)buf, &blen, (Bytef*)zbuf, zlen) != Z_OK) {
-			fprintf(stderr, "no room in outbuffer to during decompression. see zipcomp.cpp\n");
+		slen = 0;
+		switch (uncompress((Bytef*)buf, &blen, (Bytef*)zbuf, zlen)){
+			case Z_OK: SendChars(buf, blen); slen = blen; break;
+			case Z_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during decompression.\n"); break;
+			case Z_BUF_ERROR: fprintf(stderr, "ERROR: not enough room in the out buffer during decompression.\n"); break;
+			case Z_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data during decompression.\n"); break;
+			default: fprintf(stderr, "ERROR: an unknown error occured during decompression.\n"); break;
 		}
-		SendChars(buf, blen);
 		delete [] buf;
-		slen = blen;
 	}
 	else {
-		fprintf(stderr, "No buffer to decompress!\n");
+		fprintf(stderr, "ERROR: no buffer to decompress!\n");
 	}
 	//printf("Finished decoding\n");
 	free (zbuf);
_______________________________________________
sword-devel mailing list: sword-devel@crosswire.org
http://www.crosswire.org/mailman/listinfo/sword-devel
Instructions to unsubscribe/change your settings at above page

Reply via email to