Skip to content

Commit 5fb6959

Browse files
committed
com.livecode.engine: Convert types for result of send & execute script
The engine module's `send` and `execute script` statements were failing to correctly perform type conversion of their results, potentially leaking `MCNameRef`s into LCB script. This patch adds a `MCEngineEvalScriptResult()` handler that does this correctly. A better long-term fix would be to make sure LCB can cope with `MCNameRef`s correctly and transparently through its typesystem.
1 parent 9c21918 commit 5fb6959

4 files changed

Lines changed: 73 additions & 9 deletions

File tree

engine/src/module-engine.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,25 @@ void MCEngineScriptObjectAllowAccess(void)
120120

121121
////////////////////////////////////////////////////////////////////////////////
122122

123+
static MCValueRef
124+
MCEngineEvalScriptResult (MCExecContext& ctxt)
125+
{
126+
if (MCresult->isclear())
127+
{
128+
return nil;
129+
}
130+
131+
MCAutoValueRef t_result(MCresult->getvalueref());
132+
if (!MCExtensionConvertFromScriptType(ctxt, kMCAnyTypeInfo,
133+
InOut(t_result)))
134+
{
135+
return nil;
136+
}
137+
return t_result.Take();
138+
}
139+
140+
////////////////////////////////////////////////////////////////////////////////
141+
123142
extern "C" MC_DLLEXPORT_DEF MCScriptObjectRef MCEngineExecResolveScriptObject(MCStringRef p_object_id)
124143
{
125144
if (!MCEngineScriptObjectAccessIsAllowed())
@@ -444,9 +463,7 @@ MCValueRef MCEngineDoSendToObjectWithArguments(bool p_is_function, MCStringRef p
444463

445464
MCExecContext ctxt(MCdefaultstackptr, nil, nil);
446465
MCParameter *t_params;
447-
MCValueRef t_result;
448466
t_params = nil;
449-
t_result = nil;
450467

451468
if (!MCEngineConvertToScriptParameters(ctxt, p_arguments, t_params))
452469
goto cleanup;
@@ -468,12 +485,9 @@ MCValueRef MCEngineDoSendToObjectWithArguments(bool p_is_function, MCStringRef p
468485
else
469486
s_last_message_was_handled = false;
470487

471-
/* Provide a return value iff the result was set */
472-
t_result = MCValueRetain(MCresult->isclear() ? kMCNull : MCresult->getvalueref());
473-
474488
cleanup:
475489
MCEngineFreeScriptParameters(t_params);
476-
return t_result;
490+
return MCEngineEvalScriptResult(ctxt);
477491
}
478492

479493
extern "C" MC_DLLEXPORT_DEF MCValueRef MCEngineExecSendToScriptObjectWithArguments(bool p_is_function, MCStringRef p_message, MCScriptObjectRef p_object, MCProperListRef p_arguments)
@@ -569,8 +583,9 @@ extern "C" MC_DLLEXPORT_DEF MCValueRef MCEngineExecExecuteScript(MCStringRef p_s
569583
MCEngineThrowScriptError();
570584
return nil;
571585
}
572-
573-
return MCValueRetain(MCresult -> getvalueref());
586+
587+
MCExecContext ctxt(MCdefaultstackptr, nil, nil);
588+
return MCEngineEvalScriptResult(ctxt);
574589
}
575590

576591
////////////////////////////////////////////////////////////////////////////////

tests/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,14 @@ $(LCM_DIR)/%.lcm: %.lcb | $(LCM_DIR)
111111
# Engine-based tests
112112
################################################################
113113

114-
lcs-check: $(LCS_ENGINE)
114+
lcs-check: $(LCS_ENGINE) lcm_compile
115115
@rm -f $(LCS_LOG)
116116
@cmd="$(LCS_CMD)"; \
117117
echo "$$cmd" $(_PRINT_RULE); \
118118
$$cmd
119119

120+
.PHONY: lcs-check
121+
120122
################################################################
121123
# LCB compiler tests
122124
################################################################
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
library com.livecode.lcs_tests.core.extension
2+
3+
public handler TestExtensionBridgeNames_ExecuteScript()
4+
execute script "return the version"
5+
return the result is a string
6+
end handler
7+
8+
public handler TestExtensionBridgeNumbers_ExecuteScript()
9+
execute script "return 5+0"
10+
return the result is a number
11+
end handler
12+
13+
public handler TestExtensionBridgeNames_Send()
14+
variable tScriptObject
15+
resolve script object "stack \qCoreEngineExtensions\q"
16+
put the result into tScriptObject
17+
test diagnostic tScriptObject
18+
19+
send function "TestExtensionBridgeNames_Version" to tScriptObject
20+
return the result is a string
21+
end handler
22+
23+
end library

tests/lcs/core/engine/extension.livecodescript

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1919
on TestSetup
2020
TestLoadExtension "com.livecode.library.json"
2121
TestLoadExtension "com.livecode.widget.clock"
22+
23+
TestDiagnostic the defaultfolder
24+
load extension from file "../_tests/_build/lcs/core/engine/_extension.lcm"
25+
if the result is not empty then
26+
throw "Failed to load test support extension:" && the result
27+
end if
2228
end TestSetup
2329

2430
/////////
@@ -45,3 +51,21 @@ on TestUnloadWidgetModuleAfterDeletion
4551
send "_TestUnloadWidgetModuleAfterDeletion_DoDeleteAndUnload" to me in 0 millisecs
4652
wait 1 millisecond with messages
4753
end TestUnloadWidgetModuleAfterDeletion
54+
55+
/////////
56+
57+
function TestExtensionBridgeNames_Version
58+
return the version
59+
end TestExtensionBridgeNames_Version
60+
61+
on TestExtensionBridgeNames
62+
TestAssert "LCS names bridge to LCB strings in execute script", \
63+
TestExtensionBridgeNames_ExecuteScript()
64+
TestAssert "LCS names bridge to LCB strings in send", \
65+
TestExtensionBridgeNames_Send()
66+
end TestExtensionBridgeNames
67+
68+
on TestExtensionBridgeNumbers
69+
TestAssert "LCS numbers bridge to LCB numbers in execute script", \
70+
TestExtensionBridgeNumbers_ExecuteScript()
71+
end TestExtensionBridgeNumbers

0 commit comments

Comments
 (0)