Skip to content

Commit 0260452

Browse files
committed
Fixed undefined behavior caused by using pointers as counters. Supersedes #41
1 parent 22ee78f commit 0260452

File tree

1 file changed

+18
-19
lines changed

1 file changed

+18
-19
lines changed

src/object_type_info.cpp

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,17 @@ object_type_info::call_table_message object_type_info::make_call_table_message(m
8787
void object_type_info::fill_call_table()
8888
{
8989
// first pass
90-
// find top bid messages and prepare to calculate message buffer length length
90+
// find top bid messages and prepare to calculate message buffer length
9191

92-
intptr_t message_data_buffer_size = 0;
93-
94-
// in this pass we make use of the fact that _call_table begin starts as nullptr
95-
// for a new type so we will use it as a counter
92+
uint_fast32_t message_data_buffer_size = 0;
93+
uint_fast32_t num_top_bidders_per_message[DYNAMIX_MAX_MESSAGES] = {};
9694

9795
for (const mixin_type_info* info : _compact_mixins)
9896
{
9997
for (const internal::message_for_mixin& msg : info->message_infos)
10098
{
10199
call_table_entry& table_entry = _call_table[msg.message->id];
100+
auto& num_top_bidders = num_top_bidders_per_message[msg.message->id];
102101

103102
if (msg.message->mechanism == internal::message_t::unicast)
104103
{
@@ -114,26 +113,27 @@ void object_type_info::fill_call_table()
114113
table_entry.top_bid_message = make_call_table_message(info->id, msg);
115114

116115
// also remove the top-priority size we've accumulated
117-
message_data_buffer_size -= reinterpret_cast<intptr_t>(table_entry.begin) / sizeof(*table_entry.begin);
118-
table_entry.begin = nullptr;
116+
I_DYNAMIX_ASSERT(message_data_buffer_size >= num_top_bidders);
117+
message_data_buffer_size -= num_top_bidders;
118+
num_top_bidders = 0;
119119
}
120120
else if (table_entry.top_bid_message.data->priority == msg.priority)
121121
{
122-
if (!table_entry.begin)
122+
if (num_top_bidders == 0)
123123
{
124124
// same-priority message
125125
// we will need a buffer for those if they're top-priority
126126
// add one to the buffer for the first one too
127127
++message_data_buffer_size;
128128

129-
// hacky usage of end to count top bidders
129+
// also count top bidders for this particular message
130130
// we need this so we can update message_data_buffer_size if we encounter
131131
// a message with a higher priority
132-
++table_entry.begin;
132+
++num_top_bidders;
133133
}
134134

135135
++message_data_buffer_size;
136-
++table_entry.begin;
136+
++num_top_bidders;
137137

138138
// we have multiple bidders for the same priority
139139
if (table_entry.top_bid_message.data->bid < msg.bid)
@@ -142,9 +142,9 @@ void object_type_info::fill_call_table()
142142
}
143143
}
144144
}
145-
if(msg.message->mechanism == internal::message_t::multicast)
145+
else if (msg.message->mechanism == internal::message_t::multicast)
146146
{
147-
if (!table_entry.begin)
147+
if (num_top_bidders == 0)
148148
{
149149
// for each new mulicast message add one more element to the buffer
150150
// it will be filled with nullptr so that we know when to stop when
@@ -156,9 +156,8 @@ void object_type_info::fill_call_table()
156156
table_entry.top_bid_message = make_call_table_message(info->id, msg);
157157
}
158158

159-
// again we use begin to set the size of the buffer this particular message needs
160159
++message_data_buffer_size;
161-
++table_entry.begin;
160+
++num_top_bidders;
162161
}
163162
}
164163
}
@@ -175,16 +174,16 @@ void object_type_info::fill_call_table()
175174
for (const internal::message_for_mixin& msg : info->message_infos)
176175
{
177176
call_table_entry& table_entry = _call_table[msg.message->id];
177+
const auto num_top_bidders = num_top_bidders_per_message[msg.message->id];
178178

179-
if(table_entry.begin)
179+
if (num_top_bidders)
180180
{
181181
if (!table_entry.end)
182182
{
183-
// begin is not null and end is null, so this message has not been updated
184-
// but needs to be
183+
// end is null, so this message has not been updated, but needs to be
185184

186185
auto begin = message_data_buffer_ptr;
187-
message_data_buffer_ptr += reinterpret_cast<intptr_t>(table_entry.begin) / sizeof(*table_entry.begin);
186+
message_data_buffer_ptr += num_top_bidders;
188187

189188
if (msg.message->mechanism == internal::message_t::multicast)
190189
{

0 commit comments

Comments
 (0)