From 31f931f20df22f7255200fa1e49590c38edda579 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Tue, 25 Jan 2022 17:01:44 -0700 Subject: [PATCH] check GIF list files to be the same size so not crashing --- cinelerra-5.1/cinelerra/file.C | 11 ++++++ cinelerra-5.1/cinelerra/file.inc | 1 + cinelerra-5.1/cinelerra/filebase.h | 4 ++ cinelerra-5.1/cinelerra/filegif.C | 60 ++++++++++++++++++++++++++++++ cinelerra-5.1/cinelerra/filegif.h | 2 + cinelerra-5.1/cinelerra/mwindow.C | 7 ++++ 6 files changed, 85 insertions(+) diff --git a/cinelerra-5.1/cinelerra/file.C b/cinelerra-5.1/cinelerra/file.C index dbcd6889..03941d9a 100644 --- a/cinelerra-5.1/cinelerra/file.C +++ b/cinelerra-5.1/cinelerra/file.C @@ -658,6 +658,17 @@ int File::open_file(Preferences *preferences, } +// If file type is a list verify that all files match in dimensions. +// Should be done only after the file open function has been performed +// Reason: although this function checks if file exists or not but +// it has no way of relaying this information back and if this function +// is called before open_file the program may accidently interpret file +// not found as file size don't match + if( !file->verify_file_list() ) { + delete file; file = 0; + return FILE_SIZE_DONT_MATCH; + } + // Set extra writing parameters to mandatory settings. if( wr ) { diff --git a/cinelerra-5.1/cinelerra/file.inc b/cinelerra-5.1/cinelerra/file.inc index 11a5bc9a..c6228a28 100644 --- a/cinelerra-5.1/cinelerra/file.inc +++ b/cinelerra-5.1/cinelerra/file.inc @@ -53,6 +53,7 @@ #define FILE_NOT_FOUND 1 #define FILE_UNRECOGNIZED_CODEC 2 #define FILE_IS_XML 3 +#define FILE_SIZE_DONT_MATCH 4 // Numeric codes for each file format // They're stored in XML files, so they have to be fixed. diff --git a/cinelerra-5.1/cinelerra/filebase.h b/cinelerra-5.1/cinelerra/filebase.h index 3fb8be42..fb10df07 100644 --- a/cinelerra-5.1/cinelerra/filebase.h +++ b/cinelerra-5.1/cinelerra/filebase.h @@ -132,6 +132,10 @@ public: int channel, int64_t len); void allocate_history(int len); +// thie function will be used to verify if all files in a given +// list are of same size or not. Each list type object should +// override this method with its own definition. + virtual int verify_file_list() { return 1; } // For static functions to access it Asset *asset; diff --git a/cinelerra-5.1/cinelerra/filegif.C b/cinelerra-5.1/cinelerra/filegif.C index bb26762b..b80f7412 100644 --- a/cinelerra-5.1/cinelerra/filegif.C +++ b/cinelerra-5.1/cinelerra/filegif.C @@ -31,6 +31,7 @@ #include #include #include +#include //from "getarg.h" extern "C" @@ -500,6 +501,65 @@ FrameWriterUnit* FileGIFList::new_writer_unit(FrameWriter *writer) return new GIFUnit(this, writer); } +int FileGIFList::verify_file_list() +{ + // go through all .gif files in the list and + // verify their sizes match or not. + //printf("\nAsset Path: %s\n", asset->path); + FILE *stream = fopen(asset->path, "rb"); + if (stream) { + char string[BCTEXTLEN]; + int width, height, prev_width=-1, prev_height=-1; + // build the path prefix + char prefix[BCTEXTLEN], *bp = prefix, *cp = strrchr(asset->path, '/'); + for( int i=0, n=!cp ? 0 : cp-asset->path; ipath[i]; + *bp = 0; + // read entire input file + while( !feof(stream) && fgets(string, BCTEXTLEN, stream) ) { + int len = strlen(string); + if(!len || string[0] == '#' || string[0] == ' ' || isalnum(string[0])) continue; + if( string[len-1] == '\n' ) string[len-1] = 0; + // a possible .gif file path? fetch it + char path[BCTEXTLEN], *pp = path, *ep = pp + sizeof(path)-1; + if( string[0] == '.' && string[1] == '/' && prefix[0] ) + pp += snprintf(pp, ep-pp, "%s/", prefix); + snprintf(pp, ep-pp, "%s", string); + // check if a valid file exists + if(!access(path, R_OK)) { + // check file header for size + FILE *gif_file_temp = fopen(path, "rb"); + if (gif_file_temp) { + unsigned char test[16]; + int ret = fread(test, 16, 1, gif_file_temp); + fclose(gif_file_temp); + if( ret < 1 ) continue; + // get height and width of gif file + width = test[6] | (test[7] << 8); + height = test[8] | (test[9] << 8); + // test with previous + if ( (prev_width == -1) && (prev_height == -1) ) { + prev_width = width; + prev_height = height; + continue; + } + else if ( (prev_width != width) || (prev_height != height) ) { + // this is the error case we are trying to avoid + fclose(stream); + return 0; + } + } + + } + } + fclose(stream); + return 1; + } + // not sure if our function should be the one to raise not found error + perror(asset->path); + return 0; +} + + GIFUnit::GIFUnit(FileGIFList *file, FrameWriter *writer) : FrameWriterUnit(writer) { diff --git a/cinelerra-5.1/cinelerra/filegif.h b/cinelerra-5.1/cinelerra/filegif.h index 74cae2a0..98370de9 100644 --- a/cinelerra-5.1/cinelerra/filegif.h +++ b/cinelerra-5.1/cinelerra/filegif.h @@ -80,6 +80,8 @@ public: int use_path() { return 1; } int read_frame(VFrame *output, char *path); int write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit); +// Need to override this method from FILEBASE class + int verify_file_list(); FrameWriterUnit* new_writer_unit(FrameWriter *writer); }; diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index e4d02d23..a502c156 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -2220,6 +2220,13 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); } result = 0; break; } +// File is a list and size of listed files don't match + case FILE_SIZE_DONT_MATCH: { + eprintf(_("File sizes don't match")); + sprintf(string, _("File sizes don't match")); + gui->show_message(string, theme->message_error); + gui->update_default_message(); + break; } case FILE_NOT_FOUND: { eprintf(_("Failed to open %s"), new_asset->path); -- 2.26.2