Commits

Andreas Tscharner committed c6b409b

disable encryption: Correct compiler handling if disabled encryption

Created new exception that gets thrown if an encryption (other than None) is
required, but encryption support is disabled.
The exception gets caught in ResourceData which saves the error message and
the Collector class checks for this message and shows it if available.

  • Participants
  • Parent commits 63a0ec6

Comments (0)

Files changed (7)

src/Factories.cxx

 //      Factories.cxx
 //
-//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
 
 
 // Includefiles
+#ifdef HAVE_CONFIG_H
+#include "lrc_config.h"
+#endif
+
 #include "Factories.hxx"
 #include "include/CompressDecompress.hxx"
 #include "include/EncryptDecrypt.hxx"
 #include "strategies/NoneCompression.hxx"
 #include "strategies/zLibCompression.hxx"
 #include "strategies/NoneEncryption.hxx"
+
+#ifndef NO_ENCRYPTION
 #include "strategies/SerpentEncryption.hxx"
+#endif
 
 
 lrc::CompressDecompress *CompressionFactory::get_compression_class(lrc::CompressionType p_compType)
 }
 
 
-lrc::EncryptDecrypt *EncryptionFactory::get_encryption_class(lrc::EncryptionType p_encType)
+lrc::EncryptDecrypt *EncryptionFactory::get_encryption_class(lrc::EncryptionType p_encType,
+                                                             char *p_resID) throw(lrcEncryptionDisabledException)
 {
+#ifdef NO_ENCRYPTION
+	if (p_encType == lrc::NoneEncryption) {
+		return new NoneEncryption();
+	};
+
+	throw lrcEncryptionDisabledException(p_resID);
+#else
 	switch (p_encType) {
 		case lrc::NoneEncryption:
 			return new NoneEncryption();
 	};
 
 	return nullptr;
+#endif /* NO_ENCRYPTION */
 }

src/Factories.hxx

 //      Factories.hxx
 //
-//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
  * the encryption factory class
  *
  * \author Andreas Tscharner
- * \date 2011-06-23
+ * \date 2012-01-07
  */
 
 
 // Include files
 #include "include/CompressDecompress.hxx"
 #include "include/EncryptDecrypt.hxx"
+#include "lrcExceptions.hxx"
 
 
 /*! \class CompressionFactory
 		 * encryption/decryption class (if possible of \c nullptr otherwise
 		 *
 		 * \param[in] p_encType Encryption type
+		 * \param[in] p_resID ID of resource that requests encryptiion
 		 *
 		 * \return Instance of desired encryption class
 		 */
-		static lrc::EncryptDecrypt * get_encryption_class(lrc::EncryptionType);
+		static lrc::EncryptDecrypt *get_encryption_class(lrc::EncryptionType, char *) throw(lrcEncryptionDisabledException);
 };
 
 

src/ResourceData.cxx

 //      ResourceData.cxx
 //
-//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
 
 
 #include <tuple>
-#include <string.h>
-#include <stdio.h>
+#include <cstring>
+#include <cstdio>
 #include "Utils.hxx"
 #include "StatusCodes.hxx"
 #include "Factories.hxx"
 #include "ResourceData.hxx"
 
-#ifdef __DEBUG__
-#include <stdio.h>
-#endif
 
+void ResourceData::set_error_msg(char *p_newErrMsg)
+{
+	size_t newLen;
+
+
+	if (m_errorMsg) {
+		delete[] m_errorMsg;
+	};
+
+	newLen = strlen(p_newErrMsg) + 1;
+	m_errorMsg = new char[newLen];
+	memset(m_errorMsg, 0, newLen);
+	strncpy(m_errorMsg, p_newErrMsg, (newLen-1));
+}
 
 ResourceData::ResourceData(void)
 {
 	m_encryption = lrc::NoneEncryption;
 	m_compression = lrc::NoneCompression;
 	m_inFilePosition = std::make_tuple(-1, -1);
+	m_errorMsg = nullptr;
 }
 
 ResourceData::~ResourceData(void)
 		delete[] m_password;
 	if (m_filename)
 		delete[] m_filename;
+	if (m_errorMsg)
+		delete[] m_errorMsg;
 }
 
 void ResourceData::set_ident(const char *p_resIdent)
 		return ERROR_COMPRESSION_NOT_AVAILABLE;
 	};
 
