From 32e7dda3cfc28a4e3667645304cc29f3170e4924 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Thu, 4 May 2023 17:06:17 +0700 Subject: [PATCH] use memio in d_deh.c (#1031) * use memio in d_deh.c Fixes ASan report. --- src/d_deh.c | 105 ++++++++++++++++++++++++++++++++-------------------- src/memio.c | 59 +++++++++++++++++++++++++++++ src/memio.h | 3 ++ 3 files changed, 127 insertions(+), 40 deletions(-) diff --git a/src/d_deh.c b/src/d_deh.c index 6941f8a8..509b2431 100644 --- a/src/d_deh.c +++ b/src/d_deh.c @@ -34,6 +34,7 @@ #include "d_think.h" #include "d_main.h" // D_DehChangePredefinedTranslucency() #include "w_wad.h" +#include "memio.h" #include "dsdhacked.h" @@ -43,61 +44,82 @@ static boolean bfgcells_modified = false; // (e.g. from wads) typedef struct { - byte *inp, *lump; // Pointer to string or FILE - long size; + MEMFILE *lump; + FILE *file; } DEHFILE; // killough 10/98: emulate IO whether input really comes from a file or not // haleyjd: got rid of macros for MSCV -char *dehfgets(char *buf, size_t n, DEHFILE *fp) +static char *dehfgets(char *str, size_t count, DEHFILE *fp) { - if (!fp->lump) // If this is a real file, - return fgets(buf, n, (FILE *) fp->inp); // return regular fgets - if (!n || !*fp->inp || fp->size<=0) // If no more characters - return NULL; - if (n==1) - fp->size--, *buf = *fp->inp++; - else - { // copy buffer - char *p = buf; - while (n>1 && *fp->inp && fp->size && - (n--, fp->size--, *p++ = *fp->inp++) != '\n') - ; - *p = 0; - } - return buf; // Return buffer pointer + if (fp->file) + { + return fgets(str, count, fp->file); + } + else if (fp->lump) + { + return mem_fgets(str, count, fp->lump); + } + + return NULL; } -int dehfeof(DEHFILE *fp) +static int dehfeof(DEHFILE *fp) { - return !fp->lump ? feof((FILE *) fp->inp) : !*fp->inp || fp->size<=0; + if (fp->file) + { + return feof(fp->file); + } + else if (fp->lump) + { + return mem_feof(fp->lump); + } + + return 0; } -int dehfgetc(DEHFILE *fp) +static int dehfgetc(DEHFILE *fp) { - return !fp->lump ? fgetc((FILE *) fp->inp) : fp->size > 0 ? - fp->size--, *fp->inp++ : EOF; + if (fp->file) + { + return fgetc(fp->file); + } + else if (fp->lump) + { + return mem_fgetc(fp->lump); + } + + return -1; } static long dehftell(DEHFILE *fp) { - return !fp->lump ? ftell((FILE *) fp->inp) : (fp->inp - fp->lump); + if (fp->file) + { + return ftell(fp->file); + } + else if (fp->lump) + { + return mem_ftell(fp->lump); + } + + return 0; } static int dehfseek(DEHFILE *fp, long offset) { - if (!fp->lump) - return fseek((FILE *) fp->inp, offset, SEEK_SET); - else + if (fp->file) { - long total = (fp->inp - fp->lump) + fp->size; - offset = BETWEEN(0, total, offset); - fp->inp = fp->lump + offset; - fp->size = total - offset; - return 0; + return fseek(fp->file, offset, SEEK_SET); } + else if (fp->lump) + { + return mem_fseek(fp->lump, offset, MEM_SEEK_SET); + } + + return 0; } @@ -1564,7 +1586,7 @@ void ProcessDehFile(const char *filename, char *outfilename, int lumpnum) { static int i = 0; - if (!(infile.inp = (void *) M_fopen(filename,"rt"))) + if (!(infile.file = M_fopen(filename,"rt"))) { printf("-deh file %s not found\n",filename); return; // should be checked up front anyway @@ -1578,15 +1600,18 @@ void ProcessDehFile(const char *filename, char *outfilename, int lumpnum) } else // DEH file comes from lump indicated by third argument { - infile.size = W_LumpLength(lumpnum); - infile.inp = infile.lump = W_CacheLumpNum(lumpnum, PU_STATIC); - filename = W_WadNameForLump(lumpnum); + void *buf = W_CacheLumpNum(lumpnum, PU_STATIC); // [FG] skip empty DEHACKED lumps - if (!infile.inp) + if (!buf) { printf("skipping empty DEHACKED lump from file %s\n", filename); return; } + + infile.lump = mem_fopen_read(buf, W_LumpLength(lumpnum)); + filename = W_WadNameForLump(lumpnum); + + infile.file = NULL; } printf("Loading DEH %sfile %s\n", infile.lump ? "lump from " : "", filename); @@ -1675,9 +1700,9 @@ void ProcessDehFile(const char *filename, char *outfilename, int lumpnum) } if (infile.lump) - Z_ChangeTag(infile.lump, PU_CACHE); // Mark purgable - else if(infile.inp) - fclose((FILE *) infile.inp); // Close real file + mem_fclose(infile.lump); + else if(infile.file) + fclose(infile.file); // Close real file if (outfilename) // killough 10/98: only at top recursion level { diff --git a/src/memio.c b/src/memio.c index 14e76d62..f43a4db4 100644 --- a/src/memio.c +++ b/src/memio.c @@ -150,6 +150,57 @@ int mem_fputs(const char *str, MEMFILE *stream) return mem_fwrite(str, sizeof(char), strlen(str), stream); } +char *mem_fgets(char *str, int count, MEMFILE *stream) +{ + int i; + + if (str == NULL) + return NULL; + + for (i = 0; i < count - 1; ++i) + { + byte ch; + if (mem_fread(&ch, 1, 1, stream) == 1) + { + str[i] = ch; + + if (ch == '\0') + { + return str; + } + + if (ch == '\n') + { + ++i; + break; + } + } + else + { + break; + } + } + + if (mem_feof(stream)) + return NULL; + + str[i] = '\0'; + + return str; +} + +int mem_fgetc(MEMFILE *stream) +{ + byte ch; + + if (mem_fread(&ch, 1, 1, stream) == 1) + { + return (int)ch; + } + + return -1; // EOF +} + void mem_get_buf(MEMFILE *stream, void **buf, size_t *buflen) { *buf = stream->buf; @@ -207,4 +258,12 @@ int mem_fseek(MEMFILE *stream, signed long position, mem_rel_t whence) } } +int mem_feof(MEMFILE *stream) +{ + if (stream->position >= stream->buflen) + { + return 1; + } + return 0; +} diff --git a/src/memio.h b/src/memio.h index 432b374a..37ffdb37 100644 --- a/src/memio.h +++ b/src/memio.h @@ -30,10 +30,13 @@ size_t mem_fread(void *buf, size_t size, size_t nmemb, MEMFILE *stream); MEMFILE *mem_fopen_write(void); size_t mem_fwrite(const void *ptr, size_t size, size_t nmemb, MEMFILE *stream); int mem_fputs(const char *str, MEMFILE *stream); +char *mem_fgets(char *str, int count, MEMFILE *stream); +int mem_fgetc(MEMFILE *stream); void mem_get_buf(MEMFILE *stream, void **buf, size_t *buflen); void mem_fclose(MEMFILE *stream); long mem_ftell(MEMFILE *stream); int mem_fseek(MEMFILE *stream, signed long offset, mem_rel_t whence); +int mem_feof(MEMFILE *stream); #endif /* #ifndef MEMIO_H */