From 100f94be99ef06fb168850da528492b00e7520dc Mon Sep 17 00:00:00 2001 From: "Avi Halachmi (:avih)" Date: Sun, 12 Jun 2016 14:51:29 +0300 Subject: [PATCH] tiny_libmaker: more robust arguments interpretation - Syntax is now much closer to gnu ar, but still supports whatever was supported before, with the following exceptions (which gnu ar has too): - lib is now mandatory (was optional and defaulted to ar_test.a before). - Path cannot start with '-' (but ./-myfile.o is OK). - Unlike gnu ar, modes are still optional (as before). - Now supports also (like gnu ar): - First argument as options doesn't have to start with '-', later options do. - Now supports mode v (verbose) with same output format as gnu ar. - Any names for lib/objs (were limited to .a/.o - broke cmake on windows). - Now explicitly fail on options which would be destructive for the user. - Now doesn't get confused by options between file arguments. - Still ignores other unknown options - as before. - Now doesn't read out-of-bounds if an option is one char. - As a result, cmake for windows can now use tiny_libmaker as ar, and configure can also detect tiny_libmaker as a valid ar (both couldn't before). Ignoring all options could previously cause to misinterpret the mode in a destructive way, e.g. if the user wanted to do something with an existing archive (such as p - print, or x - extract, etc), then it would instead just delete (re-create) the archive. Modes which can be destructive if ignored now explicitly fail. These include [habdioptxN]. Note that 'h' can be ignored, but this way we also implicitly print the usage for -h/--help. The .a/.o name limitations previously resulted in complete failure on some cases, such as cmake on windows which uses .obj and .lib . Fixed: e.g. 'tiny_libmaker r x.a x.o' was reading out of bounds [-1] for 'r'. --- win32/tools/tiny_libmaker.c | 88 +++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/win32/tools/tiny_libmaker.c b/win32/tools/tiny_libmaker.c index 62d2a2e..e8580bb 100644 --- a/win32/tools/tiny_libmaker.c +++ b/win32/tools/tiny_libmaker.c @@ -71,50 +71,69 @@ ArHdr arhdro = { ARFMAG }; +/* Returns 1 if s contains any of the chars of list, else 0 */ +int contains_any(const char *s, const char *list) { + const char *l; + for (; *s; s++) { + for (l = list; *l; l++) { + if (*s == *l) + return 1; + } + } + return 0; +} + +int usage(int ret) { + fprintf(stderr, "usage: tiny_libmaker [rcsv] lib file...\n"); + fprintf(stderr, "Always creates a new lib. [abdioptxN] are explicitly rejected.\n"); + return ret; +} + int main(int argc, char **argv) { FILE *fi, *fh = NULL, *fo = NULL; ElfW(Ehdr) *ehdr; ElfW(Shdr) *shdr; ElfW(Sym) *sym; - int i, fsize, iarg; + int i, fsize, i_lib, i_obj; char *buf, *shstr, *symtab = NULL, *strtab = NULL; int symtabsize = 0;//, strtabsize = 0; char *anames = NULL; int *afpos = NULL; int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs; - char afile[260], tfile[260], stmp[20]; + char tfile[260], stmp[20]; char *file, *name; int ret = 2; + char *ops_conflict = "habdioptxN"; // unsupported but destructive if ignored. + int verbose = 0; - - strcpy(afile, "ar_test.a"); - iarg = 1; - - if (argc < 2) - { - printf("usage: tiny_libmaker [lib] file...\n"); - return 1; - } - for (i=1; ie_ident[4] != ELFCLASSW) { - fprintf(stderr, "Unsupported Elf Class: %s\n", argv[iarg]); + fprintf(stderr, "Unsupported Elf Class: %s\n", argv[i_obj]); goto the_end; } @@ -202,7 +222,7 @@ int main(int argc, char **argv) } } - file = argv[iarg]; + file = argv[i_obj]; for (name = strchr(file, 0); name > file && name[-1] != '/' && name[-1] != '\\'; --name); @@ -217,7 +237,7 @@ int main(int argc, char **argv) fwrite(&arhdro, sizeof(arhdro), 1, fo); fwrite(buf, fsize, 1, fo); free(buf); - iarg++; + i_obj++; fpos += (fsize + sizeof(arhdro)); } hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);