Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 0b918da

Browse files
committed
[[ Bug 18998 ]] Check for script-only stacks in objchunk url resolution
1 parent 232d091 commit 0b918da

5 files changed

Lines changed: 150 additions & 87 deletions

File tree

docs/notes/bugfix-18998.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Fix go url <stackurl> for script-only stacks

engine/src/cmdss.cpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -447,25 +447,18 @@ Parse_stat MCGo::parse(MCScriptPoint &sp)
447447

448448
MCStack *MCGo::findstack(MCExecContext &ctxt, MCStringRef p_value, Chunk_term etype, MCCard *&cptr)
449449
{
450-
MCStack *sptr = NULL;
451-
uint4 offset;
452-
if (MCStringFirstIndexOf(p_value, MCSTR(kMCStackFileMetaCardSignature), 0, kMCCompareExact, offset)
453-
|| (MCStringGetLength(p_value) > 8 && MCStringBeginsWithCString(p_value, (char_t*)"REVO", kMCCompareExact)))
450+
MCStack *sptr = nil;
451+
if (MCInterfaceStringCouldBeStack(p_value))
454452
{
455-
char_t* t_cstring_value;
456-
uindex_t t_length;
457-
/* UNCHECKED */ MCStringConvertToNative(p_value, t_cstring_value, t_length);
458-
IO_handle stream = MCS_fakeopen(t_cstring_value, t_length);
459-
if (MCdispatcher->readfile(NULL, NULL, stream, sptr) != IO_NORMAL)
460-
{
461-
MCS_close(stream);
462-
if (MCresult->isclear())
453+
sptr = MCInterfaceTryToEvalStackFromString(p_value);
454+
if (sptr == nil)
455+
{
456+
if (MCresult->isclear())
463457
ctxt . SetTheResultToCString("can't build stack from string");
464-
return nil;
465-
}
466-
MCS_close(stream);
467-
return sptr;
468-
}
458+
}
459+
return sptr;
460+
}
461+
469462
if (etype == CT_STACK)
470463
return NULL;
471464
else

engine/src/exec-interface2.cpp

Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
6666
#include "exec-interface.h"
6767
#include "resolution.h"
6868

69+
#include "scriptpt.h"
70+
6971
////////////////////////////////////////////////////////////////////////////////
7072

7173
MC_EXEC_DEFINE_GET_METHOD(Interface, DialogData, 1)
@@ -2395,36 +2397,25 @@ void MCInterfaceEvalFocusedObjectAsObject(MCExecContext& ctxt, MCObjectPtr& r_ob
23952397
ctxt . LegacyThrow(EE_CHUNK_NOTARGET);
23962398
}
23972399

2398-
static MCStack *MCInterfaceTryToEvalBinaryStack(MCStringRef p_data, bool& r_binary_fail)
2400+
MCStack *MCInterfaceTryToEvalStackFromString(MCStringRef p_data)
23992401
{
2400-
uint4 offset;
2401-
MCStack *t_stack;
2402-
bool t_binary_fail;
2402+
char_t* t_string;
2403+
uindex_t t_length;
2404+
if (!MCStringConvertToNative(p_data, t_string, t_length))
2405+
return nil;
2406+
2407+
MCStack *t_stack = nil;
2408+
IO_handle stream = MCS_fakeopen(t_string, t_length);
2409+
/* UNCHECKED */ MCdispatcher->readfile(NULL, NULL, stream, t_stack);
2410+
MCS_close(stream);
24032411

2404-
t_stack = nil;
2405-
t_binary_fail = false;
2406-
2407-
if (MCStringFirstIndexOf(p_data, MCSTR(kMCStackFileMetaCardSignature), 0, kMCCompareExact, offset) && (MCStringGetLength(p_data) > 8 && MCStringBeginsWithCString(p_data, (const char_t *)"REVO", kMCCompareExact)))
2408-
{
2409-
char_t* t_string;
2410-
uindex_t t_length;
2411-
/* UNCHECKED */ MCStringConvertToNative(p_data, t_string, t_length);
2412-
IO_handle stream = MCS_fakeopen(t_string, t_length);
2413-
/* UNCHECKED */ MCdispatcher->readfile(NULL, NULL, stream, t_stack);
2414-
MCS_close(stream);
2415-
t_binary_fail = t_stack == nil;
2416-
}
2417-
2418-
r_binary_fail = t_binary_fail;
24192412
return t_stack;
24202413
}
24212414

