Fix undefined behavior in vs_format_ascii (#1446)

This commit is contained in:
Jacqueline Deans 2023-02-07 13:11:51 -06:00 committed by GitHub
parent a48b39bfc1
commit fb25ea70d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 25 deletions

View File

@ -251,6 +251,12 @@ TEST_F (VariableServerTest, AddRemove) {
expected = std::string("0 -1234"); expected = std::string("0 -1234");
EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0); EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0);
socket << "trick.var_add(\"vsx.vst.n\")\n";
socket >> reply;
expected = std::string("0 -1234 0,1,2,3,4");
EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0);
} }
TEST_F (VariableServerTest, BadRefResponse) { TEST_F (VariableServerTest, BadRefResponse) {

View File

@ -33,42 +33,44 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
// handle returning an array // handle returning an array
int size = 0 ; int size = 0 ;
value[0] = '\0' ; value[0] = '\0' ;
// data to send was copied to buffer in copy_sim_data // data to send was copied to buffer in copy_sim_data
void * buf_ptr = var->buffer_out ; void * buf_ptr = var->buffer_out ;
while (size < var->size) { while (size < var->size) {
size += var->ref->attr->size ; size += var->ref->attr->size ;
char temp_buf[MAX_VAL_STRLEN];
switch (ref->attr->type) { switch (ref->attr->type) {
case TRICK_CHARACTER: case TRICK_CHARACTER:
if (ref->attr->num_index == ref->num_index) { if (ref->attr->num_index == ref->num_index) {
snprintf(value, value_size, "%s%d", value,(char)cv_convert_double(var->conversion_factor, *(char *)buf_ptr)); snprintf(temp_buf, value_size, "%d",(char)cv_convert_double(var->conversion_factor, *(char *)buf_ptr));
} else { } else {
/* All but last dim specified, leaves a char array */ /* All but last dim specified, leaves a char array */
escape_str((char *) buf_ptr, value); escape_str((char *) buf_ptr, temp_buf);
size = var->size ; size = var->size ;
} }
break; break;
case TRICK_UNSIGNED_CHARACTER: case TRICK_UNSIGNED_CHARACTER:
if (ref->attr->num_index == ref->num_index) { if (ref->attr->num_index == ref->num_index) {
snprintf(value, value_size, "%s%u", value,(unsigned char)cv_convert_double(var->conversion_factor,*(unsigned char *)buf_ptr)); snprintf(temp_buf, value_size, "%u",(unsigned char)cv_convert_double(var->conversion_factor,*(unsigned char *)buf_ptr));
} else { } else {
/* All but last dim specified, leaves a char array */ /* All but last dim specified, leaves a char array */
escape_str((char *) buf_ptr, value); escape_str((char *) buf_ptr, temp_buf);
size = var->size ; size = var->size ;
} }
break; break;
case TRICK_WCHAR:{ case TRICK_WCHAR:{
if (ref->attr->num_index == ref->num_index) { if (ref->attr->num_index == ref->num_index) {
snprintf(value, value_size, "%s%d", value,*(wchar_t *) buf_ptr); snprintf(temp_buf, value_size, "%d",*(wchar_t *) buf_ptr);
} else { } else {
// convert wide char string char string // convert wide char string char string
size_t len = wcs_to_ncs_len((wchar_t *)buf_ptr) + 1 ; size_t len = wcs_to_ncs_len((wchar_t *)buf_ptr) + 1 ;
if (len > MAX_VAL_STRLEN) { if (len > MAX_VAL_STRLEN) {
return (-1); return (-1);
} }
wcs_to_ncs((wchar_t *) buf_ptr, value, len); wcs_to_ncs((wchar_t *) buf_ptr, temp_buf, len);
size = var->size ; size = var->size ;
} }
} }
@ -76,10 +78,10 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
case TRICK_STRING: case TRICK_STRING:
if ((char *) buf_ptr != NULL) { if ((char *) buf_ptr != NULL) {
escape_str((char *) buf_ptr, value); escape_str((char *) buf_ptr, temp_buf);
size = var->size ; size = var->size ;
} else { } else {
value[0] = '\0'; temp_buf[0] = '\0';
} }
break; break;
@ -90,25 +92,25 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
if (len > MAX_VAL_STRLEN) { if (len > MAX_VAL_STRLEN) {
return (-1); return (-1);
} }
wcs_to_ncs((wchar_t *) buf_ptr, value, len); wcs_to_ncs((wchar_t *) buf_ptr, temp_buf, len);
size = var->size ; size = var->size ;
} else { } else {
value[0] = '\0'; temp_buf[0] = '\0';
} }
break; break;
#if ( __linux | __sgi ) #if ( __linux | __sgi )
case TRICK_BOOLEAN: case TRICK_BOOLEAN:
snprintf(value, value_size, "%s%d", value,(unsigned char)cv_convert_double(var->conversion_factor,*(unsigned char *)buf_ptr)); snprintf(temp_buf, value_size, "%d",(unsigned char)cv_convert_double(var->conversion_factor,*(unsigned char *)buf_ptr));
break; break;
#endif #endif
case TRICK_SHORT: case TRICK_SHORT:
snprintf(value, value_size, "%s%d", value, (short)cv_convert_double(var->conversion_factor,*(short *)buf_ptr)); snprintf(temp_buf, value_size, "%d", (short)cv_convert_double(var->conversion_factor,*(short *)buf_ptr));
break; break;
case TRICK_UNSIGNED_SHORT: case TRICK_UNSIGNED_SHORT:
snprintf(value, value_size, "%s%u", value,(unsigned short)cv_convert_double(var->conversion_factor,*(unsigned short *)buf_ptr)); snprintf(temp_buf, value_size, "%u",(unsigned short)cv_convert_double(var->conversion_factor,*(unsigned short *)buf_ptr));
break; break;
case TRICK_INTEGER: case TRICK_INTEGER:
@ -116,18 +118,18 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
#if ( __sun | __APPLE__ ) #if ( __sun | __APPLE__ )
case TRICK_BOOLEAN: case TRICK_BOOLEAN:
#endif #endif
snprintf(value, value_size, "%s%d", value, (int)cv_convert_double(var->conversion_factor,*(int *)buf_ptr)); snprintf(temp_buf, value_size, "%d", (int)cv_convert_double(var->conversion_factor,*(int *)buf_ptr));
break; break;
case TRICK_BITFIELD: case TRICK_BITFIELD:
snprintf(value, value_size, "%d", GET_BITFIELD(buf_ptr, ref->attr->size, ref->attr->index[0].start, ref->attr->index[0].size)); snprintf(temp_buf, value_size, "%d", GET_BITFIELD(buf_ptr, ref->attr->size, ref->attr->index[0].start, ref->attr->index[0].size));
break; break;
case TRICK_UNSIGNED_BITFIELD: case TRICK_UNSIGNED_BITFIELD:
snprintf(value, value_size, "%u", GET_UNSIGNED_BITFIELD(buf_ptr, ref->attr->size, ref->attr->index[0].start, ref->attr->index[0].size)); snprintf(temp_buf, value_size, "%u", GET_UNSIGNED_BITFIELD(buf_ptr, ref->attr->size, ref->attr->index[0].start, ref->attr->index[0].size));
break; break;
case TRICK_UNSIGNED_INTEGER: case TRICK_UNSIGNED_INTEGER:
snprintf(value, value_size, "%s%u", value, (unsigned int)cv_convert_double(var->conversion_factor,*(unsigned int *)buf_ptr)); snprintf(temp_buf, value_size, "%u", (unsigned int)cv_convert_double(var->conversion_factor,*(unsigned int *)buf_ptr));
break; break;
case TRICK_LONG: { case TRICK_LONG: {
@ -135,7 +137,7 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
if (var->conversion_factor != cv_get_trivial()) { if (var->conversion_factor != cv_get_trivial()) {
l = (long)cv_convert_double(var->conversion_factor, l); l = (long)cv_convert_double(var->conversion_factor, l);
} }
snprintf(value, value_size, "%s%ld", value, l); snprintf(temp_buf, value_size, "%ld", l);
break; break;
} }
@ -144,16 +146,16 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
if (var->conversion_factor != cv_get_trivial()) { if (var->conversion_factor != cv_get_trivial()) {
ul = (unsigned long)cv_convert_double(var->conversion_factor, ul); ul = (unsigned long)cv_convert_double(var->conversion_factor, ul);
} }
snprintf(value, value_size, "%s%lu", value, ul); snprintf(temp_buf, value_size, "%lu", ul);
break; break;
} }
case TRICK_FLOAT: case TRICK_FLOAT:
snprintf(value, value_size, "%s%.8g", value, cv_convert_float(var->conversion_factor,*(float *)buf_ptr)); snprintf(temp_buf, value_size, "%.8g", cv_convert_float(var->conversion_factor,*(float *)buf_ptr));
break; break;
case TRICK_DOUBLE: case TRICK_DOUBLE:
snprintf(value, value_size, "%s%.16g", value, cv_convert_double(var->conversion_factor,*(double *)buf_ptr)); snprintf(temp_buf, value_size, "%.16g", cv_convert_double(var->conversion_factor,*(double *)buf_ptr));
break; break;
case TRICK_LONG_LONG: { case TRICK_LONG_LONG: {
@ -161,7 +163,7 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
if (var->conversion_factor != cv_get_trivial()) { if (var->conversion_factor != cv_get_trivial()) {
ll = (long long)cv_convert_double(var->conversion_factor, ll); ll = (long long)cv_convert_double(var->conversion_factor, ll);
} }
snprintf(value, value_size, "%s%lld", value, ll); snprintf(temp_buf, value_size, "%lld", ll);
break; break;
} }
@ -170,12 +172,12 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
if (var->conversion_factor != cv_get_trivial()) { if (var->conversion_factor != cv_get_trivial()) {
ull = (unsigned long long)cv_convert_double(var->conversion_factor, ull); ull = (unsigned long long)cv_convert_double(var->conversion_factor, ull);
} }
snprintf(value, value_size, "%s%llu", value, ull); snprintf(temp_buf, value_size, "%llu", ull);
break; break;
} }
case TRICK_NUMBER_OF_TYPES: case TRICK_NUMBER_OF_TYPES:
snprintf(value, value_size, "BAD_REF" ); snprintf(temp_buf, value_size, "BAD_REF" );
break; break;
default:{ default:{
@ -185,9 +187,10 @@ int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_si
if (size < var->size) { if (size < var->size) {
// if returning an array, continue array as comma separated values // if returning an array, continue array as comma separated values
strcat(value, ",") ; strcat(temp_buf, ",") ;
buf_ptr = (void*) ((long)buf_ptr + var->ref->attr->size) ; buf_ptr = (void*) ((long)buf_ptr + var->ref->attr->size) ;
} }
strncat(value, temp_buf, value_size - strlen(value) - 1);
} //end while } //end while
if (ref->units) { if (ref->units) {