Skip to content

Commit b2190fa

Browse files
acontylgritz
authored andcommitted
Fix userdata binding corner case (#1673)
This includes two fixes: 1) When registering symbols that need user data, sort the entries in the set so the layer number is ignored. A needed udata iteam shouldn't depend on the layer and separating them makes find_userdata_index() sometimes find an index with different derivs status. 2) osl_bind_interpolated_param() is memcpy'ing derivs that might not be there, yielding corrupted derivs and possibly a crash. Signed-off-by: Alejandro Conty <[email protected]>
1 parent 35aa264 commit b2190fa

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

src/liboslexec/oslexec_pvt.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,10 @@ struct UserDataNeeded {
191191
{
192192
if (a.name != b.name)
193193
return a.name < b.name;
194-
if (a.layer_num != b.layer_num)
195-
return a.layer_num < b.layer_num;
194+
// Checking for layer_num means that if derivs differ find_userdata_index
195+
// may find the wrong layer symbol with the wrong derivs setting.
196+
//if (a.layer_num != b.layer_num)
197+
// return a.layer_num < b.layer_num;
196198
if (a.type.basetype != b.type.basetype)
197199
return a.type.basetype < b.type.basetype;
198200
if (a.type.aggregate != b.type.aggregate)

src/liboslexec/shadingsys.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4469,8 +4469,13 @@ osl_bind_interpolated_param(void* sg_, const void* name, long long type,
44694469
sg->context->incr_get_userdata_calls();
44704470
}
44714471
if (status == 2) {
4472+
int udata_size = (userdata_has_derivs ? 3 : 1) * TYPEDESC(type).size();
44724473
// If userdata was present, copy it to the shader variable
4473-
memcpy(symbol_data, userdata_data, symbol_data_size);
4474+
memcpy(symbol_data, userdata_data,
4475+
std::min(symbol_data_size, udata_size));
4476+
if (symbol_data_size > udata_size)
4477+
memset((char*)symbol_data + udata_size, 0,
4478+
symbol_data_size - udata_size);
44744479
return 1;
44754480
}
44764481
return 0; // no such user data

0 commit comments

Comments
 (0)