-	encryptor = EncryptionFactory::get_encryption_class(m_encryption);
+	try {
+		encryptor = EncryptionFactory::get_encryption_class(m_encryption, m_resID);
+	} catch (lrcEncryptionDisabledException const &encDisabledEx) {
+		this->set_error_msg((char *)encDisabledEx.what());
+
+		delete compressor;
+		std::get<1>(m_inFilePosition) = 4;
+		return ERROR_ENCRYPTION_NOT_AVAILABLE;
+	};
 	if (!encryptor) {
 		delete compressor;
 
 		return ERROR_COMPRESSION_NOT_AVAILABLE;
 	};
 
-	decryptor = EncryptionFactory::get_encryption_class(p_resEntry.encType);
+	try {
+		decryptor = EncryptionFactory::get_encryption_class(p_resEntry.encType, p_resEntry.resID);
+	} catch (lrcEncryptionDisabledException const &encDisabledEx) {
+		this->set_error_msg((char *)encDisabledEx.what());
+
+		delete decompressor;
+		return ERROR_ENCRYPTION_NOT_AVAILABLE;
+	};
 	if (!decryptor) {
 		delete decompressor;
 
 
 	return NO_ERROR;
 }
+
+char *ResourceData::get_error_msg(void)
+{
+	size_t errMsgLen;
+	char *retErrMsg;
+
+
+	if (!m_errorMsg) {
+		return nullptr;
+	};
+
+	errMsgLen = strlen(m_errorMsg);
+	retErrMsg = new char[errMsgLen+1];
+	memset(retErrMsg, 0, (errMsgLen+1));
+	strncpy(retErrMsg, m_errorMsg, errMsgLen);
+
+	delete[] m_errorMsg;
+	m_errorMsg = nullptr;
+
+	return retErrMsg;
+}

src/ResourceData.hxx

 //      ResourceData.hxx
 //
-//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
  * information
  *
  * \author Andreas Tscharner
- * \date 2011-09-26
+ * \date 2012-01-07
  */
 
 
 		lrc::CompressionType m_compression; //!< Type of compression for this resource
 		inFilePosition m_inFilePosition;    //!< Position of resource in RC file
 
+		char *m_errorMsg;                   //!< Error message (if any)
+		/*! \brief Set new error message
+		 *
+		 * This method clears an old error message (if any) and sets the new
+		 * given one
+		 *
+		 * \param[in] p_newErrMsg New error message
+		 */
+		void set_error_msg(char *);
+
 	public:
 		/*! \brief Constructor
 		 *
 		 * \remarks The caller is responsible to free the returned class
 		 */
 		int get_data_from_memory(unsigned char *, resEntry, const unsigned char *p_password = nullptr);
+
+		/*! \brief Return error message
+		 *
+		 * This method returns the internal error message (if there is any)
+		 * and clears it
+		 *
+		 * \return Internal error message
+		 *
+		 * \remarks The caller is responsible to free the used memory for
+		 *          the message
+		 */
+		char *get_error_msg(void);
 };
 
 

src/compiler/Collector.cxx

 //      Collector.cxx
 //
-//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
 
 #include <vector>
 #include <iostream>
-#include <string.h>
-#include <stdio.h>
+#include <cstring>
+#include <cstdio>
 #include "../Utils.hxx"
 #include "../lrcExceptions.hxx"
 #include "../ResourceData.hxx"
 	const int MAX_ERR_TEXT_LEN = 255;
 	char errorText[MAX_ERR_TEXT_LEN];
 	char baseErrTxt[MAX_ERR_TEXT_LEN];
+	char *resError;
 	inFilePosition rcFPos;
 
 
 			         baseErrTxt, p_resData->get_compression());
 			break;
 		case ERROR_ENCRYPTION_NOT_AVAILABLE:
