[PATCH] setup.exe: Use String object to hold the exception description in an Exception object.

Pavel Tsekov ptsekov@gmx.net
Sun Feb 16 17:46:00 GMT 2003


Hello,

This patch was inspired by a bug present in the CVS version of setup.exe.

In the current code an exception of type class Exception is thrown like 
this:

  throw new Exception ("__LINE__ __FILE__",
                       String("something").cstr_oneuse(),
                       APPERR_something);

What is wrong here is using String::cstr_oneuse() to get the exception 
description. When an exception thrown this way is catched at some point, 
it is highly unlikely that the description will be valid anymore. The 
current way that the description is constructed, using temporary string 
objects, ensures that the description will never be valid when the 
exception is caught.

My fix uses a String object to hold the description in the Exception 
object. Additionally it adds  a second constructor to the Exception class, 
which takes a object of type String as the second argument. I did this 
change, hoping that this will make the code slightly faster and not so 
"ugly".  So now you construct an Exception object like this:

  new Exception ("__LINE__ __FILE__", String ("something"), 
                 APPERR_something);

The new constructor uses operator = of the String class which is faster 
than the constructor taking String&.

Here is Changelog entry:

2003-02-16  Pavel Tsekov  <ptsekov@gmx.net>

	* Exception.h: Declare new constructor.
	(Exception::_message): Change the type from 'const char *' to
	'class String'.
	(Exception::~Exception): Implement destructor (make gcc shut up).
	* Exception.cc: Implement new constructor.
	(Exception::what): Use String::cstr_oneuse ().
	* download.cc (validateCachedPackage): Use the constructor, which
	takes String& as its second argument, when throwing objects
	of type Exception.
	(check_for_cached): Ditto.
	* install.cc (install_one_source): Ditto.

P.S. To reproduce the bug, use custom mirror, which has a setup.ini 
file with invalid md5 checksums for binary packages, and try to install
a package from it. You can use http://ptsekov.gamersrevolt.it/cygwin -
I've put a broken setup.ini file there. Try to install the 
package nfs-server 2.2.47-4.

-------------- next part --------------
Index: Exception.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/Exception.cc,v
retrieving revision 2.2
diff -u -p -r2.2 Exception.cc
--- Exception.cc	10 Nov 2002 03:40:36 -0000	2.2
+++ Exception.cc	16 Feb 2003 13:13:06 -0000
@@ -19,10 +19,16 @@ Exception::Exception (char const *where,
 {
 }
 
+Exception::Exception (char const *where, const String &message, int _appErrNo)
+  : appErrNo (_appErrNo)
+{
+  _message = message;
+}
+
 char const *
 Exception::what() const throw()
 {
-  return _message;
+  return _message.cstr_oneuse ();
 }
 
 int
Index: Exception.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/Exception.h,v
retrieving revision 2.2
diff -u -p -r2.2 Exception.h
--- Exception.h	10 Nov 2002 03:40:36 -0000	2.2
+++ Exception.h	16 Feb 2003 13:13:07 -0000
@@ -21,15 +21,18 @@
 #define _EXCEPTION_H_
 
 #include <exception>
+#include "String++.h"
 
 /* Generic excpetion class for throwing exceptions */
 class Exception : public std::exception {
 public:
   Exception (char const *where, char const *message, int appErrNo = 0);
+  Exception (char const *where, const String &message, int appErrNo = 0);
+  ~Exception () throw () {}
   char const *what() const throw();
   int errNo() const;
 private:
-  char const *_message;
+  String _message;
   int appErrNo;
 };
 
Index: download.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/download.cc,v
retrieving revision 2.35
diff -u -p -r2.35 download.cc
--- download.cc	9 Nov 2002 13:44:52 -0000	2.35
+++ download.cc	16 Feb 2003 13:13:07 -0000
@@ -85,7 +85,7 @@ validateCachedPackage (String const &ful
 	}
       delete thefile;
       if (count < 0)
-	throw new Exception ("__LINE__ __FILE__", (String ("IO Error reading ") + pkgsource.Cached()).cstr_oneuse(), APPERR_IO_ERROR);
+	throw new Exception ("__LINE__ __FILE__", String ("IO Error reading ") + pkgsource.Cached(), APPERR_IO_ERROR);
       
       md5_byte_t tempdigest[16];
       md5_finish(&pns, tempdigest);
@@ -125,7 +125,7 @@ check_for_cached (packagesource & pkgsou
 	if (validateCachedPackage (prefix + pkgsource.Canonical (), pkgsource))
 	  pkgsource.set_cached (prefix + pkgsource.Canonical ());
 	else
-	  throw new Exception ("__LINE__ __FILE__", (String ("Package validation failure for ") + prefix + pkgsource.Canonical ()).cstr_oneuse(), APPERR_CORRUPT_PACKAGE);
+	  throw new Exception ("__LINE__ __FILE__", String ("Package validation failure for ") + prefix + pkgsource.Canonical (), APPERR_CORRUPT_PACKAGE);
 	return 1;
       }
 
@@ -143,7 +143,7 @@ check_for_cached (packagesource & pkgsou
 	  if (validateCachedPackage (fullname, pkgsource))
 	    pkgsource.set_cached (fullname );
 	  else
-	    throw new Exception ("__LINE__ __FILE__", (String ("Package validation failure for ") + fullname).cstr_oneuse(), APPERR_CORRUPT_PACKAGE);
+	    throw new Exception ("__LINE__ __FILE__", String ("Package validation failure for ") + fullname, APPERR_CORRUPT_PACKAGE);
 	  return 1;
 	}
     }
Index: install.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/install.cc,v
retrieving revision 2.54
diff -u -p -r2.54 install.cc
--- install.cc	31 Jan 2003 22:37:14 -0000	2.54
+++ install.cc	16 Feb 2003 13:13:08 -0000
@@ -210,7 +210,7 @@ install_one_source (packagemeta & pkgm, 
 	  md5_append (&pns, buffer, count);
       delete thefile;
       if (count < 0)
-	throw new Exception ("__LINE__ __FILE__", (String ("IO Error reading ") + source.Cached()).cstr_oneuse(), APPERR_IO_ERROR);
+	throw new Exception ("__LINE__ __FILE__", String ("IO Error reading ") + source.Cached(), APPERR_IO_ERROR);
       
       md5_byte_t tempdigest[16];
       md5_finish(&pns, tempdigest);
@@ -220,7 +220,7 @@ install_one_source (packagemeta & pkgm, 
       log (LOG_BABBLE, String ("For file ") + source.Cached() + " ini digest is " + source.md5.print() + " file digest is " + tempMD5.print());
       
       if (source.md5 != tempMD5)
-	  throw new Exception ("__LINE__ __FILE__", (String ("Checksum failure for ") + source.Cached()).cstr_oneuse(), APPERR_CORRUPT_PACKAGE);
+	  throw new Exception ("__LINE__ __FILE__", String ("Checksum failure for ") + source.Cached(), APPERR_CORRUPT_PACKAGE);
     }
   io_stream *tmp = io_stream::open (source.Cached (), "rb");
   archive *thefile = 0;


More information about the Cygwin-apps mailing list