shithub: scc

Download patch

ref: 4ec73213a7ed78026a99ce4d4890529340b84839
parent: 1719ff6c9904838f3c270913c45bbf140b33089c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Nov 24 16:16:19 EST 2017

[nm] Load strings into memory

--- a/nm/main.c
+++ b/nm/main.c
@@ -59,7 +59,8 @@
 nm(char *fname, char *member, FILE *fp)
 {
 	struct myrohdr hdr;
-	struct myrosym *syms;
+	struct myrosym *syms = NULL;
+	char *strings = NULL;
 	size_t n, i;
 	long off;
 
@@ -67,47 +68,46 @@
 		fprintf(stderr, "nm: %s: incorrect header\n", member);
 		return;
 	}
-	if ((off = ftell(fp)) < 0)
-		return;
 
-	if (hdr.symsize / MYROSYM_SIZ > SIZE_MAX)
-		goto too_big;
-
 	n = hdr.symsize / MYROSYM_SIZ;
 	if (n == 0) {
 		fprintf(stderr, "nm: %s: no name list\n", member);
 		return;
 	}
-
-	if (n > SIZE_MAX / sizeof(struct myrosym))
-		goto too_big;
-	if (off > LONG_MAX - hdr.strsize)
+	if (n > SIZE_MAX / sizeof(struct myrosym) ||
+	    hdr.symsize / MYROSYM_SIZ > SIZE_MAX ||
+	    hdr.strsize > SIZE_MAX) {
 		goto offset_overflow;
-	off += hdr.strsize;
+	}
+
+	syms = xmalloc(n * sizeof(struct myrosym));
+	strings = xmalloc(hdr.strsize);
+	fread(strings, hdr.strsize, 1, fp);
+	if (feof(fp))
+		goto free_arrays;
+	if ((off = ftell(fp)) < 0)
+		return;
 	if (off > LONG_MAX - hdr.secsize)
 		goto offset_overflow;
 	off += hdr.secsize;
 
 	if (fseek(fp, off, SEEK_SET) < 0)
-		return;
+		goto free_arrays;
 
-	syms = xmalloc(n * sizeof(struct myrosym));
 	for (i = 0; n--; ++i) {
 		if (rdmyrosym(fp, &syms[i]) < 0)
-			return;
+			goto free_arrays;
 	}
-	free(syms);
 
+free_arrays:
+	free(syms);
+	free(strings);
 	return;
 
 offset_overflow:
 	fprintf(stderr, "nm: %s: overflow in headers of archive\n",
 		fname);
-	return;
-
-too_big:
-	fprintf(stderr, "nm: %s: too big symbol table\n", member);
-	return;
+	goto free_arrays;
 }
 
 static void