no more strcpy/sprintf (issue #653)

This commit is contained in:
Alex Shinn 2020-05-27 18:35:18 +09:00
parent 255ee079e5
commit 95310e5823
8 changed files with 38 additions and 35 deletions

View file

@ -55,7 +55,7 @@ sexp sexp_gc_heap_walk(sexp ctx,
return res; } return res; }
size = sexp_gc_allocated_bytes(ctx, t, t_cnt, p); size = sexp_gc_allocated_bytes(ctx, t, t_cnt, p);
if (size == 0) { 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; goto done;
} }
} }
@ -145,7 +145,7 @@ static sexp sexp_gc_heap_pack_src_to_dst(void* adata, sexp srcp) {
imax = imid - 1; 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; 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; 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); sexp_heap heap = sexp_make_heap(sexp_heap_align(req_size), 0, 0);
if (!heap) { 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; return NULL;
} }
sexp base = sexp_heap_first_block(heap); 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 (!fp || !header) { return 0; }
if (fread(header, sizeof(struct sexp_image_header_t), 1, fp) != 1) { 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; return 0;
} }
if (memcmp(header->magic, SEXP_IMAGE_MAGIC, sizeof(header->magic)) != 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; const char *mod_path, *colon, *end;
char path[512]; char path[512];
FILE *fp; FILE *fp;
int i; int i, len;
sexp res = NULL, ctx = NULL, base, *ctx_globals, *ctx_types; sexp res = NULL, ctx = NULL, base, *ctx_globals, *ctx_types;
gc_heap_err_str[0] = 0; 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) { for (mod_path=all_paths[i]; *mod_path; mod_path=colon+1) {
colon = strchr(mod_path, ':'); colon = strchr(mod_path, ':');
end = colon ? colon : mod_path + strlen(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] = '/'; 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"); fp = fopen(path, "rb");
if (fp || !colon) break; if (fp || !colon) break;
} }
@ -707,6 +708,9 @@ sexp sexp_load_image (const char* filename, sexp_uint_t heap_free_size, sexp_uin
/****************** Debugging ************************/ /****************** Debugging ************************/
/* you can use (chibi heap-stats) without debug enabled */
#if SEXP_USE_DEBUG_GC
#define SEXP_CORE_TYPES_MAX 255 #define SEXP_CORE_TYPES_MAX 255
struct sexp_stats_entry { struct sexp_stats_entry {
@ -780,5 +784,6 @@ void sexp_gc_heap_stats_print(sexp ctx)
printf(" ========================================\n"); printf(" ========================================\n");
printf(" %6zu %7zu\n", total_count, total_size); printf(" %6zu %7zu\n", total_count, total_size);
} }
#endif
#endif /* SEXP_USE_IMAGE_LOADING */ #endif /* SEXP_USE_IMAGE_LOADING */

View file

@ -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(); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -95,7 +95,7 @@ sexp sexp_sockaddr_name (sexp ctx, sexp self, struct sockaddr* addr) {
char buf[INET6_ADDRSTRLEN]; char buf[INET6_ADDRSTRLEN];
/* struct sockaddr_in *sa = (struct sockaddr_in *)addr; */ /* struct sockaddr_in *sa = (struct sockaddr_in *)addr; */
/* unsigned char *ptr = (unsigned char *)&(sa->sin_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, inet_ntop(addr->sa_family,
(addr->sa_family == AF_INET6 ? (addr->sa_family == AF_INET6 ?
(void*)(&(((struct sockaddr_in6 *)addr)->sin6_addr)) : (void*)(&(((struct sockaddr_in6 *)addr)->sin6_addr)) :

View file

@ -22,13 +22,13 @@
static void sexp_write_pointer (sexp ctx, void *p, sexp out) { static void sexp_write_pointer (sexp ctx, void *p, sexp out) {
char buf[32]; char buf[32];
sprintf(buf, "%p", p); snprintf(buf, 32, "%p", p);
sexp_write_string(ctx, buf, out); sexp_write_string(ctx, buf, out);
} }
static void sexp_write_integer (sexp ctx, sexp_sint_t n, sexp out) { static void sexp_write_integer (sexp ctx, sexp_sint_t n, sexp out) {
char buf[32]; char buf[32];
sprintf(buf, SEXP_PRId, n); snprintf(buf, 32, SEXP_PRId, n);
sexp_write_string(ctx, buf, out); sexp_write_string(ctx, buf, out);
} }

View file

@ -370,7 +370,7 @@ sexp unparse_json_flonum(sexp ctx, sexp self, const sexp obj) {
return res; 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); res = sexp_c_string(ctx, cout, -1);
sexp_gc_release2(ctx); sexp_gc_release2(ctx);
return res; return res;
@ -385,7 +385,7 @@ sexp unparse_json_string(sexp ctx, sexp self, const sexp obj) {
tmp = sexp_c_string(ctx, "\"", -1); tmp = sexp_c_string(ctx, "\"", -1);
res = sexp_cons(ctx, tmp, res); 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; unsigned long ch, chh, chl;
sexp_uint_t len = sexp_string_length(obj); 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) { if(ch < 0x7F) {
switch(ch) { switch(ch) {
case '\\': case '\\':
sprintf(cout, "\\\\"); snprintf(cout, sizeof(cout), "\\\\");
break; break;
case '/': case '/':
sprintf(cout, "\\/"); snprintf(cout, sizeof(cout), "\\/");
break; break;
case '\b': case '\b':
sprintf(cout, "\\b"); snprintf(cout, sizeof(cout), "\\b");
break; break;
case '\f': case '\f':
sprintf(cout, "\\f"); snprintf(cout, sizeof(cout), "\\f");
break; break;
case '\n': case '\n':
sprintf(cout, "\\n"); snprintf(cout, sizeof(cout), "\\n");
break; break;
case '\r': case '\r':
sprintf(cout, "\\r"); snprintf(cout, sizeof(cout), "\\r");
break; break;
case '\t': case '\t':
sprintf(cout, "\\t"); snprintf(cout, sizeof(cout), "\\t");
break; break;
default: default:
sprintf(cout, "%c", (int)ch); snprintf(cout, sizeof(cout), "%c", (int)ch);
break; break;
} }
} else if(ch <= 0xFFFF) { } else if(ch <= 0xFFFF) {
sprintf(cout,"\\u%04lX", ch); snprintf(cout, sizeof(cout), "\\u%04lX", ch);
} else { } else {
// Surrogate pair // Surrogate pair
chh = (0xD800 - (0x10000 >> 10) + ((ch) >> 10)); 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); sexp_gc_release2(ctx);
return res; 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); tmp = sexp_c_string(ctx, cout, -1);
res = sexp_cons(ctx, tmp, res); res = sexp_cons(ctx, tmp, res);

11
main.c
View file

@ -182,14 +182,17 @@ static sexp_uint_t multiplier (char c) {
#endif #endif
static char* make_import(const char* prefix, const char* mod, const char* suffix) { 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); char *p, *impmod = (char*) malloc(len+1);
strcpy(impmod, prefix); snprintf(impmod, len, "%s", prefix);
strcpy(impmod+preflen, mod[0] == '(' ? mod + 1 : mod); snprintf(impmod+preflen, len-preflen, "%s", mod[0] == '(' ? mod + 1 : mod);
strcpy(impmod+len-strlen(suffix)-(mod[0] == '(' ? 1 : 0), suffix); snprintf(impmod+len-suflen, suflen+1, "%s", suffix);
impmod[len] = '\0'; impmod[len] = '\0';
for (p=impmod; *p; p++) for (p=impmod; *p; p++)
if (*p == '.') *p=' '; if (*p == '.') *p=' ';
/* fprintf(stderr, "make_import => %s\n", impmod); */
return impmod; return impmod;
} }

6
sexp.c
View file

@ -2138,7 +2138,7 @@ sexp sexp_write_one (sexp ctx, sexp obj, sexp out, sexp_sint_t bound) {
#if SEXP_USE_INFINITIES #if SEXP_USE_INFINITIES
if (isinf(f) || isnan(f)) { if (isinf(f) || isnan(f)) {
numbuf[0] = (isinf(f) && f < 0 ? '-' : '+'); 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 } else
#endif #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 (i!=0) sexp_write_char(ctx, ' ', out);
#if SEXP_BYTEVECTOR_HEX_LITERALS #if SEXP_BYTEVECTOR_HEX_LITERALS
if (str[i]) { 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); sexp_write_string(ctx, buf, out);
} else { } else {
sexp_write_char (ctx, '0', out); 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 SEXP_USE_INFINITIES
if (isinf(f) || isnan(f)) { if (isinf(f) || isnan(f)) {
numbuf[0] = (isinf(f) && f < 0 ? '-' : '+'); 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 } else
#endif #endif
{ {

View file

@ -631,7 +631,7 @@
errnos) errnos)
" } " }
sprintf(buf, \"unknown error: %d\", err); snprintf(buf, 64, \"unknown error: %d\", err);
return buf; return buf;
}"))))))) }")))))))