mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	eslint: Fix unicorn/better-regex.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/better-regex.md Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							a37616e8c6
						
					
				
				
					commit
					0042cf51c1
				
			@@ -1487,7 +1487,7 @@ run_test("on_events", () => {
 | 
			
		||||
        handler(ev);
 | 
			
		||||
 | 
			
		||||
        // video link ids consist of 15 random digits
 | 
			
		||||
        let video_link_regex = /\[translated: Click to join video call\]\(https:\/\/meet.jit.si\/\d{15}\)/;
 | 
			
		||||
        let video_link_regex = /\[translated: Click to join video call]\(https:\/\/meet.jit.si\/\d{15}\)/;
 | 
			
		||||
        assert.match(syntax_to_insert, video_link_regex);
 | 
			
		||||
 | 
			
		||||
        page_params.jitsi_server_url = null;
 | 
			
		||||
@@ -1512,7 +1512,7 @@ run_test("on_events", () => {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        handler(ev);
 | 
			
		||||
        video_link_regex = /\[translated: Click to join video call\]\(example\.zoom\.com\)/;
 | 
			
		||||
        video_link_regex = /\[translated: Click to join video call]\(example\.zoom\.com\)/;
 | 
			
		||||
        assert.match(syntax_to_insert, video_link_regex);
 | 
			
		||||
 | 
			
		||||
        page_params.realm_video_chat_provider =
 | 
			
		||||
@@ -1527,7 +1527,7 @@ run_test("on_events", () => {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        handler(ev);
 | 
			
		||||
        video_link_regex = /\[translated: Click to join video call\]\(\/calls\/bigbluebutton\/join\?meeting_id=%22zulip-1%22&password=%22AAAAAAAAAA%22&checksum=%2232702220bff2a22a44aee72e96cfdb4c4091752e%22\)/;
 | 
			
		||||
        video_link_regex = /\[translated: Click to join video call]\(\/calls\/bigbluebutton\/join\?meeting_id=%22zulip-1%22&password=%22AAAAAAAAAA%22&checksum=%2232702220bff2a22a44aee72e96cfdb4c4091752e%22\)/;
 | 
			
		||||
        assert.match(syntax_to_insert, video_link_regex);
 | 
			
		||||
    })();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -676,19 +676,19 @@ run_test("python_to_js_filter", () => {
 | 
			
		||||
    // to update_realm_filter_rules.
 | 
			
		||||
    markdown.update_realm_filter_rules([["/a(?im)a/g"], ["/a(?L)a/g"]]);
 | 
			
		||||
    let actual_value = marked.InlineLexer.rules.zulip.realm_filters;
 | 
			
		||||
    let expected_value = [/\/aa\/g(?![\w])/gim, /\/aa\/g(?![\w])/g];
 | 
			
		||||
    let expected_value = [/\/aa\/g(?!\w)/gim, /\/aa\/g(?!\w)/g];
 | 
			
		||||
    assert.deepEqual(actual_value, expected_value);
 | 
			
		||||
    // Test case with multiple replacements.
 | 
			
		||||
    markdown.update_realm_filter_rules([
 | 
			
		||||
        ["#cf(?P<contest>[0-9]+)(?P<problem>[A-Z][0-9A-Z]*)", "http://google.com"],
 | 
			
		||||
        ["#cf(?P<contest>\\d+)(?P<problem>[A-Z][\\dA-Z]*)", "http://google.com"],
 | 
			
		||||
    ]);
 | 
			
		||||
    actual_value = marked.InlineLexer.rules.zulip.realm_filters;
 | 
			
		||||
    expected_value = [/#cf([0-9]+)([A-Z][0-9A-Z]*)(?![\w])/g];
 | 
			
		||||
    expected_value = [/#cf(\d+)([A-Z][\dA-Z]*)(?!\w)/g];
 | 
			
		||||
    assert.deepEqual(actual_value, expected_value);
 | 
			
		||||
    // Test incorrect syntax.
 | 
			
		||||
    blueslip.expect(
 | 
			
		||||
        "error",
 | 
			
		||||
        "python_to_js_filter: Invalid regular expression: /!@#@(!#&((!&(@#((?![\\w])/: Unterminated group",
 | 
			
		||||
        "python_to_js_filter: Invalid regular expression: /!@#@(!#&((!&(@#((?!\\w)/: Unterminated group",
 | 
			
		||||
    );
 | 
			
		||||
    markdown.update_realm_filter_rules([["!@#@(!#&((!&(@#(", "http://google.com"]]);
 | 
			
		||||
    actual_value = marked.InlineLexer.rules.zulip.realm_filters;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ const common = require("../puppeteer_lib/common");
 | 
			
		||||
const OUTGOING_WEBHOOK_BOT_TYPE = "3";
 | 
			
		||||
const GENERIC_BOT_TYPE = "1";
 | 
			
		||||
 | 
			
		||||
const zuliprc_regex = /^data:application\/octet-stream;charset=utf-8,\[api\]\nemail=.+\nkey=.+\nsite=.+\n$/;
 | 
			
		||||
const zuliprc_regex = /^data:application\/octet-stream;charset=utf-8,\[api]\nemail=.+\nkey=.+\nsite=.+\n$/;
 | 
			
		||||
 | 
			
		||||
async function get_decoded_url_in_selector(page, selector) {
 | 
			
		||||
    return await page.evaluate(
 | 
			
		||||
@@ -76,7 +76,7 @@ async function test_get_api_key(page) {
 | 
			
		||||
 | 
			
		||||
    await page.waitForSelector("#show_api_key", {visible: true});
 | 
			
		||||
    const api_key = await common.get_text_from_selector(page, "#api_key_value");
 | 
			
		||||
    assert(/[a-zA-Z0-9]{32}/.test(api_key), "Incorrect API key format.");
 | 
			
		||||
    assert(/[\dA-Za-z]{32}/.test(api_key), "Incorrect API key format.");
 | 
			
		||||
 | 
			
		||||
    const download_zuliprc_selector = "#download_zuliprc";
 | 
			
		||||
    await page.click(download_zuliprc_selector);
 | 
			
		||||
@@ -97,7 +97,7 @@ async function test_webhook_bot_creation(page) {
 | 
			
		||||
 | 
			
		||||
    const bot_email = "1-bot@zulip.testserver";
 | 
			
		||||
    const download_zuliprc_selector = '.download_bot_zuliprc[data-email="' + bot_email + '"]';
 | 
			
		||||
    const outgoing_webhook_zuliprc_regex = /^data:application\/octet-stream;charset=utf-8,\[api\]\nemail=.+\nkey=.+\nsite=.+\ntoken=.+\n$/;
 | 
			
		||||
    const outgoing_webhook_zuliprc_regex = /^data:application\/octet-stream;charset=utf-8,\[api]\nemail=.+\nkey=.+\nsite=.+\ntoken=.+\n$/;
 | 
			
		||||
 | 
			
		||||
    await page.waitForSelector(download_zuliprc_selector, {visible: true});
 | 
			
		||||
    await page.click(download_zuliprc_selector);
 | 
			
		||||
@@ -137,7 +137,7 @@ async function test_botserverrc(page) {
 | 
			
		||||
        page,
 | 
			
		||||
        "#download_botserverrc",
 | 
			
		||||
    );
 | 
			
		||||
    const botserverrc_regex = /^data:application\/octet-stream;charset=utf-8,\[\]\nemail=.+\nkey=.+\nsite=.+\ntoken=.+\n$/;
 | 
			
		||||
    const botserverrc_regex = /^data:application\/octet-stream;charset=utf-8,\[]\nemail=.+\nkey=.+\nsite=.+\ntoken=.+\n$/;
 | 
			
		||||
    assert(botserverrc_regex.test(botserverrc_decoded_url), "Incorrect botserverrc format.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,7 @@ function filter_user_ids(user_filter_text, user_ids) {
 | 
			
		||||
 | 
			
		||||
    user_ids = user_ids.filter((user_id) => !people.is_my_user_id(user_id));
 | 
			
		||||
 | 
			
		||||
    let search_terms = user_filter_text.toLowerCase().split(/[|,]+/);
 | 
			
		||||
    let search_terms = user_filter_text.toLowerCase().split(/[,|]+/);
 | 
			
		||||
    search_terms = search_terms.map((s) => s.trim());
 | 
			
		||||
 | 
			
		||||
    const persons = user_ids.map((user_id) => people.get_by_user_id(user_id));
 | 
			
		||||
 
 | 
			
		||||
@@ -100,7 +100,7 @@ exports.copy_data_attribute_value = function (elem, key) {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.has_mac_keyboard = function () {
 | 
			
		||||
    return /Mac/i.test(navigator.platform);
 | 
			
		||||
    return /mac/i.test(navigator.platform);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.adjust_mac_shortcuts = function (key_elem_class, require_cmd_style) {
 | 
			
		||||
 
 | 
			
		||||
@@ -278,7 +278,7 @@ exports.tokenize_compose_str = function (s) {
 | 
			
		||||
            case "_":
 | 
			
		||||
                if (i === 0) {
 | 
			
		||||
                    return s;
 | 
			
		||||
                } else if (/[\s(){}[\]]/.test(s[i - 1])) {
 | 
			
		||||
                } else if (/[\s()[\]{}]/.test(s[i - 1])) {
 | 
			
		||||
                    return s.slice(i);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
@@ -612,7 +612,7 @@ exports.get_candidates = function (query) {
 | 
			
		||||
        // as :P or :-p
 | 
			
		||||
        // Also, if the user has only typed a colon and nothing after,
 | 
			
		||||
        // no need to match yet.
 | 
			
		||||
        if (/^:-.?$/.test(current_token) || /^:[^a-z+]?$/.test(current_token)) {
 | 
			
		||||
        if (/^:-.?$/.test(current_token) || /^:[^+a-z]?$/.test(current_token)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        // Don't autocomplete if there is a space following a ':'
 | 
			
		||||
 
 | 
			
		||||
@@ -317,7 +317,7 @@ exports.paste_handler = function (event) {
 | 
			
		||||
        const paste_html = clipboardData.getData("text/html");
 | 
			
		||||
        if (paste_html && page_params.development_environment) {
 | 
			
		||||
            const text = exports.paste_handler_converter(paste_html);
 | 
			
		||||
            const mdImageRegex = /^!\[.*\]\(.*\)$/;
 | 
			
		||||
            const mdImageRegex = /^!\[.*]\(.*\)$/;
 | 
			
		||||
            if (text.match(mdImageRegex)) {
 | 
			
		||||
                // This block catches cases where we are pasting an
 | 
			
		||||
                // image into Zulip, which is handled by upload.js.
 | 
			
		||||
 
 | 
			
		||||
@@ -30,12 +30,12 @@ const backend_only_markdown_re = [
 | 
			
		||||
    // Inline image previews, check for contiguous chars ending in image suffix
 | 
			
		||||
    // To keep the below regexes simple, split them out for the end-of-message case
 | 
			
		||||
 | 
			
		||||
    /[^\s]*(?:(?:\.bmp|\.gif|\.jpg|\.jpeg|\.png|\.webp)\)?)\s+/m,
 | 
			
		||||
    /[^\s]*(?:(?:\.bmp|\.gif|\.jpg|\.jpeg|\.png|\.webp)\)?)$/m,
 | 
			
		||||
    /\S*(?:\.bmp|\.gif|\.jpg|\.jpeg|\.png|\.webp)\)?\s+/m,
 | 
			
		||||
    /\S*(?:\.bmp|\.gif|\.jpg|\.jpeg|\.png|\.webp)\)?$/m,
 | 
			
		||||
 | 
			
		||||
    // Twitter and youtube links are given previews
 | 
			
		||||
 | 
			
		||||
    /[^\s]*(?:twitter|youtube).com\/[^\s]*/,
 | 
			
		||||
    /\S*(?:twitter|youtube).com\/\S*/,
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
exports.translate_emoticons_to_names = (text) => {
 | 
			
		||||
@@ -88,7 +88,7 @@ exports.contains_backend_only_syntax = function (content) {
 | 
			
		||||
    // then don't render it locally. It is workaround for the fact that
 | 
			
		||||
    // javascript regex doesn't support lookbehind.
 | 
			
		||||
    const false_filter_match = realm_filter_list.find((re) => {
 | 
			
		||||
        const pattern = /(?:[^\s'"(,:<])/.source + re[0].source + /(?![\w])/.source;
 | 
			
		||||
        const pattern = /[^\s"'(,:<]/.source + re[0].source + /(?!\w)/.source;
 | 
			
		||||
        const regex = new RegExp(pattern);
 | 
			
		||||
        return regex.test(content);
 | 
			
		||||
    });
 | 
			
		||||
@@ -237,7 +237,7 @@ exports.add_topic_links = function (message) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Also make raw urls navigable
 | 
			
		||||
    const url_re = /\b(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/g; // Slightly modified from third/marked.js
 | 
			
		||||
    const url_re = /\b(https?:\/\/[^\s<]+[^\s"'),.:;<\]])/g; // Slightly modified from third/marked.js
 | 
			
		||||
    const match = topic.match(url_re);
 | 
			
		||||
    if (match) {
 | 
			
		||||
        links = links.concat(match);
 | 
			
		||||
@@ -432,7 +432,7 @@ function python_to_js_filter(pattern, url) {
 | 
			
		||||
    }
 | 
			
		||||
    // Convert any python in-regex flags to RegExp flags
 | 
			
		||||
    let js_flags = "g";
 | 
			
		||||
    const inline_flag_re = /\(\?([iLmsux]+)\)/;
 | 
			
		||||
    const inline_flag_re = /\(\?([Limsux]+)\)/;
 | 
			
		||||
    match = inline_flag_re.exec(pattern);
 | 
			
		||||
 | 
			
		||||
    // JS regexes only support i (case insensitivity) and m (multiline)
 | 
			
		||||
@@ -456,7 +456,7 @@ function python_to_js_filter(pattern, url) {
 | 
			
		||||
    // is rendered locally, otherwise, we return false there and
 | 
			
		||||
    // message is rendered on the backend which has proper support
 | 
			
		||||
    // for negative lookbehind.
 | 
			
		||||
    pattern = pattern + /(?![\w])/.source;
 | 
			
		||||
    pattern = pattern + /(?!\w)/.source;
 | 
			
		||||
    let final_regex = null;
 | 
			
		||||
    try {
 | 
			
		||||
        final_regex = new RegExp(pattern, js_flags);
 | 
			
		||||
@@ -537,7 +537,7 @@ exports.initialize = function (realm_filters, helper_config) {
 | 
			
		||||
    disable_markdown_regex(marked.Lexer.rules.tables, "lheading");
 | 
			
		||||
 | 
			
		||||
    // Disable __strong__ (keeping **strong**)
 | 
			
		||||
    marked.InlineLexer.rules.zulip.strong = /^\*\*([\s\S]+?)\*\*(?!\*)/;
 | 
			
		||||
    marked.InlineLexer.rules.zulip.strong = /^\*\*([\S\s]+?)\*\*(?!\*)/;
 | 
			
		||||
 | 
			
		||||
    // Make sure <del> syntax matches the backend processor
 | 
			
		||||
    marked.InlineLexer.rules.zulip.del = /^(?!<~)~~([^~]+)~~(?!~)/;
 | 
			
		||||
@@ -545,7 +545,7 @@ exports.initialize = function (realm_filters, helper_config) {
 | 
			
		||||
    // Disable _emphasis_ (keeping *emphasis*)
 | 
			
		||||
    // Text inside ** must start and end with a word character
 | 
			
		||||
    // to prevent mis-parsing things like "char **x = (char **)y"
 | 
			
		||||
    marked.InlineLexer.rules.zulip.em = /^\*(?!\s+)((?:\*\*|[\s\S])+?)((?:[\S]))\*(?!\*)/;
 | 
			
		||||
    marked.InlineLexer.rules.zulip.em = /^\*(?!\s+)((?:\*\*|[\S\s])+?)(\S)\*(?!\*)/;
 | 
			
		||||
 | 
			
		||||
    // Disable autolink as (a) it is not used in our backend and (b) it interferes with @mentions
 | 
			
		||||
    disable_markdown_regex(marked.InlineLexer.rules.zulip, "autolink");
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,17 @@
 | 
			
		||||
export function detect_user_os() {
 | 
			
		||||
    if (/Android/i.test(navigator.userAgent)) {
 | 
			
		||||
    if (/android/i.test(navigator.userAgent)) {
 | 
			
		||||
        return "android";
 | 
			
		||||
    }
 | 
			
		||||
    if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
 | 
			
		||||
    if (/iphone|ipad|ipod/i.test(navigator.userAgent)) {
 | 
			
		||||
        return "ios";
 | 
			
		||||
    }
 | 
			
		||||
    if (common.has_mac_keyboard()) {
 | 
			
		||||
        return "mac";
 | 
			
		||||
    }
 | 
			
		||||
    if (/Win/i.test(navigator.userAgent)) {
 | 
			
		||||
    if (/win/i.test(navigator.userAgent)) {
 | 
			
		||||
        return "windows";
 | 
			
		||||
    }
 | 
			
		||||
    if (/Linux/i.test(navigator.userAgent)) {
 | 
			
		||||
    if (/linux/i.test(navigator.userAgent)) {
 | 
			
		||||
        return "linux";
 | 
			
		||||
    }
 | 
			
		||||
    return "mac"; // if unable to determine OS return Mac by default
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@ function is_local_part(value, element) {
 | 
			
		||||
    // Adapted from Django's EmailValidator
 | 
			
		||||
    return (
 | 
			
		||||
        this.optional(element) ||
 | 
			
		||||
        /^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$/i.test(value)
 | 
			
		||||
        /^[\w!#$%&'*+/=?^`{|}~-]+(\.[\w!#$%&'*+/=?^`{|}~-]+)*$/i.test(value)
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -154,13 +154,13 @@ exports.get_color_class = _.memoize((color) => {
 | 
			
		||||
    const channel = [0, 0, 0];
 | 
			
		||||
    let mult = 1;
 | 
			
		||||
 | 
			
		||||
    match = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/.exec(color);
 | 
			
		||||
    match = /^#([\dA-Fa-f]{2})([\dA-Fa-f]{2})([\dA-Fa-f]{2})$/.exec(color);
 | 
			
		||||
    if (!match) {
 | 
			
		||||
        // 3-digit shorthand; Spectrum gives this e.g. for pure black.
 | 
			
		||||
        // Multiply each digit by 16+1.
 | 
			
		||||
        mult = 17;
 | 
			
		||||
 | 
			
		||||
        match = /^#([\da-fA-F])([\da-fA-F])([\da-fA-F])$/.exec(color);
 | 
			
		||||
        match = /^#([\dA-Fa-f])([\dA-Fa-f])([\dA-Fa-f])$/.exec(color);
 | 
			
		||||
        if (!match) {
 | 
			
		||||
            // Can't understand color.
 | 
			
		||||
            return "";
 | 
			
		||||
 
 | 
			
		||||
@@ -315,7 +315,7 @@ exports.slug_to_name = function (slug) {
 | 
			
		||||
    GitHub conversations.  We migrated to modern slugs in
 | 
			
		||||
    early 2018.
 | 
			
		||||
    */
 | 
			
		||||
    const m = /^([\d]+)(-.*)?/.exec(slug);
 | 
			
		||||
    const m = /^(\d+)(-.*)?/.exec(slug);
 | 
			
		||||
    if (m) {
 | 
			
		||||
        const stream_id = Number.parseInt(m[1], 10);
 | 
			
		||||
        const sub = subs_by_stream_id.get(stream_id);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user