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

Commit 0f8cf94

Browse files
committed
[[ Bug 17652 ]] Correct code path for 'delete tVar'
When the latter contained an object text chunk, it would select the 'delete object' code path as the variable contents were not parsed as a chunk before selection. Also reinstate fix for bug 11928 which was lost in the refactoring - its absence was causing 'delete tVar' to work exactly once.
1 parent c2ed21a commit 0f8cf94

File tree

4 files changed

+101
-48
lines changed

4 files changed

+101
-48
lines changed

docs/notes/bugfix-17652.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Fix 'delete tVar' where tVar contains an object text chunk

engine/src/chunk.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4931,6 +4931,9 @@ bool MCChunk::issubstringchunk(void) const
49314931
if (destvar == nil)
49324932
return false;
49334933

4934+
if (m_transient_text_chunk)
4935+
return false;
4936+
49344937
if (isstringchunk() || isdatachunk())
49354938
return true;
49364939

engine/src/cmdsc.cpp

Lines changed: 59 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,59 +1725,70 @@ void MCDelete::exec_ctxt(MCExecContext& ctxt)
17251725
MCValueRelease(t_chunks[i] . mark . text);
17261726
}
17271727
}
1728-
else if (targets != nil && targets -> istextchunk())
1728+
else if (targets != nil)
17291729
{
1730-
MCAutoArray<MCObjectChunkPtr> t_chunks;
1731-
bool t_return;
1732-
t_return = false;
1733-
for(MCChunk *t_chunk = targets; t_chunk != nil && !t_return; t_chunk = t_chunk -> next)
1734-
{
1735-
if (!t_chunk -> istextchunk())
1736-
{
1737-
ctxt . LegacyThrow(EE_CLIPBOARD_BADMIX);
1738-
t_return = true;
1739-
break;
1740-
}
1730+
// Parse the first chunk before determining if we have a text
1731+
// chunk or not - otherwise things like 'delete tVar' where
1732+
// tVar contains 'line x of field y' do not go through the
1733+
// correct code path.
1734+
MCObjectPtr t_first_object;
1735+
if (!targets -> getobj(ctxt, t_first_object, True))
1736+
return;
1737+
1738+
if (targets -> istextchunk())
1739+
{
1740+
MCAutoArray<MCObjectChunkPtr> t_chunks;
1741+
bool t_return;
1742+
t_return = false;
1743+
for(MCChunk *t_chunk = targets; t_chunk != nil && !t_return; t_chunk = t_chunk -> next)
1744+
{
1745+
if (!t_chunk -> istextchunk())
1746+
{
1747+
ctxt . LegacyThrow(EE_CLIPBOARD_BADMIX);
1748+
t_return = true;
1749+
break;
1750+
}
1751+
1752+
MCObjectChunkPtr t_obj_chunk;
1753+
if (!t_chunk -> evalobjectchunk(ctxt, true, false, t_obj_chunk))
1754+
{
1755+
t_return = true;
1756+
break;
1757+
}
1758+
1759+
if (!t_chunks . Push(t_obj_chunk))
1760+
{
1761+
ctxt . LegacyThrow(EE_NO_MEMORY);
1762+
MCValueRelease(t_obj_chunk . mark . text);
1763+
break;
1764+
}
1765+
}
17411766

1742-
MCObjectChunkPtr t_obj_chunk;
1743-
if (!t_chunk -> evalobjectchunk(ctxt, true, false, t_obj_chunk))
1767+
if (!t_return)
1768+
MCInterfaceExecDeleteObjectChunks(ctxt, t_chunks . Ptr(), t_chunks . Size());
1769+
1770+
for (uindex_t i = 0; i < t_chunks . Size(); ++i)
1771+
MCValueRelease(t_chunks[i] . mark . text);
1772+
}
1773+
else
1774+
{
1775+
MCAutoArray<MCObjectPtr> t_objects;
1776+
for(MCChunk *t_chunk = targets; t_chunk != nil; t_chunk = t_chunk -> next)
17441777
{
1745-
t_return = true;
1746-
break;
1778+
MCObjectPtr t_object;
1779+
if (!t_chunk -> getobj(ctxt, t_object, True))
1780+
return;
1781+
1782+
if (!t_objects . Push(t_object))
1783+
{
1784+
ctxt . LegacyThrow(EE_NO_MEMORY);
1785+
break;
1786+
}
17471787
}
17481788

1749-
if (!t_chunks . Push(t_obj_chunk))
1750-
{
1751-
ctxt . LegacyThrow(EE_NO_MEMORY);
1752-
MCValueRelease(t_obj_chunk . mark . text);
1753-
break;
1754-
}
1755-
}
1756-
1757-
if (!t_return)
1758-
MCInterfaceExecDeleteObjectChunks(ctxt, t_chunks . Ptr(), t_chunks . Size());
1759-
1760-
for (uindex_t i = 0; i < t_chunks . Size(); ++i)
1761-
MCValueRelease(t_chunks[i] . mark . text);
1762-
}
1763-
else if (targets != nil)
1764-
{
1765-
MCAutoArray<MCObjectPtr> t_objects;
1766-
for(MCChunk *t_chunk = targets; t_chunk != nil; t_chunk = t_chunk -> next)
1767-
{
1768-
MCObjectPtr t_object;
1769-
if (!t_chunk -> getobj(ctxt, t_object, True))
1770-
return;
1771-
1772-
if (!t_objects . Push(t_object))
1773-
{
1774-
ctxt . LegacyThrow(EE_NO_MEMORY);
1775-
break;
1776-
}
1777-
}
1778-
1779-
MCInterfaceExecDeleteObjects(ctxt, t_objects . Ptr(), t_objects . Size());
1780-
}
1789+
MCInterfaceExecDeleteObjects(ctxt, t_objects . Ptr(), t_objects . Size());
1790+
}
1791+
}
17811792
else if (session)
17821793
{
17831794
#ifdef _SERVER
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
script "CoreChunksDelete"
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 TestDeleteVar
20+
create field
21+
put "a" & return & "b" into field 1
22+
23+
local tToDelete
24+
put "line 1 of field 1" into tToDelete
25+
26+
delete tToDelete
27+
28+
TestAssert "delete obj text chunk in variable", field 1 is "b"
29+
30+
delete tToDelete
31+
32+
-- ensure left-over components from chunk evaluation are not re-used
33+
-- See bug 11928
34+
TestAssert "delete obj text chunk in variable again", field 1 is empty
35+
end TestDeleteVar
36+
37+
38+

0 commit comments

Comments
 (0)