From: Eli Zaretskii Date: Sun, 7 Nov 2021 12:22:15 +0000 (+0200) Subject: Improve detection of suspiciously reordered text segments X-Git-Tag: emacs-29.0.90~3671^2~110 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=75f4af0b303418f7bf107741684ea50b8c52b7f7;p=emacs.git Improve detection of suspiciously reordered text segments * 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. --- diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 7a6bfa58ada..089decb83c8 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -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 diff --git a/src/bidi.c b/src/bidi.c index 511b4602fec..890a60acc43 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -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 diff --git a/test/src/xdisp-tests.el b/test/src/xdisp-tests.el index 4a87f19cabb..cc67aef8e15 100644 --- a/test/src/xdisp-tests.el +++ b/test/src/xdisp-tests.el @@ -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