Repository: spyder-ide/spyder

Issue:
Repeatable segfault while editing HTML file
_From [techtonik@gmail.com](https://code.google.com/u/techtonik@gmail.com/) on 2013-06-26T14:36:03Z_

Spyder Version:  2.3.0dev3 (2872: rfe6f59363a2b )
Python Version:  2.7.4
Qt Version:      4.8.4, PyQt4 (API v1) 4.10 on Linux (Ubuntu 13.04) 

What steps will reproduce the problem?
1. The attache file is just
   <table>
   </table>
   1. Try to edit it to become
      <table -->
      </table> What is the expected output? What do you see instead? Spyder fails with segfault once a first ' -' is entered.
      <table ->
      </table>

Please provide any additional information below

.
The bug did not repeat after I restarted Spyder, and hit ? -> Report bug.. to open this page.

I attach debug logs, and I am afraid I don't know what to do next.

**Attachment:** [crash.html gdb.txt](http://code.google.com/p/spyderlib/issues/detail?id=1462)

_Original issue: http://code.google.com/p/spyderlib/issues/detail?id=1462_



Discussion:
_From [stonebi...@gmail.com](https://code.google.com/u/116068254323340012360/) on 2013-12-12T10:25:36Z_

remark  : if you do
2.  
<table>t
</table>
3.
<table ->t
</table>
4.
<table ->
</table>

It doesn't crash.

_From [contrebasse](https://code.google.com/u/contrebasse/) on 2013-12-12T12:55:20Z_

I can reproduce this bug, but it segfaults when I enter the second '-', I have no problem with the first one.
It doesn't crash if the file has a .py extension rather than html.

I managed to have an error in the internal console (and no crash) by doing :
1.
<!-- table>
</table>
2.
<!-- table -->
</table>
3.
<!- table -->
</table>

Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/spyderlib/widgets/sourcecode/syntaxhighlighters.py", line 840, in highlightBlock
    self.formats[key])
KeyError: 'multiline_comment_end'

As the crash is only with .html file, I suppose that the crash is also due to the syntax highlighting when the file is invalid.

I have:
Spyder Version:  2.3.0dev (today's last mater)
Python Version:  2.7.6
Qt Version    :  4.8.5, PyQt4 (API v2) 4.10.3 on Linux
pyflakes >=0.5.0:  0.7.3 (OK)
pep8 >=0.6      :  1.4.6 (OK)
IPython >=0.13  :  1.1.0 (OK)
rope >=0.9.2    :  0.9.4 (OK)
sphinx >=0.6.6  :  1.1.3 (OK)
matplotlib >=1.0:  1.3.1 (OK)
sympy >=0.7.0   :  0.7.4 (OK)
pylint >=0.25   :  1.0.0 (OK)

_From [ccordoba12](https://code.google.com/u/ccordoba12/) on 2015-01-02T19:04:22Z_

**Labels:** MS-v2.3.3  

_From [ccordoba12](https://code.google.com/u/ccordoba12/) on 2015-01-09T18:50:55Z_

**Labels:** -MS-v2.3.3 MS-v2.3.4  


Resolving patch:
diff --git a/spyderlib/utils/syntaxhighlighters.py b/spyderlib/utils/syntaxhighlighters.py
--- a/spyderlib/utils/syntaxhighlighters.py
+++ b/spyderlib/utils/syntaxhighlighters.py
@@ -870,8 +870,13 @@ def highlightBlock(self, text):
                                            self.formats["comment"])
                         else:
                             self.setCurrentBlockState(self.NORMAL)
-                            self.setFormat(start, end-start,
-                                           self.formats[key])
+                            try:
+                                self.setFormat(start, end-start,
+                                               self.formats[key])
+                            except KeyError:
+                                # happens with unmatched end-of-comment;
+                                # see issue 1462
+                                pass
             
             match = self.PROG.search(text, match.end())
             match_count += 1
@@ -987,23 +992,3 @@ def guess_pygments_highlighter(filename):
     class GuessedPygmentsSH(PygmentsSH):
         _lexer = lexer
     return GuessedPygmentsSH
-
-
-
-if __name__ == '__main__':
-    # Test Python Outline Explorer comment regexps
-    valid_comments = [
-      '# --- First variant',
-      '#------ 2nd variant',
-      '### 3rd variant'
-    ]
-    invalid_comments = [
-      '#---', '#--------', '#---   ', '# -------'
-    ]
-    for line in valid_comments:
-        if not PythonSH.OECOMMENT.match(line):
-            print("Error matching '%s' as outline comment" % line)
-    for line in invalid_comments:
-        if PythonSH.OECOMMENT.match(line):
-            print("Error: '%s' is matched as outline comment" % line)
-        


Test patch:
diff --git a/spyderlib/utils/tests/test_syntaxhighlighters.py b/spyderlib/utils/tests/test_syntaxhighlighters.py
new file mode 100644
--- /dev/null
+++ b/spyderlib/utils/tests/test_syntaxhighlighters.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright © 2009- The Spyder Development Team
+# Licensed under the terms of the MIT License
+
+"""Tests for syntaxhighlighters.py"""
+
+import pytest
+from qtpy.QtWidgets import QApplication
+from qtpy.QtGui import QTextDocument
+
+from spyderlib.utils.syntaxhighlighters import HtmlSH, PythonSH
+
+def compare_formats(actualFormats, expectedFormats, sh):
+    assert len(actualFormats) == len(expectedFormats)
+    for actual, expected in zip(actualFormats, expectedFormats):
+        assert actual.start == expected[0]
+        assert actual.length == expected[1]
+        # compare formats by looking at foreground colours only
+        assert (actual.format.foreground().color().name()
+                == sh.formats[expected[2]].foreground().color().name())
+
+def test_HtmlSH_basic():
+    txt = '<p style="color:red;">Foo <!--comment--> bar.</p>'
+    doc = QTextDocument(txt)
+    sh = HtmlSH(doc, color_scheme='Spyder')
+    sh.rehighlightBlock(doc.firstBlock())
+
+    # Expected result as list of tuples (begin, length, format)
+    res = [(0, 2, 'builtin'),    # |<p|
+           (2, 6, 'keyword'),    # | style|
+           (8, 1, 'normal'),     # | |
+           (9, 12, 'string'),    # |"color:red;"|
+           (21, 1, 'builtin'),   # |>|
+           (22, 4, 'normal'),    # |Foo |
+           (26, 14, 'comment'),  # |<!--comment-->|
+           (40, 5, 'normal'),    # | bar.|
+           (45, 4, 'builtin')]   # |</p>|
+    compare_formats(doc.firstBlock().layout().additionalFormats(), res, sh)
+
+def test_HtmlSH_unclosed_commend():
+    txt = '-->'
+    doc = QTextDocument(txt)
+    sh = HtmlSH(doc, color_scheme='Spyder')
+    sh.rehighlightBlock(doc.firstBlock())
+    res = [(0, 3, 'normal')]
+    compare_formats(doc.firstBlock().layout().additionalFormats(), res, sh)
+
+@pytest.mark.parametrize('line', ['# --- First variant',
+                                  '#------ 2nd variant',
+                                  '### 3rd variant'])
+def test_python_outline_explorer_comment(line):
+    assert PythonSH.OECOMMENT.match(line)
+
+@pytest.mark.parametrize('line', ['#---', '#--------', '#---   ', '# -------'])
+def test_python_not_an_outline_explorer_comment(line):
+    assert not PythonSH.OECOMMENT.match(line)
+
+
+if __name__ == '__main__':
+    pytest.main()