From c8026cd16c37079e3b2468f06f37f7dcd6aa3f95 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Mon, 17 Jun 2019 23:06:31 +0300 Subject: [PATCH] Add an option to disable TLD validation Added `validate_tld` option, which can be set to false to disable tld validation and to :no_scheme to disable tld validation when a scheme is present Closes #8 --- lib/auto_linker.ex | 1 + lib/auto_linker/parser.ex | 16 +++++++---- test/parser_test.exs | 60 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/lib/auto_linker.ex b/lib/auto_linker.ex index 222cd79..d07e6df 100644 --- a/lib/auto_linker.ex +++ b/lib/auto_linker.ex @@ -48,6 +48,7 @@ defmodule AutoLinker do * `hashtag_prefix: nil` - a prefix to build a link for a hashtag (example: `https://example.com/tag/`) * `hashtag_handler: nil` - a custom handler to validate and formart a hashtag * `extra: false` - link urls with rarely used schemes (magnet, ipfs, irc, etc.) + * `validate_tld: true` - Set to false to disable TLD validation for urls, also can be set to :no_scheme to validate TLDs only for urls without a scheme (e.g `example.com` will be validated, but `http://example.loki` won't) Each of the above options can be specified when calling `link(text, opts)` or can be set in the `:auto_linker`'s configuration. For example: diff --git a/lib/auto_linker/parser.ex b/lib/auto_linker/parser.ex index 739173f..0ca906d 100644 --- a/lib/auto_linker/parser.ex +++ b/lib/auto_linker/parser.ex @@ -42,7 +42,7 @@ defmodule AutoLinker.Parser do @tlds "./priv/tlds.txt" |> File.read!() |> String.split("\n", trim: true) |> MapSet.new() - @default_opts ~w(url)a + @default_opts ~w(url validate_tld)a @doc """ Parse the given string, identifying items to link. @@ -262,7 +262,7 @@ defmodule AutoLinker.Parser do def check_and_link(buffer, opts, _user_acc) do str = strip_parens(buffer) - if url?(str, opts[:scheme]) do + if url?(str, opts[:scheme], opts[:validate_tld]) do case parse_link(str, opts) do ^buffer -> link_url(buffer, opts) url -> String.replace(buffer, url, link_url(url, opts)) @@ -315,12 +315,16 @@ defmodule AutoLinker.Parser do end # @doc false - def url?(buffer, true) do - valid_url?(buffer) && Regex.match?(@match_scheme, buffer) && valid_tld?(buffer) + def url?(buffer, scheme, validate_tld \\ true) + + def url?(buffer, true, validate_tld) do + valid_url?(buffer) && Regex.match?(@match_scheme, buffer) && + (!validate_tld or validate_tld == :no_scheme || valid_tld?(buffer)) end - def url?(buffer, _) do - valid_url?(buffer) && Regex.match?(@match_url, buffer) && valid_tld?(buffer) + def url?(buffer, _, validate_tld) do + valid_url?(buffer) && Regex.match?(@match_url, buffer) && + (validate_tld == false || valid_tld?(buffer)) end def email?(buffer) do diff --git a/test/parser_test.exs b/test/parser_test.exs index 851fe3e..2b49a7c 100644 --- a/test/parser_test.exs +++ b/test/parser_test.exs @@ -4,7 +4,7 @@ defmodule AutoLinker.ParserTest do import AutoLinker.Parser - describe "url?/2" do + describe "url?/3" do test "valid scheme true" do valid_scheme_urls() |> Enum.each(fn url -> @@ -32,6 +32,48 @@ defmodule AutoLinker.ParserTest do refute url?(url, false) end) end + + test "checks the tld for url with a scheme when validate_tld: true" do + custom_tld_scheme_urls() + |> Enum.each(fn url -> + refute url?(url, true, true) + end) + end + + test "does not check the tld for url with a scheme when validate_tld: false" do + custom_tld_scheme_urls() + |> Enum.each(fn url -> + assert url?(url, true, false) + end) + end + + test "does not check the tld for url with a scheme when validate_tld: :no_scheme" do + custom_tld_scheme_urls() + |> Enum.each(fn url -> + assert url?(url, true, :no_scheme) + end) + end + + test "checks the tld for url without a scheme when validate_tld: true" do + custom_tld_non_scheme_urls() + |> Enum.each(fn url -> + refute url?(url, false, true) + end) + end + + test "checks the tld for url without a scheme when validate_tld: :no_scheme" do + custom_tld_non_scheme_urls() + |> Enum.each(fn url -> + refute url?(url, false, :no_scheme) + end) + end + + test "does not check the tld for url without a scheme when validate_tld: false" do + custom_tld_non_scheme_urls() + |> Enum.each(fn url -> + assert url?(url, false, false) + end) + end end describe "match_phone" do @@ -216,4 +258,20 @@ defmodule AutoLinker.ParserTest do "x5", "(555) 555-55" ] + + def custom_tld_scheme_urls, + do: [ + "http://whatever.null/", + "https://example.o/index.html", + "http://pleroma.i2p/test", + "http://misskey.loki" + ] + + def custom_tld_non_scheme_urls, + do: [ + "whatever.null/", + "example.o/index.html", + "pleroma.i2p/test", + "misskey.loki" + ] end