* Bug 16549 fixed: simple script crashed Scilab in GUI mode 82/21582/8
mottelet [Thu, 1 Oct 2020 10:13:51 +0000 (12:13 +0200)]
https://bugzilla.scilab.org/show_bug.cgi?id=16549

This patch fixes the problem and reconsiders the processing
of carriage returns in Scilab output. Only the last occurence was
considered in https://codereview.scilab.org/#/c/21166/

Now the output is exactly the same in GUI and CLI mode:

--> mprintf("%s\n123456\rabc\rZ",getscilabmode())
STD
Zbc456

--> mprintf("%s\n123456\rabc\rZ",getscilabmode())
NW
Zbc456

Moreover, one line counter display is now supported in all modes:

for i=1:10000; mprintf("%05d\r",i);end

Change-Id: I82f05d115afc2911466b52230cd667dee3397db2

scilab/CHANGES.md
scilab/modules/console/src/java/org/scilab/modules/console/SciOutputView.java
scilab/modules/console/tests/nonreg_tests/bug_16549.tst [new file with mode: 0644]

index 131077e..ad1edac 100644 (file)
@@ -327,6 +327,7 @@ Bug Fixes
 * [#16517](https://bugzilla.scilab.org/16517): `getdate("s")` truncated the actual time to integer seconds. `getdate(u)(10)` returned fractional seconds instead of milliseconds as `getdate()`.
 * [#16522](https://bugzilla.scilab.org/16522): `bitget(x,pos)` and `bitset(x,pos)` results could be wrong when `pos` is an encoded integer.
 * [#16525](https://bugzilla.scilab.org/16525): `soundsec(t,freq)` has the trivial equivalence `0 : 1/freq : t*(1-%eps)` and should be removed.
+* [#16549](https://bugzilla.scilab.org/16549): simple script crashed Scilab in GUI mode.
 
 
 ### Bugs fixed in 6.1.0:
index 050d619..e673211 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2007-2008 - INRIA - Vincent COUVERT
  *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2020 - St├ęphane Mottelet
  *
  * This file is hereby licensed under the terms of the GNU GPL v2.0,
  * pursuant to article 5.3.4 of the CeCILL v.2.1.
@@ -218,42 +219,31 @@ public class SciOutputView extends JEditorPane implements OutputView, ViewFactor
      */
     private void displayLineBuffer(String buff, String style) {
         int sDocLength = getDocument().getLength();
+        boolean bEndsWithCR  = false;
+
+        // replace all CR+LF occurences by a LF
+        buff = buff.replaceAll("\r\n","\n");
+        bEndsWithCR  = buff.endsWith("\r");
+
+        // special case of leading \r but nothing printed yet
+        if (buff.startsWith("\r") & lastEOL == false) {
+          try {
+              String outputTxt = getDocument().getText(0,  getDocument().getLength());
+              insertPosition = outputTxt.lastIndexOf(StringConstants.NEW_LINE) + 1;
+          } catch (BadLocationException e) {
+              e.printStackTrace();
+          }
+        }
 
-        if (buff.equals("\r")) {
-            /* If \r sent by mprintf then display nothing but prepare next display */
-            /* Insertion will be done just after last NEW_LINE */
-            try {
-                String outputTxt = getDocument().getText(0, sDocLength);
-                insertPosition = outputTxt.lastIndexOf(StringConstants.NEW_LINE) + 1;
-            } catch (BadLocationException e) {
-                e.printStackTrace();
-            }
-            return;
-        } else if (buff.contains("\r")) {
-            /* If \r is part of the buff then perform CR on to the buff */
-            int n = buff.lastIndexOf("\r");
-            buff = buff.substring(n + 1) + buff.substring(buff.length() - n - 1, n) + "\r";
-
-        } else {
-            /* Change position for insertion if a previous \r still influence display */
-            if ((insertPosition != 0) && (insertPosition < sDocLength)) {
-                sDocLength = insertPosition;
-                try {
-                    /* Remove chars to be replaced */
-                    if (!buff.equals("\n")) {
-                        if ((insertPosition + buff.length() == getDocument().getLength())) {
-                            getDocument().remove(insertPosition, buff.length());
-                        } else {
-                            getDocument().remove(insertPosition, getDocument().getLength() - insertPosition);
-                        }
-                    }
-                } catch (BadLocationException e) {
-                    e.printStackTrace();
-                }
-            } else {
-                /* Reinit insertPosition: 0 is equivalent to insertPosition value ignored */
-                insertPosition = 0;
-            }
+        // successively apply carriage returns to the buffer by splitting it with '\r' as a separator
+        // the case buff == "\r" is considered at the end of the method
+        if (buff.contains("\r") & buff.length() > 1) {
+          String tokens[] = buff.split("\r");
+          buff = tokens[0];
+          for (int i=1; i<tokens.length;i++)
+          {
+            buff = tokens[i] + (buff.length() >= tokens[i].length() ? buff.substring(tokens[i].length()) : "");
+          }
         }
 
         boolean slastEOL = lastEOL;
@@ -267,6 +257,26 @@ public class SciOutputView extends JEditorPane implements OutputView, ViewFactor
             str = "\n" + str;
         }
 
+        /* Change position for insertion if a previous \r still influence display */
+        if ((insertPosition != 0) && (insertPosition < sDocLength)) {
+            sDocLength = insertPosition;
+            try {
+                /* Remove chars to be replaced */
+                if (!str.equals("\n")) {
+                    if ((insertPosition + str.length() <= getDocument().getLength())) {
+                        getDocument().remove(insertPosition, str.length());
+                    } else {
+                        getDocument().remove(insertPosition, getDocument().getLength() - insertPosition);
+                    }
+                }
+            } catch (BadLocationException e) {
+                e.printStackTrace();
+            }
+        } else {
+            /* Reinit insertPosition: 0 is equivalent to insertPosition value ignored */
+            insertPosition = 0;
+        }
+
         try {
             getDocument().insertString(sDocLength, str, null);
 
@@ -294,6 +304,15 @@ public class SciOutputView extends JEditorPane implements OutputView, ViewFactor
                 e.printStackTrace();
             }
         }
+
+        if (bEndsWithCR) {
+          try {
+              String outputTxt = getDocument().getText(0,  getDocument().getLength());
+              insertPosition = outputTxt.lastIndexOf(StringConstants.NEW_LINE) + 1;
+          } catch (BadLocationException e) {
+              e.printStackTrace();
+          }
+        }
     }
 
     /**
diff --git a/scilab/modules/console/tests/nonreg_tests/bug_16549.tst b/scilab/modules/console/tests/nonreg_tests/bug_16549.tst
new file mode 100644 (file)
index 0000000..c96c8b9
--- /dev/null
@@ -0,0 +1,23 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - St├ęphane Mottelet
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 16549 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/16549
+//
+// <-- Short Description -->
+// Simple script crashes Scilab in GUI mode
+//
+
+// line must end with CR+LF
+
+mputl("l=;"+ascii([13 10]),TMPDIR+"/test.sce");
+err = exec(TMPDIR+"/test.sce", "errcatch", -1);
+assert_checktrue(err <> 0);
\ No newline at end of file