summaryrefslogtreecommitdiff
path: root/test/lisp/progmodes/python-tests.el
diff options
context:
space:
mode:
authorPhilipp Stephani <phst@google.com>2017-02-28 22:21:37 +0100
committerPhilipp Stephani <phst@google.com>2017-03-23 23:05:19 +0100
commit4fbd330fae54a9c45d4a717127aa86d75e9938d5 (patch)
tree7af5dde9a3194b504fe6b837a6339b7683d8efa6 /test/lisp/progmodes/python-tests.el
parentaa0fb4fed8ef1f3599f573476fc6291f8872c7e7 (diff)
downloademacs-4fbd330fae54a9c45d4a717127aa86d75e9938d5.tar.gz
Protect against an infloop in python-mode
There appears to be an edge case caused by using `syntax-ppss' in a narrowed buffer during JIT lock inside of Python triple-quote strings. Unfortunately it is impossible to reproduce without manually destroying the syntactic information in the Python buffer, but it has been observed in practice. In that case it can happen that the syntax caches get sufficiently out of whack so that there appear to be overlapping strings in the buffer. As Python has no nested strings, this situation is impossible and leads to an infloop in `python-nav-end-of-statement'. Protect against this by checking whether the search for the end of the current string makes progress. * python.el (python-nav-end-of-statement): Protect against infloop. * progmodes/python-tests.el (python-tests--python-nav-end-of-statement--infloop): Add unit test.
Diffstat (limited to 'test/lisp/progmodes/python-tests.el')
-rw-r--r--test/lisp/progmodes/python-tests.el19
1 files changed, 19 insertions, 0 deletions
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 1e6b867d30b..2f4c2fb849d 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -5314,6 +5314,25 @@ class SomeClass:
(or enabled (hs-minor-mode -1)))))
+(ert-deftest python-tests--python-nav-end-of-statement--infloop ()
+ "Checks that `python-nav-end-of-statement' doesn't infloop in a
+buffer with overlapping strings."
+ (python-tests-with-temp-buffer "''' '\n''' ' '\n"
+ (syntax-propertize (point-max))
+ ;; Create a situation where strings nominally overlap. This
+ ;; shouldn't happen in practice, but apparently it can happen when
+ ;; a package calls `syntax-ppss' in a narrowed buffer during JIT
+ ;; lock.
+ (put-text-property 4 5 'syntax-table (string-to-syntax "|"))
+ (remove-text-properties 8 9 '(syntax-table nil))
+ (goto-char 4)
+ (setq-local syntax-propertize-function nil)
+ ;; The next form should not infloop. We have to disable
+ ;; ‘debug-on-error’ so that ‘cl-assert’ doesn’t call the debugger.
+ (should-error (let ((debug-on-error nil))
+ (python-nav-end-of-statement)))
+ (should (eolp))))
+
(provide 'python-tests)