From 95310e5823f6852b33b13610250cc24b8e06cf10 Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Wed, 27 May 2020 18:35:18 +0900 Subject: [PATCH] no more strcpy/sprintf (issue #653) --- gc_heap.c | 19 ++++++++++++------- include/chibi/gc_heap.h | 5 ----- lib/chibi/accept.c | 2 +- lib/chibi/disasm.c | 4 ++-- lib/chibi/json.c | 24 ++++++++++++------------ main.c | 11 +++++++---- sexp.c | 6 +++--- tools/chibi-ffi | 2 +- 8 files changed, 38 insertions(+), 35 deletions(-) diff --git a/gc_heap.c b/gc_heap.c index 80382d57..e6e3f4ed 100644 --- a/gc_heap.c +++ b/gc_heap.c @@ -55,7 +55,7 @@ sexp sexp_gc_heap_walk(sexp ctx, return res; } size = sexp_gc_allocated_bytes(ctx, t, t_cnt, p); if (size == 0) { - strcpy(gc_heap_err_str, "Heap element with a zero size detected"); + snprintf(gc_heap_err_str, ERR_STR_SIZE, "Heap element with a zero size detected"); goto done; } } @@ -145,7 +145,7 @@ static sexp sexp_gc_heap_pack_src_to_dst(void* adata, sexp srcp) { imax = imid - 1; } } - strcpy(gc_heap_err_str, "Source SEXP not found in src->dst mapping"); + snprintf(gc_heap_err_str, ERR_STR_SIZE, "Source SEXP not found in src->dst mapping"); return SEXP_FALSE; } @@ -260,7 +260,7 @@ static sexp_heap sexp_gc_packed_heap_make(size_t packed_size, size_t free_size) size_t req_size = packed_size + free_size + sexp_free_chunk_size + 128; sexp_heap heap = sexp_make_heap(sexp_heap_align(req_size), 0, 0); if (!heap) { - strcpy(gc_heap_err_str, "Could not allocate memory for heap"); + snprintf(gc_heap_err_str, ERR_STR_SIZE, "Could not allocate memory for heap"); return NULL; } sexp base = sexp_heap_first_block(heap); @@ -577,7 +577,7 @@ static int load_image_header(FILE *fp, struct sexp_image_header_t* header) { if (!fp || !header) { return 0; } if (fread(header, sizeof(struct sexp_image_header_t), 1, fp) != 1) { - strcpy(gc_heap_err_str, "couldn't read image header"); + snprintf(gc_heap_err_str, ERR_STR_SIZE, "couldn't read image header"); return 0; } if (memcmp(header->magic, SEXP_IMAGE_MAGIC, sizeof(header->magic)) != 0) { @@ -609,7 +609,7 @@ sexp sexp_load_image (const char* filename, off_t offset, sexp_uint_t heap_free_ const char *mod_path, *colon, *end; char path[512]; FILE *fp; - int i; + int i, len; sexp res = NULL, ctx = NULL, base, *ctx_globals, *ctx_types; gc_heap_err_str[0] = 0; @@ -623,9 +623,10 @@ sexp sexp_load_image (const char* filename, off_t offset, sexp_uint_t heap_free_ for (mod_path=all_paths[i]; *mod_path; mod_path=colon+1) { colon = strchr(mod_path, ':'); end = colon ? colon : mod_path + strlen(mod_path); - strncpy(path, mod_path, end-mod_path); + snprintf(path, end-mod_path, "%s", mod_path); if (end[-1] != '/') path[end-mod_path] = '/'; - strcpy(path + (end-mod_path) + (end[-1] == '/' ? 0 : 1), filename); + len = (end-mod_path) + (end[-1] == '/' ? 0 : 1); + snprintf(path + len, sizeof(path) - len, "%s", filename); fp = fopen(path, "rb"); if (fp || !colon) break; } @@ -707,6 +708,9 @@ sexp sexp_load_image (const char* filename, sexp_uint_t heap_free_size, sexp_uin /****************** Debugging ************************/ +/* you can use (chibi heap-stats) without debug enabled */ +#if SEXP_USE_DEBUG_GC + #define SEXP_CORE_TYPES_MAX 255 struct sexp_stats_entry { @@ -780,5 +784,6 @@ void sexp_gc_heap_stats_print(sexp ctx) printf(" ========================================\n"); printf(" %6zu %7zu\n", total_count, total_size); } +#endif #endif /* SEXP_USE_IMAGE_LOADING */ diff --git a/include/chibi/gc_heap.h b/include/chibi/gc_heap.h index bf6e75db..eacf6b2f 100644 --- a/include/chibi/gc_heap.h +++ b/include/chibi/gc_heap.h @@ -94,11 +94,6 @@ SEXP_API sexp sexp_load_image (const char* filename, off_t offset, sexp_uint_t h */ SEXP_API char* sexp_load_image_err(); - -/* Debugging tool. Prints a summary of the heap structure to stdout. - */ -SEXP_API void sexp_gc_heap_stats_print(sexp ctx); - #ifdef __cplusplus } #endif diff --git a/lib/chibi/accept.c b/lib/chibi/accept.c index b3d79d43..b05a6820 100644 --- a/lib/chibi/accept.c +++ b/lib/chibi/accept.c @@ -95,7 +95,7 @@ sexp sexp_sockaddr_name (sexp ctx, sexp self, struct sockaddr* addr) { char buf[INET6_ADDRSTRLEN]; /* struct sockaddr_in *sa = (struct sockaddr_in *)addr; */ /* unsigned char *ptr = (unsigned char *)&(sa->sin_addr); */ - /* sprintf(buf, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]); */ + /* snprintf(buf, INET6_ADDRSTRLEN, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]); */ inet_ntop(addr->sa_family, (addr->sa_family == AF_INET6 ? (void*)(&(((struct sockaddr_in6 *)addr)->sin6_addr)) : diff --git a/lib/chibi/disasm.c b/lib/chibi/disasm.c index 788e368b..d84faf0e 100644 --- a/lib/chibi/disasm.c +++ b/lib/chibi/disasm.c @@ -22,13 +22,13 @@ static void sexp_write_pointer (sexp ctx, void *p, sexp out) { char buf[32]; - sprintf(buf, "%p", p); + snprintf(buf, 32, "%p", p); sexp_write_string(ctx, buf, out); } static void sexp_write_integer (sexp ctx, sexp_sint_t n, sexp out) { char buf[32]; - sprintf(buf, SEXP_PRId, n); + snprintf(buf, 32, SEXP_PRId, n); sexp_write_string(ctx, buf, out); } diff --git a/lib/chibi/json.c b/lib/chibi/json.c index d6d85342..c289f698 100644 --- a/lib/chibi/json.c +++ b/lib/chibi/json.c @@ -370,7 +370,7 @@ sexp unparse_json_flonum(sexp ctx, sexp self, const sexp obj) { return res; } - sprintf(cout, "%.*G", FLONUM_SIGNIFICANT_DIGITS, sexp_flonum_value(obj)); + snprintf(cout, sizeof(cout), "%.*G", FLONUM_SIGNIFICANT_DIGITS, sexp_flonum_value(obj)); res = sexp_c_string(ctx, cout, -1); sexp_gc_release2(ctx); return res; @@ -385,7 +385,7 @@ sexp unparse_json_string(sexp ctx, sexp self, const sexp obj) { tmp = sexp_c_string(ctx, "\"", -1); res = sexp_cons(ctx, tmp, res); - char cout[(2+USEQ_LEN)*2 + 1]; + char cout[32]; /* oversized to avoid snprintf warnings */ unsigned long ch, chh, chl; sexp_uint_t len = sexp_string_length(obj); @@ -394,32 +394,32 @@ sexp unparse_json_string(sexp ctx, sexp self, const sexp obj) { if(ch < 0x7F) { switch(ch) { case '\\': - sprintf(cout, "\\\\"); + snprintf(cout, sizeof(cout), "\\\\"); break; case '/': - sprintf(cout, "\\/"); + snprintf(cout, sizeof(cout), "\\/"); break; case '\b': - sprintf(cout, "\\b"); + snprintf(cout, sizeof(cout), "\\b"); break; case '\f': - sprintf(cout, "\\f"); + snprintf(cout, sizeof(cout), "\\f"); break; case '\n': - sprintf(cout, "\\n"); + snprintf(cout, sizeof(cout), "\\n"); break; case '\r': - sprintf(cout, "\\r"); + snprintf(cout, sizeof(cout), "\\r"); break; case '\t': - sprintf(cout, "\\t"); + snprintf(cout, sizeof(cout), "\\t"); break; default: - sprintf(cout, "%c", (int)ch); + snprintf(cout, sizeof(cout), "%c", (int)ch); break; } } else if(ch <= 0xFFFF) { - sprintf(cout,"\\u%04lX", ch); + snprintf(cout, sizeof(cout), "\\u%04lX", ch); } else { // Surrogate pair chh = (0xD800 - (0x10000 >> 10) + ((ch) >> 10)); @@ -429,7 +429,7 @@ sexp unparse_json_string(sexp ctx, sexp self, const sexp obj) { sexp_gc_release2(ctx); return res; } - sprintf(cout, "\\u%04lX\\u%04lX", chh, chl); + snprintf(cout, sizeof(cout), "\\u%04lX\\u%04lX", chh, chl); } tmp = sexp_c_string(ctx, cout, -1); res = sexp_cons(ctx, tmp, res); diff --git a/main.c b/main.c index 47d03fc6..6d2dcc0a 100644 --- a/main.c +++ b/main.c @@ -182,14 +182,17 @@ static sexp_uint_t multiplier (char c) { #endif static char* make_import(const char* prefix, const char* mod, const char* suffix) { - int preflen = strlen(prefix), len = preflen + strlen(mod) + strlen(suffix); + int preflen = strlen(prefix), modlen = strlen(mod); + int len = preflen + modlen + strlen(suffix); + int suflen = strlen(suffix) + (mod[0] == '(' ? 1 : 0); char *p, *impmod = (char*) malloc(len+1); - strcpy(impmod, prefix); - strcpy(impmod+preflen, mod[0] == '(' ? mod + 1 : mod); - strcpy(impmod+len-strlen(suffix)-(mod[0] == '(' ? 1 : 0), suffix); + snprintf(impmod, len, "%s", prefix); + snprintf(impmod+preflen, len-preflen, "%s", mod[0] == '(' ? mod + 1 : mod); + snprintf(impmod+len-suflen, suflen+1, "%s", suffix); impmod[len] = '\0'; for (p=impmod; *p; p++) if (*p == '.') *p=' '; + /* fprintf(stderr, "make_import => %s\n", impmod); */ return impmod; } diff --git a/sexp.c b/sexp.c index 5ce4eb68..c4510b3a 100644 --- a/sexp.c +++ b/sexp.c @@ -2138,7 +2138,7 @@ sexp sexp_write_one (sexp ctx, sexp obj, sexp out, sexp_sint_t bound) { #if SEXP_USE_INFINITIES if (isinf(f) || isnan(f)) { numbuf[0] = (isinf(f) && f < 0 ? '-' : '+'); - strcpy(numbuf+1, isinf(f) ? "inf.0" : "nan.0"); + strncpy(numbuf+1, isinf(f) ? "inf.0" : "nan.0", NUMBUF_LEN-1); } else #endif { @@ -2279,7 +2279,7 @@ sexp sexp_write_one (sexp ctx, sexp obj, sexp out, sexp_sint_t bound) { if (i!=0) sexp_write_char(ctx, ' ', out); #if SEXP_BYTEVECTOR_HEX_LITERALS if (str[i]) { - sprintf(buf, "#x%02hhX", ((unsigned char*) str)[i]); + snprintf(buf, 5, "#x%02hhX", ((unsigned char*) str)[i]); sexp_write_string(ctx, buf, out); } else { sexp_write_char (ctx, '0', out); @@ -2342,7 +2342,7 @@ sexp sexp_write_one (sexp ctx, sexp obj, sexp out, sexp_sint_t bound) { #if SEXP_USE_INFINITIES if (isinf(f) || isnan(f)) { numbuf[0] = (isinf(f) && f < 0 ? '-' : '+'); - strcpy(numbuf+1, isinf(f) ? "inf.0" : "nan.0"); + strncpy(numbuf+1, isinf(f) ? "inf.0" : "nan.0", NUMBUF_LEN-1); } else #endif { diff --git a/tools/chibi-ffi b/tools/chibi-ffi index 38eaea4d..e1e7ffa4 100755 --- a/tools/chibi-ffi +++ b/tools/chibi-ffi @@ -631,7 +631,7 @@ errnos) " } - sprintf(buf, \"unknown error: %d\", err); + snprintf(buf, 64, \"unknown error: %d\", err); return buf; }")))))))