Prevent return of dangling Vector/QAngle to VScript

When a Vector or QAngle rvalue reference is returned from a VScript
function, the constructed ScriptVariant_t must not store the pointer to
it since it is, per convention, a temporary reference. Only do that for
lvalue-references, but do a copy when constructing from or assigning a
rvalue reference.
This commit is contained in:
Alexander 'z33ky' Hirsch 2024-09-05 23:24:06 +02:00
parent 471a840ed9
commit c9dd357470
3 changed files with 7 additions and 6 deletions

View File

@ -396,6 +396,9 @@ struct ScriptVariant_t
#ifdef MAPBASE_VSCRIPT #ifdef MAPBASE_VSCRIPT
ScriptVariant_t( const QAngle &val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pAngle = &val; } else { m_pAngle = new QAngle( val ); m_flags |= SV_FREE; } } ScriptVariant_t( const QAngle &val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pAngle = &val; } else { m_pAngle = new QAngle( val ); m_flags |= SV_FREE; } }
ScriptVariant_t( const QAngle *val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pAngle = val; } else { m_pAngle = new QAngle( *val ); m_flags |= SV_FREE; } } ScriptVariant_t( const QAngle *val, bool bCopy = false ) : m_flags( 0 ), m_type( FIELD_VECTOR ) { if ( !bCopy ) { m_pAngle = val; } else { m_pAngle = new QAngle( *val ); m_flags |= SV_FREE; } }
ScriptVariant_t( Vector &&val ) : ScriptVariant_t( val, true ) { }
ScriptVariant_t( QAngle &&val ) : ScriptVariant_t( val, true ) { }
#endif #endif
bool IsNull() const { return (m_type == FIELD_VOID ); } bool IsNull() const { return (m_type == FIELD_VOID ); }
@ -423,6 +426,9 @@ struct ScriptVariant_t
#ifdef MAPBASE_VSCRIPT #ifdef MAPBASE_VSCRIPT
void operator=( const QAngle &vec ) { m_type = FIELD_VECTOR; m_pAngle = &vec; } void operator=( const QAngle &vec ) { m_type = FIELD_VECTOR; m_pAngle = &vec; }
void operator=( const QAngle *vec ) { m_type = FIELD_VECTOR; m_pAngle = vec; } void operator=( const QAngle *vec ) { m_type = FIELD_VECTOR; m_pAngle = vec; }
void operator=( Vector &&vec ) { m_type = FIELD_VECTOR; m_pVector = new Vector( vec ); m_flags |= SV_FREE; }
void operator=( QAngle &&vec ) { m_type = FIELD_VECTOR; m_pAngle = new QAngle( vec ); m_flags |= SV_FREE; }
#endif #endif
void Free() { if ( ( m_flags & SV_FREE ) && ( m_type == FIELD_HSCRIPT || m_type == FIELD_VECTOR || m_type == FIELD_CSTRING ) ) delete m_pszString; } // Generally only needed for return results void Free() { if ( ( m_flags & SV_FREE ) && ( m_type == FIELD_HSCRIPT || m_type == FIELD_VECTOR || m_type == FIELD_CSTRING ) ) delete m_pszString; } // Generally only needed for return results

View File

@ -337,8 +337,6 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
return false; \ return false; \
} \ } \
*pReturn = ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ); \ *pReturn = ((FUNC_TYPE)pFunction)( SCRIPT_BINDING_ARGS_##N ); \
if ( pReturn->m_type == FIELD_VECTOR ) \
pReturn->m_pVector = new Vector(*pReturn->m_pVector); \
return true; \ return true; \
} \ } \
}; \ }; \
@ -377,8 +375,6 @@ inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( void *p )
return false; \ return false; \
} \ } \
*pReturn = (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \ *pReturn = (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
if ( pReturn->m_type == FIELD_VECTOR ) \
pReturn->m_pVector = new Vector(*pReturn->m_pVector); \
return true; \ return true; \
} \ } \
}; \ }; \

View File

@ -1415,8 +1415,7 @@ SQInteger function_stub(HSQUIRRELVM vm)
PushVariant(vm, retval); PushVariant(vm, retval);
if (retval.m_type == FIELD_VECTOR) retval.Free();
delete retval.m_pVector;
return pFunc->m_desc.m_ReturnType != FIELD_VOID; return pFunc->m_desc.m_ReturnType != FIELD_VOID;
} }