Improve bounds checking

No particular crashes, but replace strcpy / strncpy with snprintf
and GLib functions wherever possible.
This commit is contained in:
Evan Miller
2020-12-28 20:12:39 -05:00
parent 31d8bc13aa
commit 2bb31f05ee
11 changed files with 42 additions and 54 deletions

View File

@@ -60,7 +60,7 @@ int main(int argc, char **argv)
fseek(in,(pg*pg_size),SEEK_SET); fseek(in,(pg*pg_size),SEEK_SET);
i = 0; i = 0;
while ((length = fread(data,1,16,in))) { while ((length = fread(data,1,16,in))) {
sprintf(addr, "%06lx", i); snprintf(addr, sizeof(addr), "%06lx", i);
//if (!strcmp(&addr[3],"000") || (!jet4 && !strcmp(&addr[3],"800")) && //if (!strcmp(&addr[3],"000") || (!jet4 && !strcmp(&addr[3],"800")) &&
//pg) break; //pg) break;
if (!strcmp(&addr[3],"000") || (!jet4 && !strcmp(&addr[3],"800"))) { if (!strcmp(&addr[3],"000") || (!jet4 && !strcmp(&addr[3],"800"))) {

View File

@@ -493,23 +493,18 @@ mdb_get_index_name(int backend, MdbTableDef *table, MdbIndex *idx)
switch(backend){ switch(backend){
case MDB_BACKEND_MYSQL: case MDB_BACKEND_MYSQL:
// appending table name to index often makes it too long for mysql // appending table name to index often makes it too long for mysql
index_name = malloc(strlen(idx->name)+5+1);
if (idx->index_type==1) if (idx->index_type==1)
// for mysql name of primary key is not used // for mysql name of primary key is not used
strcpy(index_name, "_pkey"); index_name = g_strdup("_pkey");
else { else {
strcpy(index_name, idx->name); index_name = g_strdup(idx->name);
} }
break; break;
default: default:
index_name = malloc(strlen(table->name)+strlen(idx->name)+5+1);
strcpy(index_name, table->name);
if (idx->index_type==1) if (idx->index_type==1)
strcat(index_name, "_pkey"); index_name = g_strconcat(table->name, "_pkey", NULL);
else { else {
strcat(index_name, "_"); index_name = g_strconcat(table->name, "_", idx->name, "_idx", NULL);
strcat(index_name, idx->name);
strcat(index_name, "_idx");
} }
} }

View File

@@ -87,7 +87,7 @@ GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
msysobj.mdb = mdb; msysobj.mdb = mdb;
msysobj.object_type = MDB_TABLE; msysobj.object_type = MDB_TABLE;
msysobj.table_pg = 2; msysobj.table_pg = 2;
strcpy(msysobj.object_name, "MSysObjects"); snprintf(msysobj.object_name, sizeof(msysobj.object_name), "%s", "MSysObjects");
/* mdb_table_dump(&msysobj); */ /* mdb_table_dump(&msysobj); */
@@ -125,7 +125,7 @@ GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
// (atol(obj_id) & 0x00FFFFFF), type, type, obj_name); // (atol(obj_id) & 0x00FFFFFF), type, type, obj_name);
entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry)); entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
entry->mdb = mdb; entry->mdb = mdb;
strcpy(entry->object_name, obj_name); snprintf(entry->object_name, sizeof(entry->object_name), "%s", obj_name);
entry->object_type = (type & 0x7F); entry->object_type = (type & 0x7F);
entry->table_pg = atol(obj_id) & 0x00FFFFFF; entry->table_pg = atol(obj_id) & 0x00FFFFFF;
entry->flags = atol(obj_flags); entry->flags = atol(obj_flags);

View File

@@ -188,8 +188,9 @@ mdb_ascii2unicode(MdbHandle *mdb, const char *src, size_t slen, char *dest, size
dlen -= len_out; dlen -= len_out;
#else #else
if (IS_JET3(mdb)) { if (IS_JET3(mdb)) {
dlen = MIN(len_in, len_out); int count;
strncpy(out_ptr, in_ptr, dlen); snprintf(out_ptr, len_out, "%*s%n", (int)len_in, in_ptr, &count);
dlen = count;
} else { } else {
unsigned int i; unsigned int i;
slen = MIN(len_in, len_out/2); slen = MIN(len_in, len_out/2);

View File

@@ -123,9 +123,7 @@ mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len)
dsize = mdb_get_int16(kkd, pos + 6); dsize = mdb_get_int16(kkd, pos + 6);
if (dsize < 0 || pos + 8 + dsize > len) if (dsize < 0 || pos + 8 + dsize > len)
break; break;
value = g_malloc(dsize + 1); value = g_strdup_printf("%*s", dsize, &kkd[pos+8]);
strncpy(value, &kkd[pos + 8], dsize);
value[dsize] = '\0';
name = g_ptr_array_index(names,elem); name = g_ptr_array_index(names,elem);
if (mdb_get_option(MDB_DEBUG_PROPS)) { if (mdb_get_option(MDB_DEBUG_PROPS)) {
fprintf(stderr, "%02d ",i++); fprintf(stderr, "%02d ",i++);

View File

@@ -100,7 +100,7 @@ int mdb_test_int(MdbSargNode *node, gint32 i)
static double poor_mans_trunc(double x) static double poor_mans_trunc(double x)
{ {
char buf[16]; char buf[16];
sprintf(buf, "%.6f", x); snprintf(buf, sizeof(buf), "%.6f", x);
sscanf(buf, "%lf", &x); sscanf(buf, "%lf", &x);
return x; return x;
} }

View File

@@ -34,7 +34,7 @@ MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry)
table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef)); table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef));
table->entry=entry; table->entry=entry;
strcpy(table->name, entry->object_name); snprintf(table->name, sizeof(table->name), "%s", entry->object_name);
return table; return table;
} }

