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

Commit eb3a8d5

Browse files
author
livecodeali
committed
[[ Bug 9778 ]] Correct code path for 'cut tVar'
1 parent 16a928c commit eb3a8d5

File tree

3 files changed

+117
-71
lines changed

3 files changed

+117
-71
lines changed

docs/notes/bugfix-9778.md

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

engine/src/cmdsc.cpp

Lines changed: 82 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -438,90 +438,101 @@ void MCClipboardCmd::exec_ctxt(MCExecContext& ctxt)
438438
else
439439
MCPasteboardExecCopy(ctxt);
440440
}
441-
else if (targets -> istextchunk())
441+
else
442442
{
443-
// Explicit form (1) - text chunk-
444-
if (targets -> next != NULL)
445-
{
446-
ctxt . LegacyThrow(EE_CLIPBOARD_BADMIX);
447-
return;
448-
}
449-
450-
MCObjectChunkPtr t_obj_chunk;
451-
452-
if (!targets -> evalobjectchunk(ctxt, true, false, t_obj_chunk))
453-
{
454-
ctxt . LegacyThrow(EE_CLIPBOARD_BADTEXT);
443+
// Parse the first chunk before determining if we have a text
444+
// chunk or not - otherwise things like 'cut tVar' where
445+
// tVar contains 'line x of field y' do not go through the
446+
// correct code path.
447+
MCObjectPtr t_first_object;
448+
if (!targets -> getobj(ctxt, t_first_object, True))
455449
return;
456-
}
457-
458-
if (iscut())
459-
MCPasteboardExecCutTextToClipboard(ctxt, t_obj_chunk);
460-
else
461-
MCPasteboardExecCopyTextToClipboard(ctxt, t_obj_chunk);
462-
463-
MCValueRelease(t_obj_chunk . mark . text);
464-
}
465-
else
466-
{
467-
// Explicit form (2)/(3) - object chunks
468-
469-
MCChunk *chunkptr = targets;
470-
MCObjectPtr t_object;
471-
MCAutoArray<MCObjectPtr> t_objects;
472450

473-
while (chunkptr != NULL)
474-
{
475-
if (chunkptr -> istextchunk())
476-
{
451+
if (targets -> istextchunk())
452+
{
453+
// Explicit form (1) - text chunk-
454+
if (targets -> next != NULL)
455+
{
477456
ctxt . LegacyThrow(EE_CLIPBOARD_BADMIX);
478-
return;
479-
}
457+
return;
458+
}
480459

481-
if (!chunkptr -> getobj(ctxt, t_object, True))
460+
MCObjectChunkPtr t_obj_chunk;
461+
462+
if (!targets -> evalobjectchunk(ctxt, true, false, t_obj_chunk))
482463
{
483-
ctxt . LegacyThrow(EE_CLIPBOARD_BADOBJ);
464+
ctxt . LegacyThrow(EE_CLIPBOARD_BADTEXT);
484465
return;
485466
}
486-
487-
if (!t_objects . Push(t_object))
488-
{
489-
ctxt . LegacyThrow(EE_NO_MEMORY);
490-
break;
491-
}
492467

493-
chunkptr = chunkptr->next;
494-
}
495-
496-
// Calculate destination object (if applicable)
497-
MCObjectPtr t_dst_object;
498-
if (dest != NULL)
468+
if (iscut())
469+
MCPasteboardExecCutTextToClipboard(ctxt, t_obj_chunk);
470+
else
471+
MCPasteboardExecCopyTextToClipboard(ctxt, t_obj_chunk);
472+
473+
MCValueRelease(t_obj_chunk . mark . text);
474+
}
475+
else
499476
{
500-
if (!dest -> getobj(ctxt, t_dst_object, True))
477+
// Explicit form (2)/(3) - object chunks
478+
479+
MCChunk *chunkptr = targets;
480+
MCObjectPtr t_object;
481+
MCAutoArray<MCObjectPtr> t_objects;
482+
483+
while (chunkptr != NULL)
501484
{
502-
ctxt . LegacyThrow(EE_CLIPBOARD_BADOBJ);
503-
return;
485+
if (chunkptr -> istextchunk())
486+
{
487+
ctxt . LegacyThrow(EE_CLIPBOARD_BADMIX);
488+
return;
489+
}
490+
491+
if (!chunkptr -> getobj(ctxt, t_object, True))
492+
{
493+
ctxt . LegacyThrow(EE_CLIPBOARD_BADOBJ);
494+
return;
495+
}
496+
497+
if (!t_objects . Push(t_object))
498+
{
499+
ctxt . LegacyThrow(EE_NO_MEMORY);
500+
break;
501+
}
502+
503+
chunkptr = chunkptr->next;
504+
}
505+
506+
// Calculate destination object (if applicable)
507+
MCObjectPtr t_dst_object;
508+
if (dest != NULL)
509+
{
510+
if (!dest -> getobj(ctxt, t_dst_object, True))
511+
{
512+
ctxt . LegacyThrow(EE_CLIPBOARD_BADOBJ);
513+
return;
514+
}
515+
}
516+
517+
if (t_objects . Size() > 0)
518+
{
519+
if (dest != NULL)
520+
{
521+
if (iscut())
522+
MCInterfaceExecCutObjectsToContainer(ctxt, t_objects . Ptr(), t_objects . Size(), t_dst_object);
523+
else
524+
MCInterfaceExecCopyObjectsToContainer(ctxt, t_objects . Ptr(), t_objects . Size(), t_dst_object);
525+
}
526+
else
527+
{
528+
if (iscut())
529+
MCPasteboardExecCutObjectsToClipboard(ctxt, t_objects . Ptr(), t_objects . Size());
530+
else
531+
MCPasteboardExecCopyObjectsToClipboard(ctxt, t_objects . Ptr(), t_objects . Size());
532+
}
504533
}
505534
}
506-
507-
if (t_objects . Size() > 0)
508-
{
509-
if (dest != NULL)
510-
{
511-
if (iscut())
512-
MCInterfaceExecCutObjectsToContainer(ctxt, t_objects . Ptr(), t_objects . Size(), t_dst_object);
513-
else
514-
MCInterfaceExecCopyObjectsToContainer(ctxt, t_objects . Ptr(), t_objects . Size(), t_dst_object);
515-
}
516-
else
517-
{
518-
if (iscut())
519-
MCPasteboardExecCutObjectsToClipboard(ctxt, t_objects . Ptr(), t_objects . Size());
520-
else
521-
MCPasteboardExecCopyObjectsToClipboard(ctxt, t_objects . Ptr(), t_objects . Size());
522-
}
523-
}
524-
}
535+
}
525536
}
526537

527538
void MCClipboardCmd::compile(MCSyntaxFactoryRef ctxt)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
script "CoreChunksCut"
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 TestCutVar
20+
create field
21+
put "a" & return & "b" into field 1
22+
23+
local tToCut
24+
put "line 1 of field 1" into tToCut
25+
26+
cut tToCut
27+
28+
TestDiagnostic field 1
29+
TestDiagnostic the clipboardData["text"]
30+
31+
TestAssert "cut obj text chunk in variable", field 1 is "b"
32+
TestAssert "clipboard after cut obj text chunk in variable", \
33+
the clipboardData["text"] is ("a" & return)
34+
end TestCutVar

0 commit comments

Comments
 (0)