From 3cb8e5204309d5efbd0421c4a227b90043018709 Mon Sep 17 00:00:00 2001 From: Kevin Fischer Date: Sat, 21 Jul 2018 18:37:18 -0500 Subject: [PATCH] Fix error in "last all" command and several -Wunused-result compiler errors (#55) * Add build generated files to .gitignore * Fix error in "last all" output and resolve Wunused-result warnings - Check return value of several standard library calls that could return error states. - Fix issue with "last all" command (it sent tabs for alignment that were reinterpreted as colors). * Fix buffer overflow in do_export_zone command --- .gitignore | 9 ++++ src/act.wizard.c | 50 ++++++++++++++-------- src/boards.c | 34 +++++++++++++-- src/comm.c | 11 ++++- src/db.c | 107 ++++++++++++++++++++++++++++++++++------------- src/genolc.c | 6 +-- src/limits.c | 4 +- src/msgedit.c | 36 ++++++++++++---- src/shop.c | 9 +++- 9 files changed, 204 insertions(+), 62 deletions(-) diff --git a/.gitignore b/.gitignore index d9fc1c6..35c0bed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ bin/* src/*.o src/util/*.o +config.cache +config.log +config.status +src/Makefile +src/conf.h +src/util/Makefile +src/.accepted +src/depend +src/util/depend diff --git a/src/act.wizard.c b/src/act.wizard.c index 55daf66..5ae0cad 100644 --- a/src/act.wizard.c +++ b/src/act.wizard.c @@ -1893,7 +1893,10 @@ static void mod_llog_entry(struct last_entry *llast,int type) { * do (like searching for the last shutdown/etc..) */ for(tmp=recs; tmp > 0; tmp--) { fseek(fp,-1*((long)sizeof(struct last_entry)),SEEK_CUR); - fread(&mlast,sizeof(struct last_entry),1,fp); + if(fread(&mlast,sizeof(struct last_entry),1,fp) != 1) { + log("mod_llog_entry: read error or unexpected end of file."); + return; + } /* Another one to keep that stepback. */ fseek(fp,-1*((long)sizeof(struct last_entry)),SEEK_CUR); @@ -1988,7 +1991,10 @@ void clean_llog_entries(void) { /* copy the rest */ while (!feof(ofp)) { - fread(&mlast,sizeof(struct last_entry),1,ofp); + if(fread(&mlast,sizeof(struct last_entry),1,ofp) != 1 ) { + log("clean_llog_entries: read error or unexpected end of file."); + return; + } fwrite(&mlast,sizeof(struct last_entry),1,nfp); } fclose(ofp); @@ -2006,18 +2012,21 @@ static void list_llog_entries(struct char_data *ch) char timestr[25]; if(!(fp=fopen(LAST_FILE,"r"))) { - log("bad things."); + log("llist_log_entries: could not open last log file %s.", LAST_FILE); send_to_char(ch, "Error! - no last log"); } send_to_char(ch, "Last log\r\n"); - fread(&llast, sizeof(struct last_entry), 1, fp); - strftime(timestr, sizeof(timestr), "%a %b %d %Y %H:%M:%S", localtime(&llast.time)); - - while(!feof(fp)) { - send_to_char(ch, "%10s\t%d\t%s\t%s\r\n", llast.username, llast.punique, + while(fread(&llast, sizeof(struct last_entry), 1, fp) == 1) { + strftime(timestr, sizeof(timestr), "%a %b %d %Y %H:%M:%S", localtime(&llast.time)); + send_to_char(ch, "%10s %d %s %s\r\n", llast.username, llast.punique, last_array[llast.close_type], timestr); - fread(&llast, sizeof(struct last_entry), 1, fp); + break; + } + + if(ferror(fp)) { + log("llist_log_entries: error reading %s.", LAST_FILE); + send_to_char(ch, "Error reading last_log file."); } } @@ -2100,11 +2109,14 @@ ACMD(do_last) send_to_char(ch, "Last log\r\n"); while(num > 0 && recs > 0) { fseek(fp,-1* ((long)sizeof(struct last_entry)),SEEK_CUR); - fread(&mlast,sizeof(struct last_entry),1,fp); + if(fread(&mlast,sizeof(struct last_entry),1,fp) != 1) { + send_to_char(ch, "Error reading log file."); + return; + } fseek(fp,-1*((long)sizeof(struct last_entry)),SEEK_CUR); if(!*name ||(*name && !str_cmp(name, mlast.username))) { strftime(timestr, sizeof(timestr), "%a %b %d %Y %H:%M", localtime(&mlast.time)); - send_to_char(ch,"%10.10s %20.20s %20.21s - ", + send_to_char(ch, "%10.10s %20.20s %20.21s - ", mlast.username, mlast.hostname, timestr); if((temp=is_in_game(mlast.idnum)) && mlast.punique == GET_PREF(temp)) { send_to_char(ch, "Still Playing "); @@ -4200,16 +4212,20 @@ ACMD(do_copyover) sprintf (buf2, "-C%d", mother_desc); /* Ugh, seems it is expected we are 1 step above lib - this may be dangerous! */ - chdir (".."); + if(chdir ("..") != 0) { + log("Error changing working directory: %s", strerror(errno)); + send_to_char(ch, "Error changing working directory: %s.", strerror(errno)); + exit(1); + } /* Close reserve and other always-open files and release other resources */ - execl (EXE_FILE, "circle", buf2, buf, (char *) NULL); + execl (EXE_FILE, "circle", buf2, buf, (char *) NULL); - /* Failed - successful exec will not return */ - perror ("do_copyover: execl"); - send_to_char (ch, "Copyover FAILED!\n\r"); + /* Failed - successful exec will not return */ + perror ("do_copyover: execl"); + send_to_char (ch, "Copyover FAILED!\n\r"); - exit (1); /* too much trouble to try to recover! */ + exit (1); /* too much trouble to try to recover! */ } ACMD(do_peace) diff --git a/src/boards.c b/src/boards.c index 49a3b90..a6cf6bc 100644 --- a/src/boards.c +++ b/src/boards.c @@ -464,14 +464,33 @@ void board_load_board(int board_type) return; } for (i = 0; i < num_of_msgs[board_type]; i++) { - fread(&(msg_index[board_type][i]), sizeof(struct board_msginfo), 1, fl); + if (fread(&(msg_index[board_type][i]), sizeof(struct board_msginfo), 1, fl) != 1) { + if (feof(fl)) + log("SYSERR: Unexpected EOF encountered in board file %d! Resetting.", board_type); + else if (ferror(fl)) + log("SYSERR: Error reading board file %d: %s. Resetting.", board_type, strerror(errno)); + else + log("SYSERR: Error reading board file %d. Resetting.", board_type); + board_reset_board(board_type); + } if ((len1 = msg_index[board_type][i].heading_len) <= 0) { log("SYSERR: Board file %d corrupt! Resetting.", board_type); board_reset_board(board_type); return; } + CREATE(tmp1, char, len1); - fread(tmp1, sizeof(char), len1, fl); + + if (fread(tmp1, sizeof(char), len1, fl) != len1) { + if (feof(fl)) + log("SYSERR: Unexpected EOF encountered in board file %d! Resetting.", board_type); + else if (ferror(fl)) + log("SYSERR: Error reading board file %d: %s. Resetting.", board_type, strerror(errno)); + else + log("SYSERR: Error reading board file %d. Resetting.", board_type); + board_reset_board(board_type); + } + MSG_HEADING(board_type, i) = tmp1; if ((MSG_SLOTNUM(board_type, i) = find_slot()) == -1) { @@ -481,7 +500,16 @@ void board_load_board(int board_type) } if ((len2 = msg_index[board_type][i].message_len) > 0) { CREATE(tmp2, char, len2); - fread(tmp2, sizeof(char), len2, fl); + if (fread(tmp2, sizeof(char), len2, fl) != sizeof(char) * len2) { + if (feof(fl)) + log("SYSERR: Unexpected EOF encountered in board file %d! Resetting.", board_type); + else if (ferror(fl)) + log("SYSERR: Error reading board file %d: %s. Resetting.", board_type, strerror(errno)); + else + log("SYSERR: Error reading board file %d. Resetting.", board_type); + board_reset_board(board_type); + } + msg_storage[MSG_SLOTNUM(board_type, i)] = tmp2; } else msg_storage[MSG_SLOTNUM(board_type, i)] = NULL; diff --git a/src/comm.c b/src/comm.c index 6cd2cc4..5ec5a3a 100644 --- a/src/comm.c +++ b/src/comm.c @@ -422,7 +422,16 @@ void copyover_recover() for (;;) { fOld = TRUE; - fscanf (fp, "%d %ld %s %s %s\n", &desc, &pref, name, host, guiopt); + if (fscanf(fp, "%d %ld %s %s %s\n", &desc, &pref, name, host, guiopt) != 5) { + if(!feof(fp)) { + if(ferror(fp)) + log("SYSERR: error reading copyover file %s: %s", COPYOVER_FILE, strerror(errno)); + else if(!feof(fp)) + log("SYSERR: could not scan line in copyover file %s.", COPYOVER_FILE); + exit(1); + } + } + if (desc == -1) break; diff --git a/src/db.c b/src/db.c index 814ecb6..82c8664 100644 --- a/src/db.c +++ b/src/db.c @@ -157,14 +157,18 @@ char *fread_action(FILE *fl, int nr) char buf[MAX_STRING_LENGTH]; int i; - fgets(buf, MAX_STRING_LENGTH, fl); - if (feof(fl)) { - log("SYSERR: fread_action: unexpected EOF near action #%d", nr); - /* SYSERR_DESC: fread_action() will fail if it discovers an end of file - * marker before it is able to read in the expected string. This can be - * caused by a truncated socials file. */ + if(fgets(buf, MAX_STRING_LENGTH, fl) == NULL) { + if(feof(fl)) { + log("SYSERR: fread_action: unexpected EOF near action #%d", nr); + /* SYSERR_DESC: fread_action() will fail if it discovers an end of file + * marker before it is able to read in the expected string. This can be + * caused by a truncated socials file. */ + } else { + log("SYSERR: fread_action: read error near action #%d: %s", nr, strerror(errno)); + } exit(1); } + if (*buf == '#') return (NULL); @@ -199,9 +203,12 @@ static void boot_social_messages(void) } /* count socials */ *next_soc = '\0'; - while (!feof(fl)) { - fgets(next_soc, MAX_STRING_LENGTH, fl); + while (fgets(next_soc, MAX_STRING_LENGTH, fl)) if (*next_soc == '~') top_of_socialt++; + + if(ferror(fl)) { + log("SYSERR: error encountered reading socials file %s: %s", SOCMESS_FILE_NEW, strerror(errno)); + exit(1); } } else { /* old style */ @@ -214,9 +221,12 @@ static void boot_social_messages(void) exit(1); } /* count socials */ - while (!feof(fl)) { - fgets(next_soc, MAX_STRING_LENGTH, fl); + while (fgets(next_soc, MAX_STRING_LENGTH, fl)) if (*next_soc == '\n' || *next_soc == '\r') top_of_socialt++; /* all socials are followed by a blank line */ + + if(ferror(fl)) { + log("SYSERR: error encountered reading socials file %s: %s", SOCMESS_FILE_NEW, strerror(errno)); + exit(1); } } @@ -226,8 +236,16 @@ static void boot_social_messages(void) CREATE(soc_mess_list, struct social_messg, top_of_socialt + 1); /* now read 'em */ - for (;;) { - fscanf(fl, " %s ", next_soc); + for (int line_number = 0;; ++line_number) { + if (fscanf(fl, " %s ", next_soc) != 1) { + if(feof(fl)) + log("SYSERR: unexpected end of file encountered in socials file %s", SOCMESS_FILE_NEW); + else if(ferror(fl)) + log("SYSERR: error reading socials file %s: %s", SOCMESS_FILE_NEW, strerror(errno)); + else + log("SYSERR: format error in social file near line %d", line_number); + exit(1); + } if (*next_soc == '$') break; if (CONFIG_NEW_SOCIALS == TRUE) { if (fscanf(fl, " %s %d %d %d %d \n", @@ -798,7 +816,13 @@ static void reset_time(void) if ((bgtime = fopen(TIME_FILE, "r")) == NULL) log("No time file '%s' starting from the beginning.", TIME_FILE); else { - fscanf(bgtime, "%ld\n", (long *)&beginning_of_time); + if(fscanf(bgtime, "%ld\n", (long *)&beginning_of_time) == EOF) { + if(feof(bgtime)) { + log("SYSERR: reset_time: unexpected end of file encountered reading %s.", TIME_FILE); + } else if(ferror(bgtime)) { + log("SYSERR: reset_time: unexpected end of file encountered reading %s: %s.", TIME_FILE, strerror(errno)); + } + } fclose(bgtime); } @@ -955,26 +979,38 @@ void index_boot(int mode) exit(1); } - /* first, count the number of records in the file so we can malloc */ - fscanf(db_index, "%s\n", buf1); - while (*buf1 != '$') { + for (int line_number = 0;; ++line_number) { + /* first, count the number of records in the file so we can malloc */ + if (fscanf(db_index, "%s\n", buf1) != 1) { + if (feof(db_index)) + log("SYSERR: boot error -- unexpected end of file encountered in index file ./%s%s. " + "Ensure that the last line of the file starts with the character '$'.", + prefix, index_filename); + else if (ferror(db_index)) + log("SYSERR: boot error -- unexpected end of file encountered in index file ./%s%s: %s", + prefix, index_filename, strerror(errno)); + else + log("SYSERR: boot error -- error parsing index file %s%s on line %d", + prefix, index_filename, line_number); + exit(1); + } + + if (*buf1 == '$') + break; + snprintf(buf2, sizeof(buf2), "%s%s", prefix, buf1); if (!(db_file = fopen(buf2, "r"))) { log("SYSERR: File '%s' listed in '%s/%s': %s", buf2, prefix, - index_filename, strerror(errno)); - fscanf(db_index, "%s\n", buf1); - continue; + index_filename, strerror(errno)); } else { if (mode == DB_BOOT_ZON) - rec_count++; + rec_count++; else if (mode == DB_BOOT_HLP) - rec_count += count_alias_records(db_file); + rec_count += count_alias_records(db_file); else - rec_count += count_hash_records(db_file); + rec_count += count_hash_records(db_file); + fclose(db_file); } - - fclose(db_file); - fscanf(db_index, "%s\n", buf1); } /* Exit if 0 records, unless this is shops */ @@ -1028,8 +1064,24 @@ void index_boot(int mode) } rewind(db_index); - fscanf(db_index, "%s\n", buf1); - while (*buf1 != '$') { + + for (int line_number = 1;; ++line_number) { + if (fscanf(db_index, "%s\n", buf1) != 1) { + if (feof(db_index)) + log("SYSERR: boot error -- unexpected end of file encountered in index file ./%s%s", + prefix, index_filename); + else if (ferror(db_index)) + log("SYSERR: boot error -- unexpected end of file encountered in index file ./%s%s: %s", + prefix, index_filename, strerror(errno)); + else + log("SYSERR: boot error -- error parsing index file ./%s%s on line %d", + prefix, index_filename, line_number); + exit(1); + } + + if (*buf1 == '$') + break; + snprintf(buf2, sizeof(buf2), "%s%s", prefix, buf1); if (!(db_file = fopen(buf2, "r"))) { log("SYSERR: %s: %s", buf2, strerror(errno)); @@ -1055,7 +1107,6 @@ void index_boot(int mode) } fclose(db_file); - fscanf(db_index, "%s\n", buf1); } fclose(db_index); diff --git a/src/genolc.c b/src/genolc.c index 31503f1..7279033 100644 --- a/src/genolc.c +++ b/src/genolc.c @@ -366,13 +366,13 @@ ACMD(do_export_zone) f = fix_filename(zone_name); /* Remove the old copy. */ - snprintf(sysbuf, MAX_STRING_LENGTH, "rm %s%s.tar.gz", path, f); + snprintf(sysbuf, MAX_INPUT_LENGTH, "rm %s%s.tar.gz", path, f); /* Tar the new copy. */ - snprintf(sysbuf, MAX_STRING_LENGTH, "tar -cf %s%s.tar %sqq.info %sqq.wld %sqq.zon %sqq.mob %sqq.obj %sqq.trg %sqq.shp", path, f, path, path, path, path, path, path, path); + snprintf(sysbuf, MAX_INPUT_LENGTH, "tar -cf %s%s.tar %sqq.info %sqq.wld %sqq.zon %sqq.mob %sqq.obj %sqq.trg %sqq.shp", path, f, path, path, path, path, path, path, path); /* Gzip it. */ - snprintf(sysbuf, MAX_STRING_LENGTH, "gzip %s%s.tar", path, f); + snprintf(sysbuf, MAX_INPUT_LENGTH, "gzip %s%s.tar", path, f); send_to_char(ch, "Files tar'ed to \"%s%s.tar.gz\"\r\n", path, f); } diff --git a/src/limits.c b/src/limits.c index fb4e3cc..a9c5378 100644 --- a/src/limits.c +++ b/src/limits.c @@ -211,7 +211,9 @@ void run_autowiz(void) if (res < sizeof(buf)) { mudlog(CMP, LVL_IMMORT, FALSE, "Initiating autowiz."); reboot_wizlists(); - system(buf); + int rval = system(buf); + if(rval != 0) + mudlog(BRF, LVL_IMMORT, TRUE, "Warning: autowiz failed with return value %d", rval); } else log("Cannot run autowiz: command-line doesn't fit in buffer."); } diff --git a/src/msgedit.c b/src/msgedit.c index 2eb3bdc..5c43060 100644 --- a/src/msgedit.c +++ b/src/msgedit.c @@ -88,13 +88,36 @@ void load_messages(void) fight_messages[i].msg = NULL; } - while (!feof(fl)) { - fgets(chk, 128, fl); - while (!feof(fl) && (*chk == '\n' || *chk == '*')) - fgets(chk, 128, fl); + while (fgets(chk, 128, fl)) { + while (*chk == '\n' || *chk == '*') { + if (fgets(chk, 128, fl) == NULL) { + if (feof(fl)) + break; + else if(ferror(fl)) + log("SYSERR: Error reading combat message file %s: %s", MESS_FILE, strerror(errno)); + else + log("SYSERR: Error reading combat message file %s", MESS_FILE); + exit(1); + } + } + + if(feof(fl)) { + break; + } while (*chk == 'M') { - fgets(chk, 128, fl); + if (fgets(chk, 128, fl) == NULL) { + if(feof(fl)) { + log("SYSERR: Unexpected end of file reading combat message file %s", MESS_FILE); + break; + } + else if(ferror(fl)) + log("SYSERR: Error reading combat message file %s: %s", MESS_FILE, strerror(errno)); + else + log("SYSERR: Error reading combat message file %s", MESS_FILE); + exit(1); + } + sscanf(chk, " %d\n", &type); for (i = 0; (i < MAX_MESSAGES) && (fight_messages[i].a_type != type) && (fight_messages[i].a_type); i++); @@ -120,9 +143,6 @@ void load_messages(void) messages->god_msg.attacker_msg = fread_action(fl, i); messages->god_msg.victim_msg = fread_action(fl, i); messages->god_msg.room_msg = fread_action(fl, i); - fgets(chk, 128, fl); - while (!feof(fl) && (*chk == '\n' || *chk == '*')) - fgets(chk, 128, fl); } } fclose(fl); diff --git a/src/shop.c b/src/shop.c index c3559d9..ed37038 100644 --- a/src/shop.c +++ b/src/shop.c @@ -1089,7 +1089,14 @@ static int read_type_list(FILE *shop_f, struct shop_buy_data *list, return (read_list(shop_f, list, 0, max, LIST_TRADE)); do { - fgets(buf, sizeof(buf), shop_f); + if (fgets(buf, sizeof(buf), shop_f) == NULL) { + if (feof(shop_f)) + log("SYSERR: unexpected end of file reading shop file type list."); + else if (ferror(shop_f)) + log("SYSERR: error reading reading shop file type list: %s", strerror(errno)); + else + log("SYSERR: error reading reading shop file type list."); + } if ((ptr = strchr(buf, ';')) != NULL) *ptr = '\0'; else