Commit 957ed5e

Nick committed on
Properly handle invalid clipboard data (fixes #43)
commit 957ed5eb7a152fa2f258c22521aea4ba6af21765 parent 9fa0637
2 changed files +53−22
Modifiedclipboardutils.pas +23−15
@@ -7,6 +7,9 @@ interface
7 uses 7 uses
8 Classes, SysUtils, Constants, Clipbrd, HugeDatatypes, Utils; 8 Classes, SysUtils, Constants, Clipbrd, HugeDatatypes, Utils;
9 9
10 type
11 EClipboardFormatException = class(Exception);
12
10 function GetPastedCells: TSelection; 13 function GetPastedCells: TSelection;
11 procedure CopyCells(Selection: TSelection); 14 procedure CopyCells(Selection: TSelection);
12 15
@@ -59,21 +62,26 @@ var
59 begin 62 begin
60 SL := TStringList.Create; 63 SL := TStringList.Create;
61 try 64 try
62 SL.Text := Clipboard.AsText; 65 try
63 66 SL.Text := Clipboard.AsText;
64 // Delete lines until we reach the note data 67
65 while not SL.Strings[0].StartsWith('|') do 68 // Delete lines until we reach the note data
66 SL.Delete(0); 69 while not SL.Strings[0].StartsWith('|') do
67 SetLength(Result, SL.Count); 70 SL.Delete(0);
68 71 SetLength(Result, SL.Count);
69 I := 0; 72
70 for Row in SL do begin 73 I := 0;
71 StringCells := Row.Split('|'); 74 for Row in SL do begin
72 75 StringCells := Row.Split('|');
73 SetLength(Result[I], Length(StringCells)-1); 76
74 for J := 0 to High(StringCells)-1 do 77 SetLength(Result[I], Length(StringCells)-1);
75 Result[I, J] := ParseCell(StringCells[J+1]); 78 for J := 0 to High(StringCells)-1 do
76 Inc(I); 79 Result[I, J] := ParseCell(StringCells[J+1]);
80 Inc(I);
81 end;
82 except
83 on E: Exception do
84 raise EClipboardFormatException.Create('Clipboard contained invalid data!');
77 end; 85 end;
78 finally 86 finally
79 SL.Free; 87 SL.Free;
Modifiedtrackergrid.pas +30−7
@@ -88,6 +88,7 @@ type
88 procedure DoCut(var Msg: TLMessage); message LM_CUT; 88 procedure DoCut(var Msg: TLMessage); message LM_CUT;
89 procedure BeginUndoAction; 89 procedure BeginUndoAction;
90 procedure EndUndoAction; 90 procedure EndUndoAction;
91 procedure RevertUndoAction;
91 92
92 procedure RenderSelectedArea; 93 procedure RenderSelectedArea;
93 procedure ClampCursors; 94 procedure ClampCursors;
@@ -560,12 +561,20 @@ var
560 begin 561 begin
561 BeginUndoAction; 562 BeginUndoAction;
562 563
563 Selection := GetPastedCells; 564 try
564 I := Cursor.Y; 565 Selection := GetPastedCells;
565 while I <= High(TPattern) do begin 566 I := Cursor.Y;
566 Cursor.Y := I; 567 while I <= High(TPattern) do begin
567 PerformPaste(Selection); 568 Cursor.Y := I;
568 Inc(I, High(Selection)+1); 569 PerformPaste(Selection);
570 Inc(I, High(Selection)+1);
571 end;
572 except
573 on E: EClipboardFormatException do begin
574 WriteLn(StdErr, '[WARNING] ', E.Message);
575 RevertUndoAction;
576 Exit
577 end;
569 end; 578 end;
570 579
571 Invalidate; 580 Invalidate;
@@ -576,7 +585,15 @@ procedure TTrackerGrid.DoPaste(var Msg: TLMessage);
576 begin 585 begin
577 BeginUndoAction; 586 BeginUndoAction;
578 587
579 PerformPaste(GetPastedCells); 588 try
589 PerformPaste(GetPastedCells);
590 except
591 on E: EClipboardFormatException do begin
592 WriteLn(StdErr, '[WARNING] ', E.Message);
593 RevertUndoAction;
594 Exit
595 end;
596 end;
580 597
581 Invalidate; 598 Invalidate;
582 EndUndoAction; 599 EndUndoAction;
@@ -638,6 +655,12 @@ begin
638 Dec(NestedUndoCount); 655 Dec(NestedUndoCount);
639 end; 656 end;
640 657
658 procedure TTrackerGrid.RevertUndoAction;
659 begin
660 // Don't save the undo action, just decrement the nested undo count.
661 Dec(NestedUndoCount);
662 end;
663
641 procedure TTrackerGrid.DoUndo; 664 procedure TTrackerGrid.DoUndo;
642 var 665 var
643 State: TUndoRedoAction; 666 State: TUndoRedoAction;