-			snprintf(errorText, MAX_ERR_TEXT_LEN, "%s Encryption type %d not available.\n",
-			         baseErrTxt, p_resData->get_encryption());
+			resError = p_resData->get_error_msg();
+			if (resError) {
+				snprintf(errorText, MAX_ERR_TEXT_LEN, "%s %s\n", baseErrTxt, resError);
+				delete[] resError;
+			} else {
+				snprintf(errorText, MAX_ERR_TEXT_LEN, "%s Encryption type %d not available.\n",
+			             baseErrTxt, p_resData->get_encryption());
+			};
 			break;
 		case ERROR_FILE_OPEN:
 			snprintf(errorText, MAX_ERR_TEXT_LEN, "%s Could not open file \"%s\".\n",

src/lrcExceptions.cxx

 //      lrcExceptions.cxx
 //
-//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
 
 
 #include <string>
-#include <string.h>
+#include <cstring>
 #include "lrcExceptions.hxx"
 
 
 	strncpy(m_fileNotFound, p_fileNotFoundName, (len-1));
 }
 
-lrcFileNotFoundException::~lrcFileNotFoundException() throw()
+lrcFileNotFoundException::~lrcFileNotFoundException(void) throw()
 {
 	delete[] m_fileNotFound;
 }
 	strncpy(m_fileOverwrite, p_filename, (len-1));
 }
 
-lrcFileExistsException::~lrcFileExistsException() throw()
+lrcFileExistsException::~lrcFileExistsException(void) throw()
 {
 	delete[] m_fileOverwrite;
 }
 	retStr += "\" should be overwritten, but overwriting is not allowed.";
 	return retStr.c_str();
 }
+
+
+lrcEncryptionDisabledException::lrcEncryptionDisabledException(char *p_resourceID)
+{
+	size_t reqStrLen;
+
+
+	reqStrLen = strlen(p_resourceID) + 1;
+	m_resourceID = new char[reqStrLen];
+	memset(m_resourceID, 0, reqStrLen);
+	strncpy(m_resourceID, p_resourceID, (reqStrLen-1));
+}
+
+lrcEncryptionDisabledException::~lrcEncryptionDisabledException(void) throw()
+{
+	delete[] m_resourceID;
+}
+
+const char *lrcEncryptionDisabledException::what(void) const throw()
+{
+	std::string retStr;
+
+
+	retStr = "The resource \"";
+	retStr += m_resourceID;
+	retStr += "\" requires encryption, but the compiler was built without it.";
+	return retStr.c_str();
+}

src/lrcExceptions.hxx

 //      lrcExceptions.hxx
 //
-//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
+//      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
 //
 //      This program is free software; you can redistribute it and/or modify
 //      it under the terms of the GNU Lesser General Public License as
  * This file contains all exception classes for lrc project
  *
  * \author Andreas Tscharner
- * \date 2011-06-19
+ * \date 2012-01-07
  */
 
 #ifndef __LRC_EXCEPTIONS_HXX__
 		lrcFileNotFoundException(char *);
 		/*! \brief Destructor
 		 */
-		~lrcFileNotFoundException() throw();
+		~lrcFileNotFoundException(void) throw();
 
 		/*! \brief Method to return reason
 		 *
 		 *
 		 * Frees up memory needed by the class
 		 */
-		~lrcFileExistsException() throw();
+		~lrcFileExistsException(void) throw();
 
 		/*! \brief Gives a reason for the exception
 		 *
 		virtual const char *what(void) const throw();
 };
 
+/*! \class lrcEncryptionDisabledException
+ *  \brief Exception if encryption is disabled but required
+ *
+ * This exception is thrown if the compiler is compiled without encryption
+ * support, but the defined input file (.rc or .rif) defines to encrypt a
+ * resource
+ */
+class lrcEncryptionDisabledException : public std::exception
+{
+	private:
+		char *m_resourceID;            //!< Resource that requires encryption
+
+	public:
+		/*! \brief Constructor
+		 *
+		 * The constructor expects the name of the resource that requires
+		 * encryption
+		 *
+		 * \param[in] p_resourceID Resource ID
+		 */
+		lrcEncryptionDisabledException(char *);
+		/*! \brief Destructor
+		 *
+		 * Frees the memory of the exception
+		 */
+		~lrcEncryptionDisabledException(void) throw();
+
+		/*! \brief Gives a reason for the exception
+		 *
+		 * Returns a message explaining that the user disabled encryption at
+		 * compile time and therefore encryption of the resource is not
+		 * possible
+		 *
+		 * \return Reason for exception
+		 */
+		virtual const char *what(void) const throw();
+};
+
 
 #endif /* __LRC_EXCEPTIONS_HXX__ */