From 53fa89373855bd9b1c3e89cff8d32033377ebc54 Mon Sep 17 00:00:00 2001 From: carl Date: Sun, 24 Mar 2019 17:11:56 +0800 Subject: [PATCH 1/8] ANSI C version More portability fixes. --- util/arch/archiver.c | 1094 ++++++++++++++++++++++++------------------ 1 file changed, 615 insertions(+), 479 deletions(-) diff --git a/util/arch/archiver.c b/util/arch/archiver.c index 2be5fd3ad..73ea4e606 100644 --- a/util/arch/archiver.c +++ b/util/arch/archiver.c @@ -2,91 +2,96 @@ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". */ -/* ar - archiver Author: Michiel Huisjes */ +/* ar - archiver Author: Michiel Huisjes */ /* Made into arch/aal by Ceriel Jacobs */ -static char RcsId[] = "$Id$"; + /* * Usage: [arch|aal] [qdprtx][vlcu] archive [file] ... - * v: verbose - * x: extract - * q: append - * r: replace (append when not in archive) - * d: delete - * t: print contents of archive - * p: print named files - * l: temporaries in current directory instead of /tmp - * c: don't give "create" message - * u: replace only if dated later than member in archive -#ifdef DISTRIBUTION - * D: make distribution: use distr_time, uid=2, gid=2, mode=0644 -#endif + * possible key + * d: delete + * p: print named files + * q: append + * r: replace (append when not in archive) + * t: print contents of archive + * x: extract + * possible args + * c: don't give "create" message + * u: replace only if dated later than member in archive + * v: verbose + #ifdef DISTRIBUTION + * D: make distribution: use distr_time, uid=2, gid=2, mode=0644 + #endif */ #include +#include #include #include #include #include #include -#include -#include +#include "print.h" +#include "system.h" +#include "object.h" +#include "arch.h" +#include "ranlib.h" + +/* UNIX specific */ +#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) +#ifndef unix +#define unix +#endif +#endif + +#ifdef unix #include +#else +#define getuid() 0 +#define getgid() 0 +#endif + #ifdef AAL -#include -#define MAGIC_NUMBER AALMAG -long offset; +#include "out.h" +#define MAGIC_NUMBER AALMAG +long offset; struct ranlib *tab; -unsigned int tnum = 0; -char *tstrtab; -unsigned int tssiz = 0; +unsigned int tnum = 0; +char *tstrtab; +unsigned int tssiz = 0; unsigned int tabsz, strtabsz; #else -#define MAGIC_NUMBER ARMAG +#define MAGIC_NUMBER ARMAG #endif -#define odd(nr) (nr & 01) -#define even(nr) (odd(nr) ? nr + 1 : nr) +#define odd(nr) (nr & 01) +#define even(nr) (odd(nr) ? nr + 1 : nr) typedef char BOOL; -#define FALSE 0 -#define TRUE 1 +#define FALSE 0 +#define TRUE 1 -#define READ 0 -#define APPEND 2 -#define CREATE 1 +#define READ 0 +#define APPEND 2 +#define CREATE 1 -#define MEMBER struct ar_hdr +#define MEMBER struct ar_hdr -#define NIL_PTR ((char *) 0) -#define NIL_MEM ((MEMBER *) 0) -#define NIL_LONG ((long *) 0) +#define NIL_PTR ((char *) 0) +#define NIL_MEM ((MEMBER *) 0) +#define NIL_LONG ((long *) 0) -#define IO_SIZE (10 * 1024) +#define IO_SIZE (10 * 1024) -#define equal(str1, str2) (!strncmp((str1), (str2), 14)) -#ifndef S_ISDIR -#define S_ISDIR(m) (m & S_IFDIR) /* is a directory */ -#endif - -/* Use Posix names if old-fashioned names are not defined. */ - -#ifndef S_IREAD -#define S_IREAD S_IRUSR -#endif -#ifndef S_IWRITE -#define S_IWRITE S_IWUSR -#endif -#ifndef S_IEXEC -#define S_IEXEC S_IXUSR -#endif +#define equal(str1, str2) (!strncmp((str1), (str2), AR_NAME_MAX)) BOOL verbose; BOOL app_fl; BOOL ex_fl; BOOL show_fl; +/* print files found in archive. */ BOOL pr_fl; BOOL u_fl; BOOL rep_fl; @@ -95,536 +100,658 @@ BOOL nocr_fl; BOOL local_fl; #ifdef DISTRIBUTION BOOL distr_fl; -long distr_time; +time_t distr_time; #endif -int ar_fd; +#ifndef S_ISUID +#define S_ISUID 0 +#endif +#ifndef S_ISGID +#define S_ISGID 0 +#endif + +#define MODE_COUNT 11 char io_buffer[IO_SIZE]; char *progname; -char temp_buf[32]; +char temp_buf[L_tmpnam]; char *temp_arch = &temp_buf[0]; -extern char *ctime(); -void do_object(int f, long size); -void write_symdef(); -void add(); +void do_object(FILE* f, long size); +void do_names(struct outhead *headp); +void enter_name(struct outname *namep); +void write_symdef(FILE *ar); -usage() +void error(BOOL quit, char *str1, char *str2); +FILE* open_archive(char *name, int mode); +void +catch(int param); +MEMBER *get_member(FILE*); +void get(int argc, char *argv[]); +void add(char *name, FILE* ar, FILE* dst, char *mess); +void extract(FILE* ar, MEMBER *member); +void copy_member(MEMBER *member, FILE* from, FILE* to, BOOL extracting); +char *get_mode(int mode); +void wr_fatal(void); +void rd_fatal(void); +void mwrite(FILE* f, void* address, size_t bytes); +void show(char *s, char *name); + +/* Conversion utilities. */ +static mode_t ar2mode(short mode); +static short mode2ar(mode_t mode); + +/** Maps an AR mode to the current system mode. */ +struct modemap { - error(TRUE, "usage: %s [qdprtxl][vlc] archive [file] ...\n", - progname - ); + short ar_mode; + mode_t mode; +}; + +/** Mapping table to map an AR mode to a system mode. */ +static const struct modemap armodes[MODE_COUNT] = +{ +{ AR_IRUSR, S_IRUSR }, +{ AR_IWUSR, S_IWUSR }, +{ AR_IXUSR, S_IXUSR }, + +{ AR_IRGRP, S_IRGRP }, +{ AR_IWGRP, S_IWGRP }, +{ AR_IXGRP, S_IXGRP }, + +{ AR_IROTH, S_IROTH }, +{ AR_IWOTH, S_IWOTH }, +{ AR_IXOTH, S_IXOTH }, + +{ AR_ISUID, S_ISUID }, +{ AR_ISGID, S_ISGID } }; + +/** Convert an "ar" mode to a system specific + * mode. + */ +static mode_t ar2mode(short mode) +{ + int i; + mode_t result = 0; + for (i = 0; i < MODE_COUNT; i++) + { + if (mode & armodes[i].ar_mode) + { + result = result | armodes[i].mode; + } + } + return result; +} + +/** Convert a system specified mode to + * an ar compatible mode. + */ +static short mode2ar(mode_t mode) +{ + int i; + short result = 0; + for (i = 0; i < MODE_COUNT; i++) + { + if (mode & armodes[i].mode) + { + result = result | armodes[i].ar_mode; + } + } + return result; +} + +static void usage(void) +{ + error(TRUE, "usage: %s [qdprtxl][vc] archive [file] ...\n", progname); } /*VARARGS2*/ -error(quit, str1, str2, str3, str4) -BOOL quit; -char *str1, *str2, *str3, *str4; +void error(BOOL quit, char *str1, char *str2) { char errbuf[256]; - sprint(errbuf, str1, str2, str3, str4); - write(2, errbuf, strlen(errbuf)); - if (quit) { - unlink(temp_arch); - _exit(1); - } -} - -char *basename(path) -char *path; -{ - register char *ptr = path; - register char *last = NIL_PTR; - - while (*ptr != '\0') { - if (*ptr == '/') - last = ptr; - ptr++; - } - if (last == NIL_PTR) - return path; - if (*(last + 1) == '\0') { - *last = '\0'; - return basename(path); - } - return last + 1; -} - -extern unsigned int rd_unsigned2(); - -open_archive(name, mode) -register char *name; -register int mode; -{ - unsigned short magic = 0; - int fd; - - if (mode == CREATE) { - if ((fd = creat(name, 0666)) < 0) - error(TRUE, "cannot creat %s\n", name); - magic = MAGIC_NUMBER; - wr_int2(fd, magic); - return fd; - } - - if ((fd = open(name, mode)) < 0) { - if (mode == APPEND) { - close(open_archive(name, CREATE)); - if (!nocr_fl) error(FALSE, "%s: creating %s\n", progname, name); - return open_archive(name, APPEND); + sprint(errbuf, str1, str2); + fwrite(errbuf, strlen(errbuf), 1, stderr); + if (quit) + { + remove(temp_arch); + exit(1); } - error(TRUE, "cannot open %s\n", name); - } - lseek(fd, 0L, 0); - magic = rd_unsigned2(fd); - if (magic != AALMAG && magic != ARMAG) - error(TRUE, "%s is not in ar format\n", name); +} - return fd; +/** Opens the specified archive. */ +FILE* open_archive(char *name, int mode) +{ + unsigned short magic = 0; + FILE* file = NULL; + + if (mode == CREATE) + { + file = fopen(name, "wb+"); + if (file == NULL) + error(TRUE, "cannot create %s\n", name); + magic = MAGIC_NUMBER; + wr_int2(file, magic); + return file; + } + + file = fopen(name, "rb"); + if (file == NULL) + { + /* mode APPEND and files does not exist. */ + if (mode == APPEND) + { + fclose(open_archive(name, CREATE)); + if (!nocr_fl) + error(FALSE, "creating %s\n", name); + return open_archive(name, APPEND); + } + error(TRUE, "cannot open %s\n", name); + } + else + /* file already exists, simply open it for appending */ + { + if (mode == APPEND) + { + fclose(file); + file = fopen(name, "a+b"); + } + } + fseek(file, 0, SEEK_SET); + magic = rd_unsigned2(file); + if (magic != AALMAG && magic != ARMAG) + error(TRUE, "%s is not in ar format\n", name); + + return file; } void -catch() +catch(int param) { - unlink(temp_arch); - _exit (2); + remove(temp_arch); + exit(2); } -main(argc, argv) -int argc; -char *argv[]; +int main(int argc, char *argv[]) { - register char *ptr; - int needs_arg = 0; + register char *ptr; + int needs_arg = 0; - progname = argv[0]; + progname = argv[0]; - if (argc < 3) - usage(); + if (argc < 3) + usage(); - for (ptr = argv[1]; *ptr; ptr++) { - switch (*ptr) { - case 't' : + for (ptr = argv[1]; *ptr; ptr++) + { + switch (*ptr) + { + case 't': show_fl = TRUE; break; - case 'v' : + case 'v': verbose = TRUE; break; - case 'x' : + case 'x': ex_fl = TRUE; break; - case 'q' : + case 'q': needs_arg = 1; app_fl = TRUE; break; - case 'c' : + case 'c': nocr_fl = TRUE; break; case 'u': u_fl = TRUE; break; - case 'p' : + case 'p': needs_arg = 1; pr_fl = TRUE; break; - case 'd' : + case 'd': needs_arg = 1; del_fl = TRUE; break; - case 'r' : + case 'r': needs_arg = 1; rep_fl = TRUE; break; - case 'l' : - local_fl = TRUE; - break; #ifdef DISTRIBUTION - case 'D' : + case 'D' : distr_fl = TRUE; break; #endif - default : + default: usage(); + } } - } - if (needs_arg && argc <= 3) - usage(); + if (needs_arg && argc <= 3) + usage(); #ifdef DISTRIBUTION - if (distr_fl) { - static struct stat statbuf; + if (distr_fl) + { + static struct stat statbuf; - stat(progname, &statbuf); - distr_time = statbuf.st_mtime; - } + stat(progname, &statbuf); + distr_time = statbuf.st_mtime; + } #endif - if (local_fl) strcpy(temp_arch, "ar.XXXXXX"); - else strcpy(temp_arch, "/tmp/ar.XXXXXX"); + if (sys_tmpnam(temp_arch) == NULL) + { + error(TRUE, "Cannot create a temporary filename\n", NULL); + } - if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1) - usage(); + if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1) + usage(); - if (u_fl && ! rep_fl) - usage(); + if (u_fl && !rep_fl) + usage(); - if (rep_fl || del_fl + if (rep_fl || del_fl #ifdef AAL - || app_fl + || app_fl #endif - ) { - close(mkstemp(temp_arch)); - } + ) + { + /*fclose(mkstemp(temp_arch));*/ + } #ifdef AAL - tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib)); - tstrtab = malloc(4096); - if (!tab || !tstrtab) error(TRUE,"Out of core\n"); - tabsz = 512; - strtabsz = 4096; + tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib)); + tstrtab = malloc(4096); + if (!tab || !tstrtab) + error(TRUE, "Out of core\n", NULL); + tabsz = 512; + strtabsz = 4096; #endif - signal(SIGINT, catch); - get(argc, argv); + signal(SIGINT, + catch); + get(argc, argv); - return 0; + return 0; } -MEMBER * -get_member() +/* Read next member of in the archive file "f". */ +MEMBER *get_member(FILE *f) { - static MEMBER member; + static MEMBER member; -again: - if (rd_arhdr(ar_fd, &member) == 0) + again: + if (rd_arhdr(f, &member) == 0) return NIL_MEM; - if (member.ar_size < 0) { - error(TRUE, "archive has member with negative size\n"); - } - if (equal(SYMDEF, member.ar_name)) { - lseek(ar_fd, member.ar_size, 1); - goto again; - } - return &member; + if (member.ar_size < 0) + { + error(TRUE, "archive has member with negative size\n",NULL); + } + if (equal(SYMDEF, member.ar_name)) + { + fseek(f, member.ar_size, SEEK_CUR); + goto again; + } + return &member; } -char *get_mode(); - -get(argc, argv) -int argc; -register char *argv[]; +void get(int argc, char *argv[]) { - register MEMBER *member; - int i = 0; - int temp_fd, read_chars; + register MEMBER *member; + FILE *ar_f; + int i = 0; + char buffer[FILENAME_MAX]; + size_t read_chars; + FILE* temp_fd; - ar_fd = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND); - if (rep_fl || del_fl + ar_f = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND); + if (rep_fl || del_fl #ifdef AAL - || app_fl + || app_fl #endif - ) + ) temp_fd = open_archive(temp_arch, CREATE); - while ((member = get_member()) != NIL_MEM) { - if (argc > 3) { - for (i = 3; i < argc; i++) { - if (equal(basename(argv[i]), member->ar_name)) + while ((member = get_member(ar_f)) != NIL_MEM) + { + if (argc > 3) + { + for (i = 3; i < argc; i++) + { + sys_basename(argv[i],buffer); + if (equal(buffer, member->ar_name)) break; - } - if (i == argc || app_fl) { - if (rep_fl || del_fl -#ifdef AAL - || app_fl -#endif - ) { -#ifdef AAL - if (i != argc) { - print("%s: already in archive\n", argv[i]); - argv[i] = ""; - } -#endif - wr_arhdr(temp_fd, member); - copy_member(member, ar_fd, temp_fd, 0); } - else { + if (i == argc || app_fl) + { + if (rep_fl || del_fl +#ifdef AAL + || app_fl +#endif + ) + { +#ifdef AAL + if (i != argc) + { + print("%s: already in archive\n", argv[i]); + argv[i] = ""; + } +#endif + wr_arhdr(temp_fd, member); + copy_member(member, ar_f, temp_fd, FALSE); + } + else + { #ifndef AAL - if (app_fl && i != argc) { - print("%s: already in archive\n", argv[i]); - argv[i] = ""; - } + if (app_fl && i != argc) + { + print("%s: already in archive\n", argv[i]); + argv[i] = ""; + } #endif - lseek(ar_fd, even(member->ar_size),1); + fseek(ar_f, even(member->ar_size),SEEK_CUR); + } + continue; } - continue; } - } - if (ex_fl || pr_fl) - extract(member); - else { - if (rep_fl) - add(argv[i], temp_fd, "r - %s\n"); - else if (show_fl) { - char buf[sizeof(member->ar_name) + 2]; - register char *p = buf, *q = member->ar_name; + if (ex_fl || pr_fl) + extract(ar_f,member); + else + { + if (rep_fl) + add(argv[i], ar_f, temp_fd, "r - %s\n"); + else if (show_fl) + { + char buf[sizeof(member->ar_name) + 2]; + register char *p = buf, *q = member->ar_name; - while (q <= &member->ar_name[sizeof(member->ar_name)-1] && *q) { - *p++ = *q++; + while (q <= &member->ar_name[sizeof(member->ar_name)-1] && *q) + { + *p++ = *q++; + } + *p++ = '\n'; + *p = '\0'; + if (verbose) + { + char *mode = get_mode(member->ar_mode); + char *date = ctime(&(member->ar_date)); + + *(date + 16) = '\0'; + *(date + 24) = '\0'; + + print("%s%3u/%u%7ld %s %s %s", + mode, + (unsigned) (member->ar_uid & 0377), + (unsigned) (member->ar_gid & 0377), + member->ar_size, + date+4, + date+20, + buf); + } + else print(buf); } - *p++ = '\n'; - *p = '\0'; - if (verbose) { - char *mode = get_mode(member->ar_mode); - char *date = ctime(&(member->ar_date)); - - *(date + 16) = '\0'; - *(date + 24) = '\0'; - - print("%s%3u/%u%7ld %s %s %s", - mode, - (unsigned) (member->ar_uid & 0377), - (unsigned) (member->ar_gid & 0377), - member->ar_size, - date+4, - date+20, - buf); + else if (del_fl) + { + show("d - %s\n", member->ar_name); } - else print(buf); + fseek(ar_f, even(member->ar_size), SEEK_CUR); } - else if (del_fl) - show("d - %s\n", member->ar_name); - lseek(ar_fd, even(member->ar_size), 1); + argv[i] = ""; } - argv[i] = ""; - } - if (argc > 3) { - for (i = 3; i < argc; i++) - if (argv[i][0] != '\0') { + if (argc > 3) + { + for (i = 3; i < argc; i++) + if (argv[i][0] != '\0') + { #ifndef AAL if (app_fl) - add(argv[i], ar_fd, "a - %s\n"); + add(argv[i], ar_f, "a - %s\n"); else #endif if (rep_fl #ifdef AAL - || app_fl + || app_fl #endif ) - add(argv[i], temp_fd, "a - %s\n"); - else { + add(argv[i], ar_f, temp_fd, "a - %s\n"); + else + { print("%s: not found\n", argv[i]); } } - } + } - if (rep_fl || del_fl + if (rep_fl || del_fl #ifdef AAL - || app_fl + || app_fl #endif - ) { - signal(SIGINT, SIG_IGN); - close(ar_fd); - close(temp_fd); - ar_fd = open_archive(argv[2], CREATE); - temp_fd = open_archive(temp_arch, APPEND); + ) + { + signal(SIGINT, SIG_IGN); + fclose(ar_f); + fclose(temp_fd); + ar_f = open_archive(argv[2], CREATE); + temp_fd = open_archive(temp_arch, APPEND); #ifdef AAL - write_symdef(); + write_symdef(ar_f); #endif - while ((read_chars = read(temp_fd, io_buffer, IO_SIZE)) > 0) - mwrite(ar_fd, io_buffer, read_chars); - close(temp_fd); - unlink(temp_arch); - } - close(ar_fd); + while ((read_chars = fread(io_buffer, 1, IO_SIZE, temp_fd)) > 0) + mwrite(ar_f, io_buffer, read_chars); + fclose(temp_fd); + remove(temp_arch); + } + fclose(ar_f); } -void -add(name, fd, mess) -char *name; -int fd; -char *mess; +/** Add an entry into the archive. + * + * @param[in] name path specification of the file to add. + * @param[in] ar Original ar file for update. + * @param[in] dst Archive name that will have its file added. + * + */ +void add(char *name, FILE* ar, FILE* dst, char *mess) { - static MEMBER member; - register int read_chars; - struct stat status; - int src_fd; + static MEMBER member; + size_t read_chars; + struct stat status; + char buffer[FILENAME_MAX]; + FILE* src_fd = NULL; - if (stat(name, &status) < 0) { - error(FALSE, "cannot find %s\n", name); - return; - } - else if (S_ISDIR(status.st_mode)) { - error(FALSE, "%s is a directory (ignored)\n", name); - return; - } - else if (u_fl && status.st_mtime <= member.ar_date) { - wr_arhdr(fd, member); - copy_member(member, ar_fd, fd, 0); - return; - } - else if ((src_fd = open(name, 0)) < 0) { - error(FALSE, "cannot open %s\n", name); - return; - } + if (stat(name, &status) < 0) + { + error(FALSE, "cannot find %s\n", name); + return; + } + else if (S_ISDIR(status.st_mode)) + { + error(FALSE, "%s is a directory (ignored)\n", name); + return; + } + else if (u_fl && status.st_mtime <= member.ar_date) + { + wr_arhdr(dst, &member); + copy_member(&member, ar, dst, FALSE); + return; + } + else if ((src_fd = fopen(name, "rb")) == NULL) + { + error(FALSE, "cannot open %s\n", name); + return; + } - strncpy (member.ar_name, basename (name), sizeof(member.ar_name)); - member.ar_uid = status.st_uid; - member.ar_gid = status.st_gid; - member.ar_mode = status.st_mode; - member.ar_date = status.st_mtime; - member.ar_size = status.st_size; + sys_basename(name, buffer); + strncpy (member.ar_name, buffer, sizeof(member.ar_name)); + member.ar_uid = status.st_uid; + member.ar_gid = status.st_gid; + member.ar_mode = mode2ar(status.st_mode); + member.ar_date = status.st_mtime; + member.ar_size = status.st_size; #ifdef DISTRIBUTION - if (distr_fl) { - member.ar_uid = 2; - member.ar_gid = 2; - member.ar_mode = 0644; - member.ar_date = distr_time; - } + if (distr_fl) + { + member.ar_uid = 2; + member.ar_gid = 2; + member.ar_mode = AR_IUSR | AR_IWUSR | AR_IRGRP | AR_IROTH; + member.ar_date = distr_time; + } #endif - wr_arhdr(fd, &member); + wr_arhdr(dst, &member); #ifdef AAL - do_object(src_fd, member.ar_size); - lseek(src_fd, 0L, 0); - offset += AR_TOTAL + even(member.ar_size); + do_object(src_fd, member.ar_size); + fseek(src_fd, 0L, SEEK_SET); + offset += AR_TOTAL + even(member.ar_size); #endif - while (status.st_size > 0) { - int x = IO_SIZE; + while (status.st_size > 0) + { + size_t x = IO_SIZE; - read_chars = x; - if (status.st_size < x) { - x = status.st_size; read_chars = x; - status.st_size = 0; - x = even(x); + if (status.st_size < x) + { + x = status.st_size; + read_chars = x; + status.st_size = 0; + x = even(x); + } + else status.st_size -= x; + if (fread(io_buffer, 1, read_chars, src_fd) != read_chars) + { + error(FALSE,"%s seems to shrink\n", name); + break; + } + mwrite(dst, io_buffer, x); } - else status.st_size -= x; - if (read(src_fd, io_buffer, read_chars) != read_chars) { - error(FALSE,"%s seems to shrink\n", name); - break; - } - mwrite(fd, io_buffer, x); - } - if (verbose) - show(mess, member.ar_name); - close(src_fd); + if (verbose) + show(mess, member.ar_name); + fclose(src_fd); } -extract(member) -register MEMBER *member; +/** Extract an archive entry pointed to by member to + * either standard output or to a file. + * + */ +void extract(FILE* ar, MEMBER *member) { - int fd = 1; - char buf[sizeof(member->ar_name) + 1]; + FILE* file = stdout; + char buf[sizeof(member->ar_name) + 1]; - strncpy(buf, member->ar_name, sizeof(member->ar_name)); - buf[sizeof(member->ar_name)] = 0; - if (pr_fl == FALSE && (fd = creat(buf, 0666)) < 0) { - error(FALSE, "cannot create %s\n", buf); - fd = -1; - } + strncpy(buf, member->ar_name, sizeof(member->ar_name)); + buf[sizeof(member->ar_name)] = 0; + if (pr_fl == FALSE) + { + file = fopen(buf, "wb"); + if (file == NULL) + { + error(FALSE, "cannot create %s\n", buf); + file = NULL; + } + }; - if (verbose) { - if (pr_fl == FALSE) show("x - %s\n", buf); - else show("\n<%s>\n\n", buf); - } + if (verbose) + { + if (pr_fl == FALSE) + show("x - %s\n", buf); + else + show("\n<%s>\n\n", buf); + } - copy_member(member, ar_fd, fd, 1); + copy_member(member, ar, file, TRUE); - if (fd >= 0 && fd != 1) - close(fd); - if (pr_fl == FALSE) chmod(buf, member->ar_mode); + if (file != NULL) + fclose(file); + if (pr_fl == FALSE) + chmod(buf, ar2mode(member->ar_mode)); } -copy_member(member, from, to, extracting) -register MEMBER *member; -int from, to; +void copy_member(MEMBER *member, FILE* from, FILE* to, BOOL extracting) { - register int rest; - long mem_size = member->ar_size; - BOOL is_odd = odd(mem_size) ? TRUE : FALSE; + size_t rest; + long mem_size = member->ar_size; + BOOL is_odd = odd(mem_size) ? TRUE : FALSE; #ifdef AAL - if (! extracting) { - long pos = lseek(from, 0L, 1); + if (!extracting) + { + long pos = ftell(from); - do_object(from, mem_size); - offset += AR_TOTAL + even(mem_size); - lseek(from, pos, 0); - } -#endif - do { - rest = mem_size > (long) IO_SIZE ? IO_SIZE : (int) mem_size; - if (read(from, io_buffer, rest) != rest) { - char buf[sizeof(member->ar_name) + 1]; - - strncpy(buf, member->ar_name, sizeof(member->ar_name)); - buf[sizeof(member->ar_name)] = 0; - error(TRUE, "read error on %s\n", buf); + do_object(from, mem_size); + offset += AR_TOTAL + even(mem_size); + fseek(from, pos, SEEK_SET); } - if (to >= 0) mwrite(to, io_buffer, rest); - mem_size -= (long) rest; - } while (mem_size > 0L); +#endif + do + { + rest = mem_size > (size_t) IO_SIZE ? IO_SIZE : (size_t) mem_size; + if (fread(io_buffer, 1, rest, from) != rest) + { + char buf[sizeof(member->ar_name) + 1]; - if (is_odd) { - lseek(from, 1L, 1); - if (to >= 0 && ! extracting) - lseek(to, 1L, 1); - } + strncpy(buf, member->ar_name, sizeof(member->ar_name)); + buf[sizeof(member->ar_name)] = 0; + error(TRUE, "read error on %s\n", buf); + } + if (to != NULL) + mwrite(to, io_buffer, rest); + mem_size -= (long) rest; + } while (mem_size > 0L); + + if (is_odd) + { + fseek(from, 1L, SEEK_CUR); + if ((to != NULL) && (extracting == FALSE)) + fseek(to, 1L, SEEK_CUR); + } } -char * -get_mode(mode) -register int mode; +char *get_mode(int mode) { - static char mode_buf[11]; - register int tmp = mode; - int i; + static char mode_buf[11]; + register int tmp = mode; + int i; - mode_buf[9] = ' '; - for (i = 0; i < 3; i++) { - mode_buf[i * 3] = (tmp & S_IREAD) ? 'r' : '-'; - mode_buf[i * 3 + 1] = (tmp & S_IWRITE) ? 'w' : '-'; - mode_buf[i * 3 + 2] = (tmp & S_IEXEC) ? 'x' : '-'; - tmp <<= 3; - } - if (mode & S_ISUID) - mode_buf[2] = 's'; - if (mode & S_ISGID) - mode_buf[5] = 's'; - return mode_buf; + mode_buf[9] = ' '; + for (i = 0; i < 3; i++) + { + mode_buf[i * 3] = (tmp & AR_IRUSR) ? 'r' : '-'; + mode_buf[i * 3 + 1] = (tmp & AR_IWUSR) ? 'w' : '-'; + mode_buf[i * 3 + 2] = (tmp & AR_IXUSR) ? 'x' : '-'; + tmp <<= 3; + } + if (mode & AR_ISUID) + mode_buf[2] = 's'; + if (mode & AR_ISGID) + mode_buf[5] = 's'; + return mode_buf; } -wr_fatal() +void wr_fatal(void) { - error(TRUE, "write error\n"); + error(TRUE, "write error\n", NULL); } -rd_fatal() +void rd_fatal(void) { - error(TRUE, "read error\n"); + error(TRUE, "read error\n", NULL); } -mwrite(fd, address, bytes) -int fd; -register char *address; -register int bytes; +void mwrite(FILE* f, void* address, size_t bytes) { - if (write(fd, address, bytes) != bytes) - error(TRUE, "write error\n"); + if (fwrite(address, 1, bytes, f) != bytes) + error(TRUE, "write error\n", NULL); } -show(s, name) -char *s, *name; +void show(char *s, char *name) { - MEMBER x; - char buf[sizeof(x.ar_name)+1]; - register char *p = buf, *q = name; + MEMBER x; + char buf[sizeof(x.ar_name) + 1]; + register char *p = buf, *q = name; - while (q <= &name[sizeof(x.ar_name)-1] && *q) *p++ = *q++; - *p++ = '\0'; - print(s, buf); + while (q <= &name[sizeof(x.ar_name) - 1] && *q) + *p++ = *q++; + *p++ = '\0'; + print(s, buf); } #ifdef AAL @@ -634,76 +761,80 @@ char *s, *name; * then 4 bytes giving the size of the string table, followed by the string * table itself. */ -void -write_symdef() +void write_symdef(FILE *ar) { - register struct ranlib *ran; - register int i; - register long delta; - MEMBER arbuf; + register struct ranlib *ran; + register int i; + register long delta; + time_t time_value; + MEMBER arbuf; - if (! tnum) return; + if (!tnum) + return; if (odd(tssiz)) tstrtab[tssiz++] = '\0'; for (i = 0; i < sizeof(arbuf.ar_name); i++) arbuf.ar_name[i] = '\0'; strcpy(arbuf.ar_name, SYMDEF); - arbuf.ar_size = 4 + 2 * 4 * (long)tnum + 4 + (long)tssiz; - time(&arbuf.ar_date); + arbuf.ar_size = 4 + 2 * 4 * (long) tnum + 4 + (long) tssiz; + time(&time_value); + arbuf.ar_date = (long) time_value; arbuf.ar_uid = getuid(); arbuf.ar_gid = getgid(); - arbuf.ar_mode = 0444; + arbuf.ar_mode = AR_IRUSR | AR_IRGRP | AR_IROTH; #ifdef DISTRIBUTION - if (distr_fl) { + if (distr_fl) + { arbuf.ar_uid = 2; arbuf.ar_gid = 2; arbuf.ar_date = distr_time; } #endif - wr_arhdr(ar_fd,&arbuf); - wr_long(ar_fd, (long) tnum); + wr_arhdr(ar, &arbuf); + wr_long(ar, (long) tnum); /* * Account for the space occupied by the magic number * and the ranlib table. */ delta = 2 + AR_TOTAL + arbuf.ar_size; - for (ran = tab; ran < &tab[tnum]; ran++) { + for (ran = tab; ran < &tab[tnum]; ran++) + { ran->ran_pos += delta; } - wr_ranlib(ar_fd, tab, (long) tnum); - wr_long(ar_fd, (long) tssiz); - wr_bytes(ar_fd, tstrtab, (long) tssiz); + wr_ranlib(ar, tab, (long) tnum); + wr_long(ar, (long) tssiz); + wr_bytes(ar, tstrtab, (long) tssiz); } /* * Return whether the bytes in `buf' form a good object header. * The header is put in `headp'. */ -int -is_outhead(headp) - register struct outhead *headp; +int is_outhead(struct outhead *headp) { - return !BADMAGIC(*headp) && headp->oh_nname != 0; } -void do_object(int f, long size) +void do_object(FILE* f, long size) { - struct outhead headbuf; + struct outhead headbuf; - if (size < SZ_HEAD) { + if (size < SZ_HEAD) + { /* It can't be an object file. */ return; } /* * Read a header to see if it is an object file. */ - if (! rd_fdopen(f)) { + if (!rd_fdopen(f)) + { rd_fatal(); } rd_ohead(&headbuf); - if (!is_outhead(&headbuf)) { + if (!is_outhead(&headbuf)) + { return; } do_names(&headbuf); @@ -714,30 +845,32 @@ void do_object(int f, long size) * name table and read and write the names one by one. Update the ranlib table * accordingly. */ -do_names(headp) - struct outhead *headp; +void do_names(struct outhead *headp) { - register char *strings; - register int nnames = headp->oh_nname; + register char *strings = NULL; + register int nnames = headp->oh_nname; #define NNAMES 100 - struct outname namebuf[NNAMES]; + struct outname namebuf[NNAMES]; long xxx = OFF_CHAR(*headp); - if ( headp->oh_nchar != (unsigned int)headp->oh_nchar || - (strings = malloc((unsigned int)headp->oh_nchar)) == (char *)0 - ) { - error(TRUE, "string table too big\n"); + if ( (headp->oh_nchar != (unsigned int) headp->oh_nchar) + || ((strings = malloc((unsigned int) headp->oh_nchar))) == NULL) + { + error(TRUE, "string table too big\n", NULL); } rd_string(strings, headp->oh_nchar); - while (nnames) { + while (nnames) + { int i = nnames >= NNAMES ? NNAMES : nnames; register struct outname *p = namebuf; nnames -= i; rd_name(namebuf, i); - while (i--) { + while (i--) + { long off = p->on_foff - xxx; - if (p->on_foff == (long)0) { + if (p->on_foff == (long) 0) + { p++; continue; /* An unrecognizable name. */ } @@ -750,9 +883,7 @@ do_names(headp) * However, this problem also exists on the Unix * ranlib archives. */ - if ( (p->on_type & S_EXT) && - (p->on_type & S_TYP) != S_UND - ) + if ((p->on_type & S_EXT) && (p->on_type & S_TYP) != S_UND) enter_name(p); p++; } @@ -760,26 +891,31 @@ do_names(headp) free(strings); } -enter_name(namep) - struct outname *namep; +void enter_name(struct outname *namep) { - register char *cp; + register char *cp; - if (tnum >= tabsz) { - tab = (struct ranlib *) - realloc((char *) tab, (tabsz += 512) * sizeof(struct ranlib)); - if (! tab) error(TRUE, "Out of core\n"); + if (tnum >= tabsz) + { + tab = (struct ranlib *) realloc((char *) tab, + (tabsz += 512) * sizeof(struct ranlib)); + if (!tab) + error(TRUE, "Out of core\n", NULL); } tab[tnum].ran_off = tssiz; tab[tnum].ran_pos = offset; - for (cp = namep->on_mptr;; cp++) { - if (tssiz >= strtabsz) { + for (cp = namep->on_mptr;; cp++) + { + if (tssiz >= strtabsz) + { tstrtab = realloc(tstrtab, (strtabsz += 4096)); - if (! tstrtab) error(TRUE, "string table overflow\n"); + if (!tstrtab) + error(TRUE, "string table overflow\n", NULL); } - tstrtab[tssiz++] = *cp; - if (!*cp) break; + tstrtab[tssiz++] = *cp; + if (!*cp) + break; } tnum++; } From 9fc3102b4d376bb7ac53edc4825f97efc017c334 Mon Sep 17 00:00:00 2001 From: carl Date: Sat, 15 Jun 2019 23:45:42 +0800 Subject: [PATCH 2/8] shift right cannot cause an overflow. --- doc/em/assem.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/em/assem.nr b/doc/em/assem.nr index db18e8efa..6231f2c2c 100644 --- a/doc/em/assem.nr +++ b/doc/em/assem.nr @@ -634,7 +634,7 @@ GROUP 3 \- INTEGER ARITHMETIC RMI \*w : Remainder (*) NGI \*w : Negate (two's complement) (*) SLI \*w : Shift left (*) - SRI \*w : Shift right (*) + SRI \*w : Shift right .DE .DS From 014c151091ddd3b26c3b248b53ec94b3a67cf558 Mon Sep 17 00:00:00 2001 From: carl Date: Sat, 15 Jun 2019 23:46:18 +0800 Subject: [PATCH 3/8] bugfixes to make pascal compiler work. --- fast/driver/driver.c | 47 +++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/fast/driver/driver.c b/fast/driver/driver.c index c0e70f8b1..25c2107c3 100644 --- a/fast/driver/driver.c +++ b/fast/driver/driver.c @@ -152,7 +152,7 @@ const struct system_information machine_info[2] = }} #else #ifdef FM2 - /* pc Flags */ + /* modula-2 Flags */ {1, { "-Vw2.2i2.2l4.2p2.2f8.2S2.2" }} @@ -207,7 +207,7 @@ const struct system_information machine_info[2] = }} #else #ifdef FM2 - /* pc Flags */ + /* modula-2 Flags */ {1, { "-Vw2.2i2.2l4.2p4.2f8.2S2.2" }} @@ -221,7 +221,6 @@ const struct system_information machine_info[2] = struct arglist CPP_FLAGS = {0,{NULL}}; - struct arglist LD_HEAD = { 2, { "$H/lib/$S/head_em", @@ -298,12 +297,12 @@ static int cv_flag = 0; char *mkstr(char *, ...); static char *alloc(unsigned int); static char *extension(char *); -static char *expand_string(char *); +static char *expand_string(char *s, struct system_information *); static void error(char *, char *, char *); static void warning(char *, char *, char *); static void panic(char *); static void append(register struct arglist *, char *); -static void expand(register struct arglist *); +static void expand(register struct arglist *, struct system_information *); static void concat(struct arglist *, struct arglist *); static int runvec(struct arglist *, char *); static int needsprep(char *); @@ -345,6 +344,12 @@ void trapcc(int sig) #define comp_name() "$H/lib/ack/em_pc" #endif /* FPC */ +/** Default library directories to search in. */ + +#define LIB_DIR_1 "$H/share/ack/$S" +#define LIB_DIR_2 "$H/lib/ack/plat/$S" + + #ifdef FCC int lang_opt(char *str) { @@ -524,6 +529,8 @@ char* search_library_path(struct stringlist *dirs, char* lib) return NULL; } + + int main(int argc, char *argv[]) { /* Contains the directories being searched for libraries */ @@ -574,11 +581,16 @@ int main(int argc, char *argv[]) sys_basename(*argv++, ProgCall); /* get compiler to use. */ - COMP = expand_string(comp_name()); + COMP = expand_string(comp_name(),sys_info); /* get c pre-processor to use */ - CPP = expand_string(CPP_NAME); + CPP = expand_string(CPP_NAME,sys_info); /** get linker to use */ - LD = expand_string(sys_info->linker); + LD = expand_string(sys_info->linker,sys_info); + + /* Add system directory path. */ + stringlist_add(&library_dirs,expand_string(LIB_DIR_1,sys_info)); + stringlist_add(&library_dirs,expand_string(LIB_DIR_2,sys_info)); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) @@ -682,6 +694,9 @@ int main(int argc, char *argv[]) { append(&COMP_FLAGS, sys_info->compiler_flags.al_argv[count]); } +#ifdef FPC + append(&COMP_FLAGS, "-d"); +#endif /* Now for each srcfile, if it starts with -l then replace it with the correct real * path immediately. @@ -734,12 +749,12 @@ int main(int argc, char *argv[]) } #ifdef FM2 - INCLUDE = expand_string("-I$H/lib/m2"); + INCLUDE = expand_string("-I$H/lib/m2",sys_info); #endif /* FM2 */ #ifdef FCC /* INCLUDE = expand_string( ansi_c ? "-I$H/include/tail_ac" : "-I$H/include/_tail_cc"); */ - INCLUDE = expand_string("-I$H/share/ack/include"); + INCLUDE = expand_string("-I$H/share/ack/include",sys_info); /* append(&COMP_FLAGS, "-L");*/ #endif /* FCC */ count = SRCFILES.al_argc; @@ -912,7 +927,7 @@ int main(int argc, char *argv[]) if (cv_flag) { init(call); - append(call, expand_string(sys_info->cv)); + append(call, expand_string(sys_info->cv, sys_info)); append(call, tmp_file); append(call, o_FILE); if (runvec(call, (char *) 0)==EXIT_FAILURE) @@ -959,7 +974,7 @@ static char * alloc(unsigned int u) return p; } -static char * expand_string(char *s) +static char * expand_string(char *s, struct system_information *sysinfo) { char buf[1024]; register char *p = s; @@ -986,10 +1001,10 @@ static char * expand_string(char *s) strcpy(q, ackhome); break; case 'M': - strcpy(q, MACHNAME); + strcpy(q, sysinfo->arch); break; case 'S': - strcpy(q, SYSNAME); + strcpy(q, sysinfo->platform); break; default: panic("internal error"); @@ -1018,14 +1033,14 @@ static void append(register struct arglist *al, char *arg) al->al_argv[(al->al_argc)++] = arg; } -static void expand(register struct arglist *al) +static void expand(register struct arglist *al, struct system_information *sysinfo) { register int i = al->al_argc; register char **p = &(al->al_argv[0]); while (i-- > 0) { - *p = expand_string(*p); + *p = expand_string(*p,sysinfo); p++; } } From f2c8e42f95e7d7f4860528968dfc652aace13b24 Mon Sep 17 00:00:00 2001 From: carl Date: Sat, 15 Jun 2019 23:45:42 +0800 Subject: [PATCH 4/8] shift right cannot cause an overflow. --- doc/em/assem.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/em/assem.nr b/doc/em/assem.nr index db18e8efa..6231f2c2c 100644 --- a/doc/em/assem.nr +++ b/doc/em/assem.nr @@ -634,7 +634,7 @@ GROUP 3 \- INTEGER ARITHMETIC RMI \*w : Remainder (*) NGI \*w : Negate (two's complement) (*) SLI \*w : Shift left (*) - SRI \*w : Shift right (*) + SRI \*w : Shift right .DE .DS From 1ec55dfc6ed9629f6c2b55c6b5649f0bf6346de4 Mon Sep 17 00:00:00 2001 From: carl Date: Sat, 15 Jun 2019 23:46:18 +0800 Subject: [PATCH 5/8] bugfixes to make pascal compiler work. --- fast/driver/driver.c | 47 +++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/fast/driver/driver.c b/fast/driver/driver.c index c0e70f8b1..25c2107c3 100644 --- a/fast/driver/driver.c +++ b/fast/driver/driver.c @@ -152,7 +152,7 @@ const struct system_information machine_info[2] = }} #else #ifdef FM2 - /* pc Flags */ + /* modula-2 Flags */ {1, { "-Vw2.2i2.2l4.2p2.2f8.2S2.2" }} @@ -207,7 +207,7 @@ const struct system_information machine_info[2] = }} #else #ifdef FM2 - /* pc Flags */ + /* modula-2 Flags */ {1, { "-Vw2.2i2.2l4.2p4.2f8.2S2.2" }} @@ -221,7 +221,6 @@ const struct system_information machine_info[2] = struct arglist CPP_FLAGS = {0,{NULL}}; - struct arglist LD_HEAD = { 2, { "$H/lib/$S/head_em", @@ -298,12 +297,12 @@ static int cv_flag = 0; char *mkstr(char *, ...); static char *alloc(unsigned int); static char *extension(char *); -static char *expand_string(char *); +static char *expand_string(char *s, struct system_information *); static void error(char *, char *, char *); static void warning(char *, char *, char *); static void panic(char *); static void append(register struct arglist *, char *); -static void expand(register struct arglist *); +static void expand(register struct arglist *, struct system_information *); static void concat(struct arglist *, struct arglist *); static int runvec(struct arglist *, char *); static int needsprep(char *); @@ -345,6 +344,12 @@ void trapcc(int sig) #define comp_name() "$H/lib/ack/em_pc" #endif /* FPC */ +/** Default library directories to search in. */ + +#define LIB_DIR_1 "$H/share/ack/$S" +#define LIB_DIR_2 "$H/lib/ack/plat/$S" + + #ifdef FCC int lang_opt(char *str) { @@ -524,6 +529,8 @@ char* search_library_path(struct stringlist *dirs, char* lib) return NULL; } + + int main(int argc, char *argv[]) { /* Contains the directories being searched for libraries */ @@ -574,11 +581,16 @@ int main(int argc, char *argv[]) sys_basename(*argv++, ProgCall); /* get compiler to use. */ - COMP = expand_string(comp_name()); + COMP = expand_string(comp_name(),sys_info); /* get c pre-processor to use */ - CPP = expand_string(CPP_NAME); + CPP = expand_string(CPP_NAME,sys_info); /** get linker to use */ - LD = expand_string(sys_info->linker); + LD = expand_string(sys_info->linker,sys_info); + + /* Add system directory path. */ + stringlist_add(&library_dirs,expand_string(LIB_DIR_1,sys_info)); + stringlist_add(&library_dirs,expand_string(LIB_DIR_2,sys_info)); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) @@ -682,6 +694,9 @@ int main(int argc, char *argv[]) { append(&COMP_FLAGS, sys_info->compiler_flags.al_argv[count]); } +#ifdef FPC + append(&COMP_FLAGS, "-d"); +#endif /* Now for each srcfile, if it starts with -l then replace it with the correct real * path immediately. @@ -734,12 +749,12 @@ int main(int argc, char *argv[]) } #ifdef FM2 - INCLUDE = expand_string("-I$H/lib/m2"); + INCLUDE = expand_string("-I$H/lib/m2",sys_info); #endif /* FM2 */ #ifdef FCC /* INCLUDE = expand_string( ansi_c ? "-I$H/include/tail_ac" : "-I$H/include/_tail_cc"); */ - INCLUDE = expand_string("-I$H/share/ack/include"); + INCLUDE = expand_string("-I$H/share/ack/include",sys_info); /* append(&COMP_FLAGS, "-L");*/ #endif /* FCC */ count = SRCFILES.al_argc; @@ -912,7 +927,7 @@ int main(int argc, char *argv[]) if (cv_flag) { init(call); - append(call, expand_string(sys_info->cv)); + append(call, expand_string(sys_info->cv, sys_info)); append(call, tmp_file); append(call, o_FILE); if (runvec(call, (char *) 0)==EXIT_FAILURE) @@ -959,7 +974,7 @@ static char * alloc(unsigned int u) return p; } -static char * expand_string(char *s) +static char * expand_string(char *s, struct system_information *sysinfo) { char buf[1024]; register char *p = s; @@ -986,10 +1001,10 @@ static char * expand_string(char *s) strcpy(q, ackhome); break; case 'M': - strcpy(q, MACHNAME); + strcpy(q, sysinfo->arch); break; case 'S': - strcpy(q, SYSNAME); + strcpy(q, sysinfo->platform); break; default: panic("internal error"); @@ -1018,14 +1033,14 @@ static void append(register struct arglist *al, char *arg) al->al_argv[(al->al_argc)++] = arg; } -static void expand(register struct arglist *al) +static void expand(register struct arglist *al, struct system_information *sysinfo) { register int i = al->al_argc; register char **p = &(al->al_argv[0]); while (i-- > 0) { - *p = expand_string(*p); + *p = expand_string(*p,sysinfo); p++; } } From ef246bd8e22ef6768bd4c613fac6c0f3aea8ec8f Mon Sep 17 00:00:00 2001 From: carl Date: Sun, 16 Jun 2019 00:42:48 +0800 Subject: [PATCH 6/8] Closes #193 (signed integer shift left does not correctly check overflow in the interpreter when shifting by 0 bits), Closes #192 (integer division overflow is not handled in the interpreter and crashes it) and closes #194 (lar instruction does not accept negative bounds in interpreter when doing array index checking). --- util/int/do_array.c | 7 ++++--- util/int/do_intar.c | 39 +++++++++++++++++++++++++++++++++------ util/int/main.c | 23 ++++++++++++++++++++++- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/util/int/do_array.c b/util/int/do_array.c index 62112fbd7..9f850d4c7 100644 --- a/util/int/do_array.c +++ b/util/int/do_array.c @@ -58,12 +58,13 @@ PRIVATE void arr(int type, /* operation TYPE */ { register ptr desc = dppop(); /* array DESCriptor */ register size obj_size; /* OBJect SIZE */ - register long diff = /* between index and lower bound */ - spop(elm_size) - mem_lds(desc, elm_size); + long index = spop(elm_size); + long diff = /* between index and lower bound */ + index - mem_lds(desc, elm_size); register ptr arr_addr = dppop();/* ARRay ADDRess */ if (must_test && !(IgnMask&BIT(EARRAY))) { - if (diff < 0 || diff > mem_lds(desc + elm_size, elm_size)) { + if (diff < 0 || index > mem_lds(desc + elm_size, elm_size)) { trap(EARRAY); } } diff --git a/util/int/do_intar.c b/util/int/do_intar.c index e80f1ee3f..8d0e559ec 100644 --- a/util/int/do_intar.c +++ b/util/int/do_intar.c @@ -14,7 +14,7 @@ #include "text.h" #include "fra.h" -PRIVATE long adi(long, long, size), sbi(long, long, size), dvi(long, long); +PRIVATE long adi(long, long, size), sbi(long, long, size), dvi(long, long, size); PRIVATE long mli(long, long, size), rmi(long, long), ngi(long, size); PRIVATE long sli(long, long, size), sri(long, long, size); @@ -55,7 +55,7 @@ void DoDVI(register size l) LOG(("@I6 DoDVI(%ld)", l)); spoilFRA(); - npush(dvi(spop(l), t), l); + npush(dvi(spop(l), t, l), l); } /** RMI w: Remainder (*) */ @@ -162,7 +162,7 @@ PRIVATE long mli(long w1, long w2, size nbytes) return (w1 * w2); } -PRIVATE long dvi(long w1, long w2) +PRIVATE long dvi(long w1, long w2, size nbytes) { if (w2 == 0) { if (!(IgnMask&BIT(EIDIVZ))) { @@ -170,6 +170,20 @@ PRIVATE long dvi(long w1, long w2) } else return (0L); } + + /* Check for division overflow. */ + if ((w1 == i_mins(nbytes)) && (w2 == -1)) + { + if (must_test && !(IgnMask&BIT(EIOVFL))) + { + trap(EIOVFL); + } else return i_mins(nbytes); + } + + + if (must_test && !(IgnMask&BIT(EIOVFL))) + { + } return (w1 / w2); } @@ -212,11 +226,24 @@ PRIVATE long sli(long w1, long w2, size nbytes) if (!(IgnMask&BIT(EIOVFL))) { /* check overflow */ - if ( (w1 >= 0 && (w1 >> (nbytes*8 - w2)) != 0) - || (w1 < 0 && (w1 >> (nbytes*8 - w2)) != -1) - ) { + + /* If the value is positive, then check, this is taken + * from rule INT32-C of SEI website. + */ + if ((w1 >= 0) && (w1 > (i_maxs(nbytes) >> w2))) + { trap(EIOVFL); } + + if ((w1 < 0) && (w1 < (i_mins(nbytes) >> w2))) + { + trap(EIOVFL); + } + +/* if ((w1 < 0) && (w2 != 0) && ((w1 >> (nbytes*8 - w2)) != -1)) + { + trap(EIOVFL); + }*/ } } diff --git a/util/int/main.c b/util/int/main.c index 05d49e87f..5587a3112 100644 --- a/util/int/main.c +++ b/util/int/main.c @@ -45,15 +45,36 @@ extern void disassemble(void); extern void tally(void); extern void out_tally(void); +/** Check dynamically that the interpreter can run on the target machine. */ +static void check_requirements(char *name) +{ + + /* Verify that shift right supported signed shifts. According to ISO C90, + * this is not mandatory, we should not support it here! + */ + int shrv = -4; + if ((shrv >> 1) != -2) + { + fprintf(stderr, + "%s compiled with compiler that does not support signed right shifts. Aborted.", + name); + exit(1); + } +} + int main(int argc, char *argv[]) { register int i; register int nosetjmp = 1; int must_disassemble = 0; int must_tally = 0; - + + prog_name = argv[0]; + check_requirements(prog_name); + + /* Initialize the EM machine */ PreIgnMask = 0; FRALimit = FRALIMIT; From 55eb19acf8147193eb4d9479cd6ed77bc3f06f2e Mon Sep 17 00:00:00 2001 From: carl Date: Sun, 16 Jun 2019 01:19:15 +0800 Subject: [PATCH 7/8] * Fix merge conflict issue. --- util/arch/archiver.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/util/arch/archiver.c b/util/arch/archiver.c index d4d82b69f..1a0e85afa 100644 --- a/util/arch/archiver.c +++ b/util/arch/archiver.c @@ -588,10 +588,6 @@ void add(char *name, FILE* ar, FILE* dst, char *mess) member.ar_mode = mode2ar(status.st_mode); member.ar_date = status.st_mtime; member.ar_size = status.st_size; -<<<<<<< HEAD ->>>>>>> upstream/default -======= ->>>>>>> upstream/default #ifdef DISTRIBUTION if (distr_fl) { From 0223069d29d1f41eaf30695ad6af8d4e9a91883c Mon Sep 17 00:00:00 2001 From: carl Date: Sun, 16 Jun 2019 01:27:49 +0800 Subject: [PATCH 8/8] Cleanup of modified code fixing several overflow checking issues. --- util/int/do_intar.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/util/int/do_intar.c b/util/int/do_intar.c index 8d0e559ec..df81f5511 100644 --- a/util/int/do_intar.c +++ b/util/int/do_intar.c @@ -181,9 +181,6 @@ PRIVATE long dvi(long w1, long w2, size nbytes) } - if (must_test && !(IgnMask&BIT(EIOVFL))) - { - } return (w1 / w2); } @@ -240,10 +237,6 @@ PRIVATE long sli(long w1, long w2, size nbytes) trap(EIOVFL); } -/* if ((w1 < 0) && (w2 != 0) && ((w1 >> (nbytes*8 - w2)) != -1)) - { - trap(EIOVFL); - }*/ } }