View File

@@ -27,7 +27,7 @@ void
mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed) mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed)
{ {
memset(tcol,0,sizeof(MdbColumn)); memset(tcol,0,sizeof(MdbColumn));
strcpy(tcol->name, col_name); snprintf(tcol->name, sizeof(tcol->name), "%s", col_name);
tcol->col_type = col_type; tcol->col_type = col_type;
if ((col_type == MDB_TEXT) || (col_type == MDB_MEMO)) { if ((col_type == MDB_TEXT) || (col_type == MDB_MEMO)) {
tcol->col_size = col_size; tcol->col_size = col_size;
@@ -57,7 +57,7 @@ mdb_create_temp_table(MdbHandle *mdb, char *name)
entry->mdb = mdb; entry->mdb = mdb;
entry->object_type = MDB_TABLE; entry->object_type = MDB_TABLE;
entry->table_pg = 0; entry->table_pg = 0;
strcpy(entry->object_name, name); snprintf(entry->object_name, sizeof(entry->object_name), "%s", name);
table = mdb_alloc_tabledef(entry); table = mdb_alloc_tabledef(entry);
table->columns = g_ptr_array_new(); table->columns = g_ptr_array_new();

View File

@@ -1228,8 +1228,7 @@ SQLRETURN SQL_API SQLPrepare(
TRACE("SQLPrepare"); TRACE("SQLPrepare");
strncpy(stmt->query, (char*)szSqlStr, sqllen); snprintf(stmt->query, sizeof(stmt->query), "%*s", sqllen, (char*)szSqlStr);
stmt->query[sqllen]='\0';
return SQL_SUCCESS; return SQL_SUCCESS;
} }
@@ -1349,9 +1348,9 @@ SQLRETURN SQL_API SQLColumns(
for (j=0; j<table->num_cols; j++) { for (j=0; j<table->num_cols; j++) {
col = g_ptr_array_index(table->columns, j); col = g_ptr_array_index(table->columns, j);
ts2 = mdb_ascii2unicode(mdb, table->name, 0, (char*)t2, MDB_BIND_SIZE); ts2 = mdb_ascii2unicode(mdb, table->name, 0, (char*)t2, sizeof(t2));
ts3 = mdb_ascii2unicode(mdb, col->name, 0, (char*)t3, MDB_BIND_SIZE); ts3 = mdb_ascii2unicode(mdb, col->name, 0, (char*)t3, sizeof(t3));
ts5 = mdb_ascii2unicode(mdb, _odbc_get_client_type_name(col), 0, (char*)t5, MDB_BIND_SIZE); ts5 = mdb_ascii2unicode(mdb, _odbc_get_client_type_name(col), 0, (char*)t5, sizeof(t5));
nullable = SQL_NO_NULLS; nullable = SQL_NO_NULLS;
datatype = _odbc_get_client_type(col); datatype = _odbc_get_client_type(col);
@@ -1938,15 +1937,15 @@ SQLRETURN SQL_API SQLGetInfo(
break; break;
case SQL_DBMS_NAME: case SQL_DBMS_NAME:
if (rgbInfoValue) if (rgbInfoValue)
strncpy(rgbInfoValue, "MDBTOOLS", cbInfoValueMax); snprintf(rgbInfoValue, cbInfoValueMax, "%s", "MDBTOOLS");
if (pcbInfoValue) if (pcbInfoValue)
*pcbInfoValue = 9; *pcbInfoValue = sizeof("MDBTOOLS");
break; break;
case SQL_DBMS_VER: case SQL_DBMS_VER:
if (rgbInfoValue) if (rgbInfoValue)
strncpy(rgbInfoValue, VERSION, cbInfoValueMax); snprintf(rgbInfoValue, cbInfoValueMax, "%s", VERSION);
if (pcbInfoValue) if (pcbInfoValue)
*pcbInfoValue = sizeof(VERSION)+1; *pcbInfoValue = sizeof(VERSION);
break; break;
default: default:
if (pcbInfoValue) if (pcbInfoValue)
@@ -2039,11 +2038,11 @@ SQLRETURN SQL_API SQLGetTypeInfo(
if (fSqlType && (fSqlType != type_info[i].data_type)) if (fSqlType && (fSqlType != type_info[i].data_type))
continue; continue;
ts0 = mdb_ascii2unicode(mdb, (char*)type_info[i].type_name, 0, (char*)t0, MDB_BIND_SIZE); ts0 = mdb_ascii2unicode(mdb, (char*)type_info[i].type_name, 0, (char*)t0, sizeof(t0));
ts3 = mdb_ascii2unicode(mdb, (char*)type_info[i].literal_prefix, 0, (char*)t3, MDB_BIND_SIZE); ts3 = mdb_ascii2unicode(mdb, (char*)type_info[i].literal_prefix, 0, (char*)t3, sizeof(t3));
ts4 = mdb_ascii2unicode(mdb, (char*)type_info[i].literal_suffix, 0, (char*)t4, MDB_BIND_SIZE); ts4 = mdb_ascii2unicode(mdb, (char*)type_info[i].literal_suffix, 0, (char*)t4, sizeof(t4));
ts5 = mdb_ascii2unicode(mdb, (char*)type_info[i].create_params, 0, (char*)t5, MDB_BIND_SIZE); ts5 = mdb_ascii2unicode(mdb, (char*)type_info[i].create_params, 0, (char*)t5, sizeof(t5));
ts12 = mdb_ascii2unicode(mdb, (char*)type_info[i].local_type_name, 0, (char*)t12, MDB_BIND_SIZE); ts12 = mdb_ascii2unicode(mdb, (char*)type_info[i].local_type_name, 0, (char*)t12, sizeof(t12));
FILL_FIELD(&fields[0], t0, ts0); FILL_FIELD(&fields[0], t0, ts0);
FILL_FIELD(&fields[1],&type_info[i].data_type, 0); FILL_FIELD(&fields[1],&type_info[i].data_type, 0);
@@ -2195,8 +2194,8 @@ SQLRETURN SQL_API SQLTables( //sz* not used, so Unicode API not required.
FILL_FIELD(&fields[j], NULL, 0); FILL_FIELD(&fields[j], NULL, 0);
} }
ts2 = mdb_ascii2unicode(mdb, entry->object_name, 0, (char*)t2, MDB_BIND_SIZE); ts2 = mdb_ascii2unicode(mdb, entry->object_name, 0, (char*)t2, sizeof(t2));
ts3 = mdb_ascii2unicode(mdb, table_types[ttype], 0, (char*)t3, MDB_BIND_SIZE); ts3 = mdb_ascii2unicode(mdb, table_types[ttype], 0, (char*)t3, sizeof(t3));
FILL_FIELD(&fields[2], t2, ts2); FILL_FIELD(&fields[2], t2, ts2);
FILL_FIELD(&fields[3], t3, ts3); FILL_FIELD(&fields[3], t3, ts3);

View File

@@ -408,7 +408,7 @@ mdb_sql_strptime(MdbSQL *sql, char *data, char *format)
if (date < 2 && date > 1) date--; if (date < 2 && date > 1) date--;
if ((pszDate=malloc(16))) { if ((pszDate=malloc(16))) {
char cLocale=localeconv()->decimal_point[0], *p; char cLocale=localeconv()->decimal_point[0], *p;
sprintf(pszDate, "%lf", date); snprintf(pszDate, 16, "%lf", date);
if (cLocale!='.') for (p=pszDate; *p; p++) if (*p==cLocale) *p='.'; if (cLocale!='.') for (p=pszDate; *p; p++) if (*p==cLocale) *p='.';
} }
return pszDate; return pszDate;
@@ -467,7 +467,6 @@ mdb_sql_eval_expr(MdbSQL *sql, char *const1, int op, char *const2)
int int
mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant) mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
{ {
int lastchar;
char *p; char *p;
MdbSargNode *node; MdbSargNode *node;
@@ -485,9 +484,7 @@ mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
** column definition can be checked for validity ** column definition can be checked for validity
*/ */
if (constant[0]=='\'') { if (constant[0]=='\'') {
lastchar = strlen(constant) > 256 ? 256 : strlen(constant); snprintf(node->value.s, sizeof(node->value.s), "%*s", (int)strlen(constant) - 2, &constant[1]);
strncpy(node->value.s, &constant[1], lastchar - 2);;
node->value.s[lastchar - 1]='\0';
node->val_type = MDB_TEXT; node->val_type = MDB_TEXT;
} else if ((p=strchr(constant, '.'))) { } else if ((p=strchr(constant, '.'))) {
*p=localeconv()->decimal_point[0]; *p=localeconv()->decimal_point[0];
@@ -652,7 +649,7 @@ void mdb_sql_listtables(MdbSQL *sql)
entry = g_ptr_array_index (mdb->catalog, i); entry = g_ptr_array_index (mdb->catalog, i);
if (mdb_is_user_table(entry)) { if (mdb_is_user_table(entry)) {
//col = g_ptr_array_index(table->columns,0); //col = g_ptr_array_index(table->columns,0);
tmpsiz = mdb_ascii2unicode(mdb, entry->object_name, 0, tmpstr, 100); tmpsiz = mdb_ascii2unicode(mdb, entry->object_name, 0, tmpstr, sizeof(tmpstr));
mdb_fill_temp_field(&fields[0],tmpstr, tmpsiz, 0,0,0,0); mdb_fill_temp_field(&fields[0],tmpstr, tmpsiz, 0,0,0,0);
row_size = mdb_pack_row(ttable, row_buffer, 1, fields); row_size = mdb_pack_row(ttable, row_buffer, 1, fields);
mdb_add_row_to_pg(ttable,row_buffer, row_size); mdb_add_row_to_pg(ttable,row_buffer, row_size);
@@ -716,15 +713,15 @@ void mdb_sql_describe_table(MdbSQL *sql)
for (i=0;i<table->num_cols;i++) { for (i=0;i<table->num_cols;i++) {
col = g_ptr_array_index(table->columns,i); col = g_ptr_array_index(table->columns,i);
tmpsiz = mdb_ascii2unicode(mdb, col->name, 0, col_name, 100); tmpsiz = mdb_ascii2unicode(mdb, col->name, 0, col_name, sizeof(col_name));
mdb_fill_temp_field(&fields[0],col_name, tmpsiz, 0,0,0,0); mdb_fill_temp_field(&fields[0],col_name, tmpsiz, 0,0,0,0);
strcpy(tmpstr, mdb_get_colbacktype_string(col)); snprintf(tmpstr, sizeof(tmpstr), "%s", mdb_get_colbacktype_string(col));
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, col_type, 100); tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, col_type, sizeof(col_type));
mdb_fill_temp_field(&fields[1],col_type, tmpsiz, 0,0,0,1); mdb_fill_temp_field(&fields[1],col_type, tmpsiz, 0,0,0,1);
sprintf(tmpstr,"%d",col->col_size); snprintf(tmpstr, sizeof(tmpstr), "%d", col->col_size);
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, col_size, 100); tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, col_size, sizeof(col_size));
mdb_fill_temp_field(&fields[2],col_size, tmpsiz, 0,0,0,2); mdb_fill_temp_field(&fields[2],col_size, tmpsiz, 0,0,0,2);
row_size = mdb_pack_row(ttable, row_buffer, 3, fields); row_size = mdb_pack_row(ttable, row_buffer, 3, fields);
@@ -814,8 +811,8 @@ int found = 0;
int row_size, tmpsiz; int row_size, tmpsiz;
mdb_sql_add_temp_col(sql, ttable, 0, "count", MDB_TEXT, 30, 0); mdb_sql_add_temp_col(sql, ttable, 0, "count", MDB_TEXT, 30, 0);
sprintf(tmpstr,"%d",table->num_rows); snprintf(tmpstr, sizeof(tmpstr), "%d", table->num_rows);
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, row_cnt, 32); tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, row_cnt, sizeof(row_cnt));
mdb_fill_temp_field(&fields[0],row_cnt, tmpsiz, 0,0,0,0); mdb_fill_temp_field(&fields[0],row_cnt, tmpsiz, 0,0,0,0);
row_size = mdb_pack_row(ttable, row_buffer, 1, fields); row_size = mdb_pack_row(ttable, row_buffer, 1, fields);
mdb_add_row_to_pg(ttable,row_buffer, row_size); mdb_add_row_to_pg(ttable,row_buffer, row_size);

View File

@@ -78,10 +78,8 @@ int i = 0;
break; break;
} }
} }
buf = (char *) malloc(strlen(line)+1);
strcpy(buf,line);
return buf; return g_strdup(line);
} }
#endif #endif
@@ -425,7 +423,7 @@ main(int argc, char **argv)
} else if (s[strlen(s)-1]=='\n') } else if (s[strlen(s)-1]=='\n')
s[strlen(s)-1]=0; s[strlen(s)-1]=0;
} else { } else {
sprintf(prompt, "%d => ", line); snprintf(prompt, sizeof(prompt), "%d => ", line);
s=readline(prompt); s=readline(prompt);
if (!s) if (!s)
break; break;