Properly terminate a snprintf() call.

snprintf() copies at most N characters, but the string may not be
terminated correctly. This patch uses sizeof() so that the snprintf()
call matches the size of the buffer and adds code to insert a NULL as
the last character of the string.
This commit is contained in:
Cary R 2011-05-02 09:09:22 -07:00 committed by Stephen Williams
parent c2225f679b
commit e85c43c232
9 changed files with 59 additions and 38 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2010 Cary R. (cygcary@yahoo.com)
* Copyright (C) 2008-2011 Cary R. (cygcary@yahoo.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -87,12 +87,13 @@ static PLI_INT32 sys_clog2_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
/* We can have a maximum of one argument. */
if (vpi_scan(argv) != 0) {
char msg [64];
char msg[64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s:%d:",
snprintf(msg, sizeof(msg), "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
argc = 1;
while (vpi_scan(argv)) argc += 1;

View File

@ -414,10 +414,11 @@ static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* $dumpfile must be called before $dumpvars starts! */
if (dumpvars_status != 0) {
char msg [64];
snprintf(msg, 64, "FST warning: %s:%d:",
char msg[64];
snprintf(msg, sizeof(msg), "FST warning: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s %s called after $dumpvars started,\n", msg, name);
vpi_printf("%*s using existing file (%s).\n",
(int) strlen(msg), " ", dump_path);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -469,10 +469,11 @@ static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* $dumpfile must be called before $dumpvars starts! */
if (dumpvars_status != 0) {
char msg [64];
snprintf(msg, 64, "LXT warning: %s:%d:",
char msg[64];
snprintf(msg, sizeof(msg), "LXT warning: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s %s called after $dumpvars started,\n", msg, name);
vpi_printf("%*s using existing file (%s).\n",
(int) strlen(msg), " ", dump_path);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -525,10 +525,11 @@ static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* $dumpfile must be called before $dumpvars starts! */
if (dumpvars_status != 0) {
char msg [64];
snprintf(msg, 64, "LXT2 warning: %s:%d:",
char msg[64];
snprintf(msg, sizeof(msg), "LXT2 warning: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s %s called after $dumpvars started,\n", msg, name);
vpi_printf("%*s using existing file (%s).\n",
(int) strlen(msg), " ", dump_path);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -133,7 +133,7 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
s_vpi_vlog_info info;
s_vpi_value fmt;
s_vpi_value res;
char msg [64];
char msg[64];
char*cp;
int idx;
int flag = 0;
@ -148,9 +148,10 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* Check for the start of a format string. */
cp = strchr(fmt.value.str, '%');
if (cp == 0) {
snprintf(msg, 64, "ERROR: %s:%d:",
snprintf(msg, sizeof(msg), "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s %s is missing a format code.\n", msg, name);
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", fmt.value.str);
@ -187,9 +188,10 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
case 'S':
break;
default:
snprintf(msg, 64, "ERROR: %s:%d:",
snprintf(msg, sizeof(msg), "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s %s has an invalid format string:\n", msg, name);
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", fmt.value.str);
@ -199,9 +201,10 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* Warn if there is any trailing garbage. */
if (*(cp+1) != '\0') {
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s Skipping trailing garbage in %s's format string:\n",
msg, name);
@ -244,9 +247,10 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
*sp == '_' ||
((tp = strrchr(sp, '-')) && tp != sp)) {
res.value.str = "x";
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s Invalid decimal value passed to %s:\n",
msg, name);
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp);
@ -263,9 +267,10 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
if (sp_len != strspn(sp, "-01234567_xXzZ") ||
*sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) {
res.value.str = "x";
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s Invalid octal value passed to %s:\n",
msg, name);
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp);
@ -284,9 +289,10 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
if (sp_len != strspn(sp, "-0123456789aAbBcCdDeEfF_xXzZ") ||
*sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) {
res.value.str = "x";
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s Invalid hex value passed to %s:\n",
msg, name);
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp);
@ -303,9 +309,10 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
if (sp_len != strspn(sp, "-01_xXzZ") ||
*sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) {
res.value.str = "x";
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s Invalid binary value passed to %s:\n",
msg, name);
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp);
@ -325,18 +332,20 @@ static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
if (*end) {
/* We had an invalid value passed. */
if (end == sp) {
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s Invalid real value passed to "
"%s:\n", msg, name);
vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ",
sp);
/* We have extra garbage at the end. */
} else {
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s Extra character(s) \"%s\" found "
"in %s's real string:\n",
msg, end, name);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -86,11 +86,12 @@ char *get_filename(vpiHandle callh, const char *name, vpiHandle file)
len = strlen(val.value.str);
for (idx = 0; idx < len; idx++) {
if (! isprint((int)val.value.str[idx])) {
char msg [64];
char msg[64];
char *esc_fname = as_escaped(val.value.str);
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s %s's file name argument contains non-"
"printable characters.\n", msg, name);
vpi_printf("%*s \"%s\"\n", (int) strlen(msg), " ", esc_fname);
@ -107,12 +108,13 @@ void check_for_extra_args(vpiHandle argv, vpiHandle callh, const char *name,
{
/* Check that there are no extra arguments. */
if (vpi_scan(argv) != 0) {
char msg [64];
char msg[64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s:%d:",
snprintf(msg, sizeof(msg), "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
argc = 1;
while (vpi_scan(argv)) argc += 1;
@ -242,12 +244,13 @@ PLI_INT32 sys_no_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
/* Make sure there are no arguments. */
if (argv != 0) {
char msg [64];
char msg[64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s:%d:",
snprintf(msg, sizeof(msg), "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
argc = 0;
while (vpi_scan(argv)) argc += 1;

View File

@ -304,7 +304,9 @@ static PLI_INT32 sys_readmem_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
char path[4096];
for (idx = 0; idx < sl_count; idx += 1) {
snprintf(path, 4096, "%s/%s", search_list[idx], fname);
snprintf(path, sizeof(path), "%s/%s",
search_list[idx], fname);
path[sizeof(path)-1] = 0;
if ((file = fopen(path, "r"))) break;
}
}
@ -449,11 +451,12 @@ static PLI_INT32 sys_readmempath_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
len = strlen(val.value.str);
for (idx = 0; idx < len; idx++) {
if (! isprint((int)val.value.str[idx])) {
char msg [64];
char msg[64];
char *esc_path = as_escaped(val.value.str);
snprintf(msg, 64, "WARNING: %s:%d:",
snprintf(msg, sizeof(msg), "WARNING: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s %s's argument contains non-printable "
"characters.\n", msg, name);
vpi_printf("%*s \"%s\"\n", (int) strlen(msg), " ", esc_path);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -445,10 +445,11 @@ static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
/* $dumpfile must be called before $dumpvars starts! */
if (dumpvars_status != 0) {
char msg [64];
snprintf(msg, 64, "VCD warning: %s:%d:",
char msg[64];
snprintf(msg, sizeof(msg), "VCD warning: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
vpi_printf("%s %s called after $dumpvars started,\n", msg, name);
vpi_printf("%*s using existing file (%s).\n",
(int) strlen(msg), " ", dump_path);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2010 Cary R. (cygcary@yahoo.com)
* Copyright (C) 2008-2011 Cary R. (cygcary@yahoo.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -84,12 +84,13 @@ static PLI_INT32 simparam_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name_ext)
/* We can have a maximum of two arguments. */
if (vpi_scan(argv) != 0) {
char msg [64];
char msg[64];
unsigned argc;
snprintf(msg, 64, "ERROR: %s:%d:",
snprintf(msg, sizeof(msg), "ERROR: %s:%d:",
vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
msg[sizeof(msg)-1] = 0;
argc = 1;
while (vpi_scan(argv)) argc += 1;