]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve detection of suspiciously reordered text segments
authorEli Zaretskii <eliz@gnu.org>
Sun, 7 Nov 2021 12:22:15 +0000 (14:22 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sun, 7 Nov 2021 12:22:15 +0000 (14:22 +0200)
* src/bidi.c (bidi_find_first_overridden): Detect reordered weak
and neutral characters as well.

* lisp/international/mule-cmds.el
(highlight-confusing-reorderings): Count and announce how many
instances were found.

* test/src/xdisp-tests.el
(xdisp-tests--find-directional-overrides-case-3): New test.
(xdisp-tests--find-directional-overrides-case-2): Adjust expected
result.

lisp/international/mule-cmds.el
src/bidi.c
test/src/xdisp-tests.el

index 7a6bfa58ada835716c1b9e834fe3d429d983d866..089decb83c8c31c38d823e2e0fba93004c51fe51 100644 (file)
@@ -3318,7 +3318,8 @@ or the active region if that is set."
                                               (prop-match-end prop-match)
                                               '(font-lock-face face mouse-face
                                                                help-echo)))))
-      (let (next)
+      (let ((count 0)
+            next)
         (goto-char beg)
         (while (setq next
                      (bidi-find-overridden-directionality
@@ -3358,6 +3359,15 @@ or the active region if that is set."
                                      help-echo "\
 This text is reordered on display in a way that could change its semantics;
 use \\[forward-char] and \\[backward-char] to see the actual order of characters.")))
-            (goto-char finish)))))))
+            (goto-char finish)
+            (setq count (1+ count))))
+        (message
+         (if (> count 0)
+             (ngettext
+              "Highlighted %d confusingly-reordered text string"
+              "Highlighted %d confusingly-reordered text strings"
+              count)
+           "No confusingly-reordered text strings were found")
+         count)))))
 
 ;;; mule-cmds.el ends here
index 511b4602fec9162db541296ae88de3c2d34290dd..890a60acc43b4562b5ae60b80615eae7d21893b3 100644 (file)
@@ -3575,6 +3575,8 @@ bidi_find_first_overridden (struct bidi_it *bidi_it)
      overrides, and isolates, i.e. before resolving implicit levels.  */
   int max_l2r = bidi_it->paragraph_dir == L2R ? 0 : 2;
   int max_r2l = 1;
+  /* Same for WEAK and NEUTRAL_ON types.  */
+  int max_weak = bidi_it->paragraph_dir == L2R ? 1 : 2;
 
   do
     {
@@ -3582,6 +3584,8 @@ bidi_find_first_overridden (struct bidi_it *bidi_it)
         because the directional overrides are applied by the
         former.  */
       bidi_type_t type = bidi_resolve_weak (bidi_it);
+      unsigned level = bidi_it->level_stack[bidi_it->stack_idx].level;
+      bidi_category_t category = bidi_get_category (bidi_it->orig_type);
 
       /* Detect strong L or R types that have been overridden by
         explicit overrides.  */
@@ -3594,10 +3598,14 @@ bidi_find_first_overridden (struct bidi_it *bidi_it)
             reorder) by explicit embeddings and isolates.  */
          || ((bidi_it->orig_type == STRONG_L
               || bidi_it->orig_type == WEAK_EN)
-             && bidi_it->level_stack[bidi_it->stack_idx].level > max_l2r)
+             && level > max_l2r)
          || ((bidi_it->orig_type == STRONG_R
               || bidi_it->orig_type == STRONG_AL)
-             && bidi_it->level_stack[bidi_it->stack_idx].level > max_r2l))
+             && level > max_r2l)
+         /* Detect other weak or neutral types whose level was
+            tweaked by explicit embeddings and isolates.  */
+         || ((category == WEAK || bidi_it->orig_type == NEUTRAL_ON)
+             && level > max_weak))
        found_pos = bidi_it->charpos;
     } while (found_pos == ZV
             && bidi_it->charpos < ZV
index 4a87f19cabb4d7cb05d62fc8ca7d2a6fbbe1d204..cc67aef8e15a87af20e7f38ae3d07afef6ee6eb8 100644 (file)
@@ -132,6 +132,26 @@ int main () {
     (goto-char (point-min))
     (should (eq (bidi-find-overridden-directionality (point-min) (point-max)
                                                      nil)
-                140))))
+                138))))
+
+(ert-deftest xdisp-tests--find-directional-overrides-case-3 ()
+  (with-temp-buffer
+    (insert "\
+#define is_restricted_user(user)                       \\
+  !strcmp (user, \"root\") ? 0 :                       \\
+  !strcmp (user, \"admin\") ? 0 :                      \\
+  !strcmp (user, \"superuser‮⁦? '#' : '!'⁩ ⁦\")⁩‬
+
+int main () {
+  printf (\"root: %d\\n\", is_restricted_user (\"root\"));
+  printf (\"admin: %d\\n\", is_restricted_user (\"admin\"));
+  printf (\"superuser: %d\\n\", is_restricted_user (\"superuser\"));
+  printf (\"luser: %d\\n\", is_restricted_user (\"luser\"));
+  printf (\"nobody: %d\\n\", is_restricted_user (\"nobody\"));
+}")
+    (goto-char (point-min))
+    (should (eq (bidi-find-overridden-directionality (point-min) (point-max)
+                                                     nil)
+                138))))
 
 ;;; xdisp-tests.el ends here