From cfefaf581a64974b501b1a364fba57ebd74a311e Mon Sep 17 00:00:00 2001 From: Robert MacGregor Date: Sat, 12 Mar 2016 15:41:56 -0500 Subject: [PATCH] Fix for Ecc failing on empty files --- Sources/Ecc/Main.cpp | 128 ++++++++++++++++++++++++++++++++++++++++--- Sources/Ecc/StdH.h | 4 +- 2 files changed, 121 insertions(+), 11 deletions(-) diff --git a/Sources/Ecc/Main.cpp b/Sources/Ecc/Main.cpp index 3cc2987..7c8f12a 100644 --- a/Sources/Ecc/Main.cpp +++ b/Sources/Ecc/Main.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2012 Croteam Ltd. +/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation @@ -63,7 +63,7 @@ char *LineDirective(int i) return strdup(str); } -SType SType::operator+(const SType &other) +SType SType::operator+(const SType &other) { SType sum; sum.strString = stradd(strString, other.strString); @@ -116,7 +116,7 @@ FILE *FOpen(const char *strFileName, char *strMode) /* * Print a header to an output file. */ -static void PrintHeader(FILE *f) +static void PrintHeader(FILE *f) { fprintf(f, "/*\n"); fprintf(f, " * This file is generated by Entity Class Compiler, (c) CroTeam 1997-98\n"); @@ -174,13 +174,13 @@ void ReplaceFileRL(const char *strOld, const char *strNew) { continue; } - + // process each charachter for(int ich=0;ich0) && (*(pchNew-1)=='\\')) { } else bQuotes = !bQuotes; } @@ -227,8 +227,106 @@ void ReplaceFile(const char *strOld, const char *strNew) remove(strOld); rename(strNew, strOld); } + +enum ESStatus +{ + /* Appears to be non-empty, ready to parse. */ + Good, + /* Appears to be empty, ignore it. */ + Empty, + /* Error occured during status check. */ + Error, +}; + +/* Determine whether or not our target ES file is indeed valid input. */ +ESStatus GetESStatus(char *filename) +{ + ESStatus result = ESStatus::Good; + + // Read a temporary buffer of the entire file contents + fseek(_fInput, 0, SEEK_END); + size_t length = ftell(_fInput); + char* temporaryBuffer = (char*)malloc(length); + fseek(_fInput, 0, SEEK_SET); + fread(temporaryBuffer, length, 1, _fInput); + fclose(_fInput); + + // First, let's remove line comments + char *commentBegin = NULL; + while (commentBegin = strstr(temporaryBuffer, "//")) + { + size_t commentLength = length; + + char* lineEnding = strstr(commentBegin, "\n"); + if (lineEnding) + commentLength = (size_t)(lineEnding) - (size_t)commentBegin; + + memset(commentBegin, 0x20, commentLength); + } + + // Then block comments + commentBegin = NULL; + while (commentBegin = strstr(temporaryBuffer, "/*")) + { + size_t commentLength = length; + + char* commentEnd = strstr(commentBegin, "*/"); + if (commentEnd) + commentLength = (size_t)(commentEnd + 3) - (size_t)commentBegin; + else + { + result = ESStatus::Error; + break; + } + + memset(commentBegin, 0x20, commentLength); + } + + // If we return here, it was because of unbalanced block comments + if (result != ESStatus::Good) + { + free(temporaryBuffer); + return result; + } + + // Now we just loop through the buffer until we find something that's not 0x20 or \n + result = ESStatus::Empty; + for (size_t iteration = 0; iteration < length; iteration++) + if (temporaryBuffer[iteration] != 0x20 && temporaryBuffer[iteration] != '\n') + { + size_t checkLength = length; + char* checkStart = &temporaryBuffer[iteration]; + + char* lineEnding = strstr(checkStart, "\n"); + if (lineEnding) + checkLength = (size_t)(lineEnding) - (size_t)checkStart; + + // Loop through and use isdigit to check all the digits + checkStart[checkLength + 1] = 0x00; + + for (int digit = 0; digit < strlen(checkStart); digit++) + if (checkStart[digit] != 0x20 && checkStart[digit] != '\n' && isdigit(checkStart[digit])) + result = ESStatus::Good; + else if (checkStart[digit] != 0x20 && checkStart[digit] != '\n') + { + // If this occurs, then the first non-whitespace line we read wasn't a number. + result = ESStatus::Error; + break; + } + + break; + } + + + free(temporaryBuffer); + if (result == ESStatus::Good) + _fInput = FOpen(filename, "r"); + + return result; +} + /* Replace a file with a new file if they are different. - * Used to keep .h files from constantly changing when you change the implementation. + * Used to keep .h files from constantly changing when you change the implementation. */ void ReplaceIfChanged(const char *strOld, const char *strNew) { @@ -240,7 +338,7 @@ void ReplaceIfChanged(const char *strOld, const char *strNew) while (!feof(fOld)) { char strOldLine[4096] = "#l"; char strNewLine[4096] = "#l"; - + // skip #line directives while(strNewLine[0]=='#' && strNewLine[1]=='l' && !feof(fNew)) { fgets(strNewLine, sizeof(strNewLine)-1, fNew); @@ -283,6 +381,18 @@ int main(int argc, char *argv[]) } // open the input file _fInput = FOpen(argv[1], "r"); + + // Make sure we're loading a valid ES file + ESStatus status = GetESStatus(argv[1]); + + switch (status) + { + case ESStatus::Empty: + return EXIT_SUCCESS; + case ESStatus::Error: + return EXIT_FAILURE; + } + //printf("%s\n", argv[1]); // open all the output files char *strImplementation = ChangeFileNameExtension(argv[1], ".cpp_tmp"); @@ -333,7 +443,7 @@ int main(int argc, char *argv[]) ReplaceFile(strImplementationOld, strImplementation); ReplaceIfChanged(strDeclarationOld, strDeclaration); ReplaceIfChanged(strTablesOld, strTables); - + return EXIT_SUCCESS; // if there were errors } else { diff --git a/Sources/Ecc/StdH.h b/Sources/Ecc/StdH.h index 6def450..3482ed6 100644 --- a/Sources/Ecc/StdH.h +++ b/Sources/Ecc/StdH.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2012 Croteam Ltd. +/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation @@ -13,6 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include #include @@ -27,4 +28,3 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #define _fullpath(x, y, z) realpath(y, x) #endif -