diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2023-10-29 11:56:17 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2023-10-29 11:56:17 -0400 |
commit | f7d2d40b3057f5bc249c88784b35443aad8de7aa (patch) | |
tree | 1e5a228889616e1130e0546ca432fa3096577f9a /indra/llmath | |
parent | 2667653d41d3b4799bf319783a884cbac7f826da (diff) |
DRTVWR-587: Fix LL::apply(function, LLSD array).
We define a specialization of LLSDParam<const char*> to support passing an
LLSD object to a const char* function parameter. Needless to remark, passing
object.asString().c_str() would be Bad: destroying the temporary std::string
returned by asString() would immediately invalidate the pointer returned by
its c_str(). But when you pass LLSDParam<const char*>(object) as the
parameter, that specialization itself stores the std::string so the c_str()
pointer remains valid as long as the LLSDParam object does.
Then there's LLSDParam<LLSD>, used when we don't have the parameter type
available to select the LLSDParam specialization. LLSDParam<LLSD> defines a
templated conversion operator T() that constructs an LLSDParam<T> to provide
the actual parameter value. So far, so good.
The trouble was with the implementation of LLSDParam<LLSD>: it constructed a
_temporary_ LLSDParam<T>, implicitly called its operator T() and immediately
destroyed it. Destroying LLSDParam<const char*> destroyed its stored string,
thus invalidating the c_str() pointer before the target function was entered.
Instead, make LLSDParam<LLSD>::operator T() capture each LLSDParam<T> it
constructs, extending its lifespan to the lifespan of the LLSDParam<LLSD>
instance. For this, derive each LLSDParam specialization from LLSDParamBase, a
trivial base class that simply establishes the virtual destructor. We can then
capture any specialization as a pointer to LLSDParamBase.
Also restore LazyEventAPI tests on Mac.
Diffstat (limited to 'indra/llmath')
0 files changed, 0 insertions, 0 deletions