From e16136f70950c60a879fbd965c871946fedb51bf Mon Sep 17 00:00:00 2001 From: Sergey Suprunenko Date: Tue, 10 Nov 2020 21:24:50 +0100 Subject: [PATCH 1/3] Do not parse mention if there is something before it --- lib/linkify/parser.ex | 2 +- test/linkify_test.exs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/linkify/parser.ex b/lib/linkify/parser.ex index 1e5c3db..eab5891 100644 --- a/lib/linkify/parser.ex +++ b/lib/linkify/parser.ex @@ -15,7 +15,7 @@ defmodule Linkify.Parser do # @user # @user@example.com - @match_mention ~r"^@[a-zA-Z\d_-]+@[a-zA-Z0-9_-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*|@[a-zA-Z\d_-]+"u + @match_mention ~r"^@[a-zA-Z\d_-]+@[a-zA-Z0-9_-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*|^@[a-zA-Z\d_-]+"u # https://www.w3.org/TR/html5/forms.html#valid-e-mail-address @match_email ~r"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"u diff --git a/test/linkify_test.exs b/test/linkify_test.exs index b5059f6..a18dc3c 100644 --- a/test/linkify_test.exs +++ b/test/linkify_test.exs @@ -385,6 +385,12 @@ defmodule LinkifyTest do mention_prefix: "https://example.com/user/" ) == expected end + + test "invalid mentions" do + text = "hey user@example" + + assert Linkify.link(text, mention: true, mention_prefix: "/users/") == text + end end describe "hashtag links" do From 2a050e1cbe3005bec25cb321f4c60cd656ac7ed9 Mon Sep 17 00:00:00 2001 From: Sergey Suprunenko Date: Mon, 16 Nov 2020 18:57:01 +0100 Subject: [PATCH 2/3] Ignore non-word chars in the beginning of mentions --- CHANGELOG.md | 1 + lib/linkify/parser.ex | 7 ++++--- test/linkify_test.exs | 9 +++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adfc4a7..9cb2132 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Hashtags followed by HTML tags "a", "code" and "pre" were not detected - Incorrect parsing of HTML links inside HTML tags - Punctuation marks in the end of urls were included in the html links +- Incorrect parsing of mentions with symbols before them ## 0.2.0 - 2020-07-21 diff --git a/lib/linkify/parser.ex b/lib/linkify/parser.ex index eab5891..af826c3 100644 --- a/lib/linkify/parser.ex +++ b/lib/linkify/parser.ex @@ -15,7 +15,7 @@ defmodule Linkify.Parser do # @user # @user@example.com - @match_mention ~r"^@[a-zA-Z\d_-]+@[a-zA-Z0-9_-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*|^@[a-zA-Z\d_-]+"u + @match_mention ~r/^(?:\W*)?(?@[a-zA-Z\d_-]+@[a-zA-Z0-9_-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)|^(?:\W*)?(?@[a-zA-Z\d_-]+)/u # https://www.w3.org/TR/html5/forms.html#valid-e-mail-address @match_email ~r"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"u @@ -254,8 +254,9 @@ defmodule Linkify.Parser do def ip?(buffer), do: Regex.match?(@match_ip, buffer) def match_mention(buffer) do - case Regex.run(@match_mention, buffer) do - [mention] -> mention + case Regex.run(@match_mention, buffer, capture: [:long, :short]) do + [mention, ""] -> mention + ["", mention] -> mention _ -> nil end end diff --git a/test/linkify_test.exs b/test/linkify_test.exs index a18dc3c..73ff6d0 100644 --- a/test/linkify_test.exs +++ b/test/linkify_test.exs @@ -386,6 +386,15 @@ defmodule LinkifyTest do ) == expected end + test "mentions with symbols before them" do + text = "@@example hey! >@@test@example.com" + + expected = + "@@example hey! >@@test@example.com" + + assert Linkify.link(text, mention: true, mention_prefix: "/users/") == expected + end + test "invalid mentions" do text = "hey user@example" From 45e970d60465d4d727cd1dec6213a12ada004219 Mon Sep 17 00:00:00 2001 From: Sergey Suprunenko Date: Mon, 16 Nov 2020 23:18:32 +0100 Subject: [PATCH 3/3] Upgrade credo --- lib/linkify/parser.ex | 1 + mix.exs | 2 +- mix.lock | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/linkify/parser.ex b/lib/linkify/parser.ex index af826c3..64d08db 100644 --- a/lib/linkify/parser.ex +++ b/lib/linkify/parser.ex @@ -15,6 +15,7 @@ defmodule Linkify.Parser do # @user # @user@example.com + # credo:disable-for-next-line @match_mention ~r/^(?:\W*)?(?@[a-zA-Z\d_-]+@[a-zA-Z0-9_-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)|^(?:\W*)?(?@[a-zA-Z\d_-]+)/u # https://www.w3.org/TR/html5/forms.html#valid-e-mail-address diff --git a/mix.exs b/mix.exs index 93b7934..f78671d 100644 --- a/mix.exs +++ b/mix.exs @@ -30,7 +30,7 @@ defmodule Linkify.Mixfile do defp deps do [ {:ex_doc, "~> 0.20", only: :dev, runtime: false}, - {:credo, "~> 1.4.0", only: [:dev, :test], runtime: false} + {:credo, "~> 1.5", only: [:dev, :test], runtime: false} ] end diff --git a/mix.lock b/mix.lock index be2b77f..a658f27 100644 --- a/mix.lock +++ b/mix.lock @@ -1,10 +1,11 @@ %{ "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, - "credo": {:hex, :credo, "1.4.0", "92339d4cbadd1e88b5ee43d427b639b68a11071b6f73854e33638e30a0ea11f5", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1fd3b70dce216574ce3c18bdf510b57e7c4c85c2ec9cad4bff854abaf7e58658"}, + "credo": {:hex, :credo, "1.5.1", "4fe303cc828412b9d21eed4eab60914c401e71f117f40243266aafb66f30d036", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "0b219ca4dcc89e4e7bc6ae7e6539c313e738e192e10b85275fa1e82b5203ecd7"}, "earmark": {:hex, :earmark, "1.4.10", "bddce5e8ea37712a5bfb01541be8ba57d3b171d3fa4f80a0be9bcf1db417bcaf", [:mix], [{:earmark_parser, ">= 1.4.10", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "12dbfa80810478e521d3ffb941ad9fbfcbbd7debe94e1341b4c4a1b2411c1c27"}, "earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"}, "ex_doc": {:hex, :ex_doc, "0.22.1", "9bb6d51508778193a4ea90fa16eac47f8b67934f33f8271d5e1edec2dc0eee4c", [:mix], [{:earmark, "~> 1.4.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "d957de1b75cb9f78d3ee17820733dc4460114d8b1e11f7ee4fd6546e69b1db60"}, - "jason": {:hex, :jason, "1.2.1", "12b22825e22f468c02eb3e4b9985f3d0cb8dc40b9bd704730efa11abd2708c44", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b659b8571deedf60f79c5a608e15414085fa141344e2716fbd6988a084b5f993"}, + "file_system": {:hex, :file_system, "0.2.9", "545b9c9d502e8bfa71a5315fac2a923bd060fd9acb797fe6595f54b0f975fd32", [:mix], [], "hexpm", "3cf87a377fe1d93043adeec4889feacf594957226b4f19d5897096d6f61345d8"}, + "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, "makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"}, "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, "nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"},