24222415
void MCInterfaceEvalBinaryStackAsObject(MCExecContext& ctxt, MCStringRef p_data, MCObjectPtr& r_object)
24232416
{
24242417
MCStack *t_stack;
2425-
bool t_binary_fail;
2426-
2427-
t_stack = MCInterfaceTryToEvalBinaryStack(p_data, t_binary_fail);
2418+
t_stack = MCInterfaceTryToEvalStackFromString(p_data);
24282419

24292420
if (t_stack != nil)
24302421
{
@@ -2477,11 +2468,37 @@ void MCInterfaceEvalStackOfStackById(MCExecContext& ctxt, MCObjectPtr p_parent,
24772468
ctxt . LegacyThrow(EE_CHUNK_NOSTACK);
24782469
}
24792470

2471+
bool MCInterfaceStringCouldBeStack(MCStringRef p_string)
2472+
{
2473+
// Check if it could be a binary stack
2474+
uindex_t t_offset;
2475+
if (MCStringFirstIndexOf(p_string,
2476+
MCSTR(kMCStackFileMetaCardSignature), 0,
2477+
kMCCompareExact, t_offset) ||
2478+
(MCStringGetLength(p_string) > 8 &&
2479+
MCStringBeginsWithCString(p_string, (const char_t *)"REVO",
2480+
kMCCompareExact)))
2481+
return true;
2482+
2483+
// Check if it could be a script-only stack
2484+
MCScriptPoint sp(p_string);
2485+
// Parse 'script' token.
2486+
if (sp . skip_token(SP_FACTOR, TT_PROPERTY, P_SCRIPT) != PS_NORMAL)
2487+
return false;
2488+
2489+
// Parse <string> token.
2490+
Symbol_type t_type;
2491+
if (sp . next(t_type) != PS_NORMAL || t_type != ST_LIT)
2492+
return false;
2493+
2494+
// Parse end of line.
2495+
Parse_stat t_stat = sp . next(t_type);
2496+
return (t_stat == PS_EOL || t_stat == PS_EOF);
2497+
}
2498+
24802499
void MCInterfaceEvalStackByValue(MCExecContext& ctxt, MCValueRef p_value, MCObjectPtr& r_stack)
24812500
{
2482-
uint4 offset;
2483-
2484-
if (MCStringFirstIndexOf((MCStringRef)p_value, MCSTR(kMCStackFileMetaCardSignature), 0, kMCCompareExact, offset) && MCStringGetLength((MCStringRef)p_value) > 8 && MCStringBeginsWithCString((MCStringRef)p_value, (const char_t *)"REVO", kMCCompareExact))
2501+
if (MCInterfaceStringCouldBeStack((MCStringRef)p_value))
24852502
{
24862503
MCInterfaceEvalBinaryStackAsObject(ctxt, (MCStringRef)p_value, r_stack);
24872504
return;
@@ -3270,51 +3287,6 @@ void MCInterfaceEvalStackOfOptionalStackById(MCExecContext& ctxt, MCObjectPtr p_
32703287
r_stack . part_id = p_parent . part_id;
32713288
}
32723289

3273-
void MCInterfaceEvalOptionalStackOrCardByValue(MCExecContext& ctxt, MCValueRef p_value, MCObjectPtr& r_object)
3274-
{
3275-
ctxt . SetTheResultToEmpty();
3276-
3277-
MCStack *t_stack;
3278-
bool t_binary_fail;
3279-
3280-
t_stack = MCInterfaceTryToEvalBinaryStack((MCStringRef)p_value, t_binary_fail);
3281-
3282-
if (t_binary_fail)
3283-
{
3284-
ctxt . SetTheResultToStaticCString("can't build stack from string");
3285-
r_object . object = nil;
3286-
r_object . part_id = 0;
3287-
return;
3288-
}
3289-
3290-
if (t_stack == nil)
3291-
{
3292-
integer_t t_id;
3293-
if (MCU_stoi4((MCStringRef)p_value, t_id))
3294-
t_stack = MCdefaultstackptr -> findstackid(t_id);
3295-
}
3296-
3297-
if (t_stack == nil)
3298-
t_stack = MCdefaultstackptr -> findstackname((MCNameRef)p_value);
3299-
3300-
if (t_stack != nil)
3301-
{
3302-
r_object . object = t_stack;
3303-
r_object . part_id = 0;
3304-
return;
3305-
}
3306-
3307-
bool t_parse_error;
3308-
3309-
if (!MCEngineEvalValueAsObject(p_value, false, r_object, t_parse_error))
3310-
{
3311-
if (t_parse_error)
3312-
ctxt . SetTheResultToStaticCString("no such card");
3313-
r_object . object = nil;
3314-
r_object . part_id = 0;
3315-
}
3316-
}
3317-
33183290
void MCInterfaceEvalSubstackOfOptionalStackByName(MCExecContext& ctxt, MCObjectPtr p_parent, MCNameRef p_name, MCObjectPtr& r_stack)
33193291
{
33203292
MCStack *t_stack;

engine/src/exec.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3393,6 +3393,10 @@ void MCInterfaceEvalHomeStackAsObject(MCExecContext& ctxt, MCObjectPtr& r_object
33933393
void MCInterfaceEvalSelectedObjectAsObject(MCExecContext& ctxt, MCObjectPtr& r_object);
33943394
void MCInterfaceEvalTopStackAsObject(MCExecContext& ctxt, MCObjectPtr& r_object);
33953395
void MCInterfaceEvalClickStackAsObject(MCExecContext& ctxt, MCObjectPtr& r_object);
3396+
3397+
MCStack *MCInterfaceTryToEvalStackFromString(MCStringRef p_data);
3398+
bool MCInterfaceStringCouldBeStack(MCStringRef p_string);
3399+
33963400
void MCInterfaceEvalMouseStackAsObject(MCExecContext& ctxt, MCObjectPtr& r_object);
33973401
void MCInterfaceEvalClickFieldAsObject(MCExecContext& ctxt, MCObjectPtr& r_object);
33983402
void MCInterfaceEvalSelectedFieldAsObject(MCExecContext& ctxt, MCObjectPtr& r_object);
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
script "CoreInterfaceGo"
2+
/*
3+
Copyright (C) 2016 LiveCode Ltd.
4+
5+
This file is part of LiveCode.
6+
7+
LiveCode is free software; you can redistribute it and/or modify it under
8+
the terms of the GNU General Public License v3 as published by the Free
9+
Software Foundation.
10+
11+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
12+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
18+
19+
on TestGoStackUnquotedName
20+
-- unquoted literal chunk parsing exception for `go stack "stack foo"`
21+
local tStackName
22+
create stack "stackToGo"
23+
put the short name of it into tStackName
24+
25+
local tToGo
26+
put "stack stackToGo" into tToGo
27+
28+
try
29+
go tToGo
30+
catch tError
31+
end try
32+
33+
TestAssert "unquoted literal chunk parsing exception for go stack", \
34+
tError is empty
35+
end TestGoStackUnquotedName
36+
37+
on TestGoCardUnquotedName
38+
-- unquoted literal chunk parsing exception for `go "card foo of this stack"`
39+
local tStackName
40+
create stack
41+
put the short name of it into tStackName
42+
43+
create card "cardToGo"
44+
local tToGo
45+
put "card cardToGo" && the long id of stack tStackName into tToGo
46+
47+
try
48+
go tToGo
49+
catch tError
50+
end try
51+
52+
TestAssert "unquoted literal chunk parsing exception for go card", \
53+
tError is empty
54+
end TestGoCardUnquotedName
55+
56+
local sStackFileName
57+
command _TestCreateStack pBinary
58+
local tStack
59+
put "stackToGo" into tStack
60+
61+
if pBinary then
62+
create stack tStack
63+
else
64+
create script only stack tStack
65+
end if
66+
67+
put the tempname into sStackFileName
68+
save stack tStack as sStackFileName
69+
delete stack tStack
70+
return tStack for value
71+
end _TestCreateStack
72+
73+
command _TestCleanupStack
74+
delete file sStackFileName
75+
end _TestCleanupStack
76+
77+
command _TestGoStackUrl pWhich
78+
local tStack
79+
_TestCreateStack pWhich is "binary"
80+
put it into tStack
81+
go url ("file:" & sStackFileName)
82+
TestDiagnostic the result
83+
TestAssert "go" && pWhich && "stack url", there is a stack tStack
84+
_TestCleanupStack
85+
end _TestGoStackUrl
86+
87+
on TestGoBinaryStackUrl
88+
_TestGoStackUrl "binary"
89+
end TestGoBinaryStackUrl
90+
91+
on TestGoScriptOnlyStackUrl
92+
_TestGoStackUrl "script only"
93+
end TestGoScriptOnlyStackUrl

0 commit comments

Comments
 (0)