fix a possible SIGABRT when misdetecting a vtable as being valid

add enum names enum-based indexes
develop
Ben Lubar 2020-02-09 15:12:25 -06:00
parent e9dba1d6ca
commit 05a49cbacb
No known key found for this signature in database
GPG Key ID: 92939677AB59EDA4
1 changed files with 46 additions and 8 deletions

@ -79,7 +79,7 @@ private:
bool check_access(const ToCheck &, void *, type_identity *, size_t);
bool check_vtable(const ToCheck &, void *, type_identity *);
void queue_field(ToCheck &&, const struct_field_info *);
void queue_static_array(const ToCheck &, void *, type_identity *, size_t, bool = false);
void queue_static_array(const ToCheck &, void *, type_identity *, size_t, bool = false, enum_identity * = nullptr);
void check_dispatch(const ToCheck &);
void check_global(const ToCheck &);
void check_primitive(const ToCheck &);
@ -251,6 +251,7 @@ bool Checker::check_vtable(const ToCheck & item, void *vtable, type_identity *id
return false;
}
bool letter = false;
for (char *p = name; ; p++)
{
if (!range.isInRange(p))
@ -258,9 +259,13 @@ bool Checker::check_vtable(const ToCheck & item, void *vtable, type_identity *id
return false;
}
if (!*p)
if (*p >= 'a' && *p <= 'z')
{
return true;
letter = true;
}
else if (!*p)
{
return letter;
}
}
}
@ -287,7 +292,7 @@ void Checker::queue_field(ToCheck && item, const struct_field_info *field)
queue.push(std::move(item));
break;
case struct_field_info::STATIC_ARRAY:
queue_static_array(item, item.ptr, field->type, field->count);
queue_static_array(item, item.ptr, field->type, field->count, false, field->eid);
break;
case struct_field_info::SUBSTRUCT:
queue.push(std::move(item));
@ -307,13 +312,43 @@ void Checker::queue_field(ToCheck && item, const struct_field_info *field)
}
}
void Checker::queue_static_array(const ToCheck & array, void *base, type_identity *type, size_t count, bool pointer)
void Checker::queue_static_array(const ToCheck & array, void *base, type_identity *type, size_t count, bool pointer, enum_identity *ienum)
{
size_t size = type->byte_size();
for (size_t i = 0; i < count; i++, base = PTR_ADD(base, size))
{
ToCheck item(array, i, base, type);
if (ienum)
{
const char *name = nullptr;
if (auto cplx = ienum->getComplex())
{
auto it = cplx->value_index_map.find(int64_t(i));
if (it != cplx->value_index_map.end())
{
name = ienum->getKeys()[it->second];
}
}
else if (int64_t(i) >= ienum->getFirstItem() && int64_t(i) <= ienum->getLastItem())
{
name = ienum->getKeys()[int64_t(i) - ienum->getFirstItem()];
}
std::ostringstream str;
str << "[" << ienum->getFullName() << "::";
if (name)
{
str << name;
}
else
{
str << "?" << i << "?";
}
str << "]";
item.path.back() = str.str();
}
if (pointer)
{
item.temp_identity = std::unique_ptr<pointer_identity>(new pointer_identity(type));
@ -358,7 +393,8 @@ void Checker::check_dispatch(const ToCheck & item)
case IDTYPE_BUFFER:
{
auto item_identity = static_cast<container_identity *>(item.identity)->getItemType();
queue_static_array(item, item.ptr, item_identity, item.identity->byte_size() / item_identity->byte_size());
auto ienum = static_cast<enum_identity *>(static_cast<container_identity *>(item.identity)->getIndexEnumType());
queue_static_array(item, item.ptr, item_identity, item.identity->byte_size() / item_identity->byte_size(), false, ienum);
}
break;
case IDTYPE_BITFIELD:
@ -619,7 +655,8 @@ void Checker::check_vector(const ToCheck & item, type_identity *item_identity, b
if (local_ok && check_access(item, reinterpret_cast<void *>(vector.start), item.identity, length) && item_identity)
{
queue_static_array(item, reinterpret_cast<void *>(vector.start), item_identity, ulength / item_size, pointer);
auto ienum = static_cast<enum_identity *>(static_cast<container_identity *>(item.identity)->getIndexEnumType());
queue_static_array(item, reinterpret_cast<void *>(vector.start), item_identity, ulength / item_size, pointer, ienum);
}
}
@ -649,7 +686,8 @@ void Checker::check_dfarray(const ToCheck & item, type_identity *item_identity)
if (check_access(item, reinterpret_cast<void *>(dfarray.start), item.identity, item_size * length))
{
queue_static_array(item, reinterpret_cast<void *>(dfarray.start), item_identity, length);
auto ienum = static_cast<enum_identity *>(static_cast<container_identity *>(item.identity)->getIndexEnumType());
queue_static_array(item, reinterpret_cast<void *>(dfarray.start), item_identity, length, false, ienum);
}
}