Replace ^ and $ with \A and \z in Ruby regexps (#4072)
This commit is contained in:
parent
c5cb61f932
commit
de6129b29c
12 changed files with 56 additions and 18 deletions
|
|
@ -121,7 +121,7 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
def beautified_url(url)
|
||||
url.sub(/^((http[s]?|ftp):\/)?\//, "").sub(/\?.*/, "").chomp("/")
|
||||
url.sub(/\A((http[s]?|ftp):\/)?\//, "").sub(/\?.*/, "").chomp("/")
|
||||
rescue StandardError
|
||||
url
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class CodepenTag < LiquidTagBase
|
||||
PARTIAL = "liquids/codepen".freeze
|
||||
URL_REGEXP = /\A(http|https):\/\/(codepen\.io|codepen\.io\/team)\/[a-zA-Z0-9_\-]{1,30}\/pen\/([a-zA-Z]{5,7})\/{0,1}\z/.freeze
|
||||
|
||||
def initialize(tag_name, link, tokens)
|
||||
super
|
||||
|
|
@ -46,8 +47,7 @@ class CodepenTag < LiquidTagBase
|
|||
|
||||
def valid_link?(link)
|
||||
link_no_space = link.delete(" ")
|
||||
(link_no_space =~
|
||||
/^(http|https):\/\/(codepen\.io|codepen\.io\/team)\/[a-zA-Z0-9_\-]{1,30}\/pen\/([a-zA-Z]{5,7})\/{0,1}\z/)&.zero?
|
||||
(link_no_space =~ URL_REGEXP)&.zero?
|
||||
end
|
||||
|
||||
def raise_error
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ require "uri"
|
|||
class GlitchTag < LiquidTagBase
|
||||
attr_accessor :uri
|
||||
PARTIAL = "liquids/glitch".freeze
|
||||
ID_REGEXP = /\A[a-zA-Z0-9\-]{1,110}\z/.freeze
|
||||
OPTION_REGEXP = /(app|code|no-files|preview-first|no-attribution|file\=\w(\.\w)?)/.freeze
|
||||
|
||||
def initialize(tag_name, id, tokens)
|
||||
super
|
||||
|
|
@ -23,7 +25,7 @@ class GlitchTag < LiquidTagBase
|
|||
private
|
||||
|
||||
def valid_id?(input)
|
||||
(input =~ /^[a-zA-Z0-9\-]{1,110}$/)&.zero?
|
||||
(input =~ ID_REGEXP)&.zero?
|
||||
end
|
||||
|
||||
def parse_id(input)
|
||||
|
|
@ -34,7 +36,7 @@ class GlitchTag < LiquidTagBase
|
|||
end
|
||||
|
||||
def valid_option(option)
|
||||
option.match(/(app|code|no-files|preview-first|no-attribution|file\=\w(\.\w)?)/)
|
||||
option.match(OPTION_REGEXP)
|
||||
end
|
||||
|
||||
def option_to_query_pair(option)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
class JSFiddleTag < LiquidTagBase
|
||||
PARTIAL = "liquids/jsfiddle".freeze
|
||||
OPTION_REGEXP = /\A(js|html|css|result|,)*\z/.freeze
|
||||
LINK_REGEXP = /\A(http|https):\/\/(jsfiddle\.net)\/[a-zA-Z0-9\-\/]*\z/.freeze
|
||||
|
||||
def initialize(tag_name, link, tokens)
|
||||
super
|
||||
|
|
@ -21,7 +23,7 @@ class JSFiddleTag < LiquidTagBase
|
|||
private
|
||||
|
||||
def valid_option(option)
|
||||
option.match(/^(js|html|css|result|,)*\z/)
|
||||
option.match(OPTION_REGEXP)
|
||||
end
|
||||
|
||||
def parse_options(input)
|
||||
|
|
@ -45,7 +47,7 @@ class JSFiddleTag < LiquidTagBase
|
|||
|
||||
def valid_link?(link)
|
||||
link_no_space = link.delete(" ")
|
||||
(link_no_space =~ /^(http|https):\/\/(jsfiddle\.net)\/[a-zA-Z0-9\-\/]*\z/).zero?
|
||||
(link_no_space =~ LINK_REGEXP).zero?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class KotlinTag < LiquidTagBase
|
||||
PARTIAL = "liquids/kotlin".freeze
|
||||
PARAM_REGEXP = /\A[a-zA-Z0-9]+\z/.freeze
|
||||
|
||||
def initialize(tag_name, link, tokens)
|
||||
super
|
||||
|
|
@ -44,7 +45,7 @@ class KotlinTag < LiquidTagBase
|
|||
end
|
||||
|
||||
def self.valid_param?(value)
|
||||
!value&.match(/^[a-zA-Z0-9]+$/)&.nil?
|
||||
!value&.match(PARAM_REGEXP)&.nil?
|
||||
end
|
||||
|
||||
def raise_error
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
class StackblitzTag < LiquidTagBase
|
||||
PARTIAL = "liquids/stackblitz".freeze
|
||||
ID_REGEXP = /\A[a-zA-Z0-9\-]{0,60}\z/.freeze
|
||||
VIEW_OPTION_REGEXP = /\Aview=(preview|editor|both)\z/.freeze
|
||||
FILE_OPTION_REGEXP = /\Afile=(.*)\z/.freeze
|
||||
|
||||
def initialize(tag_name, id, tokens)
|
||||
super
|
||||
|
|
@ -24,7 +27,7 @@ class StackblitzTag < LiquidTagBase
|
|||
private
|
||||
|
||||
def valid_id?(id)
|
||||
id =~ /\A[a-zA-Z0-9\-]{0,60}\Z/
|
||||
id =~ ID_REGEXP
|
||||
end
|
||||
|
||||
def parse_id(input)
|
||||
|
|
@ -45,11 +48,11 @@ class StackblitzTag < LiquidTagBase
|
|||
end
|
||||
|
||||
def valid_view?(option)
|
||||
option.match(/^view=(preview|editor|both)\z/)
|
||||
option.match(VIEW_OPTION_REGEXP)
|
||||
end
|
||||
|
||||
def valid_file?(option)
|
||||
option.match(/^file=(.*)\z/)
|
||||
option.match(FILE_OPTION_REGEXP)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class StackexchangeTag < LiquidTagBase
|
|||
"question" => "!*1SgQGDOL9bPBHULz9sKS.y6qv7V9fYNszvdhDuv5",
|
||||
"site" => "!mWxO_PNa4i"
|
||||
}.freeze
|
||||
ID_REGEXP = /\A\d{1,20}\z/.freeze
|
||||
|
||||
attr_reader :site, :post_type
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ class StackexchangeTag < LiquidTagBase
|
|||
def valid_input?(input)
|
||||
return false if input.nil?
|
||||
|
||||
/^\d{1,20}$/.match?(input.split(" ")[0])
|
||||
ID_REGEXP.match?(input.split(" ")[0])
|
||||
end
|
||||
|
||||
def handle_response_error(response)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
class TweetTag < LiquidTagBase
|
||||
include ActionView::Helpers::AssetTagHelper
|
||||
PARTIAL = "liquids/tweet".freeze
|
||||
ID_REGEXP = /\A\d{10,20}\z/.freeze # id must be all numbers between 10 and 20 chars
|
||||
|
||||
def initialize(tag_name, id, tokens)
|
||||
super
|
||||
|
|
@ -53,8 +54,7 @@ class TweetTag < LiquidTagBase
|
|||
end
|
||||
|
||||
def valid_id?(id)
|
||||
# id must be all numbers under 20 characters
|
||||
/^\d{10,20}$/.match?(id)
|
||||
ID_REGEXP.match?(id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -7,4 +7,22 @@ RSpec.describe ApplicationHelper, type: :helper do
|
|||
expect(helper.community_qualified_name).to eq(expected_name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#beautified_url" do
|
||||
it "strips the protocol" do
|
||||
expect(helper.beautified_url("https://github.com")).to eq("github.com")
|
||||
end
|
||||
|
||||
it "strips params" do
|
||||
expect(helper.beautified_url("https://github.com?a=3")).to eq("github.com")
|
||||
end
|
||||
|
||||
it "strips the last forward slash" do
|
||||
expect(helper.beautified_url("https://github.com/")).to eq("github.com")
|
||||
end
|
||||
|
||||
it "does not strip the path" do
|
||||
expect(helper.beautified_url("https://github.com/rails")).to eq("github.com/rails")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -68,5 +68,14 @@ RSpec.describe CodepenTag, type: :liquid_template do
|
|||
expect { generate_new_liquid(link) }.to raise_error(StandardError)
|
||||
end
|
||||
end
|
||||
|
||||
it "rejects multiline XSS attempt" do
|
||||
xss_multiline_link = <<~XSS
|
||||
javascript:exploit_code();/*
|
||||
#{codepen_link}
|
||||
*/
|
||||
XSS
|
||||
expect { generate_new_liquid(xss_multiline_link) }.to raise_error(StandardError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ require "rails_helper"
|
|||
|
||||
RSpec.describe KotlinTag, type: :liquid_template do
|
||||
describe "#link" do
|
||||
input = "https://pl.kotl.in/owreUFFUG?theme=darcula&from=3&to=6&readOnly=true"
|
||||
expected = "https://play.kotlinlang.org/embed?short=owreUFFUG&from=3&to=6&theme=darcula&readOnly=true"
|
||||
let(:valid_link) { "https://pl.kotl.in/owreUFFUG?theme=darcula&from=3&to=6&readOnly=true" }
|
||||
|
||||
def generate_new_liquid(link)
|
||||
Liquid::Template.register_tag("kotlin", KotlinTag)
|
||||
|
|
@ -34,11 +33,12 @@ RSpec.describe KotlinTag, type: :liquid_template do
|
|||
end
|
||||
|
||||
it "produces a correct final URL" do
|
||||
expect(described_class.embedded_url(input)).to eq(expected)
|
||||
expected = "https://play.kotlinlang.org/embed?short=owreUFFUG&from=3&to=6&theme=darcula&readOnly=true"
|
||||
expect(described_class.embedded_url(valid_link)).to eq(expected)
|
||||
end
|
||||
|
||||
it "renders correctly a Kotlin Playground link" do
|
||||
liquid = generate_new_liquid(input)
|
||||
liquid = generate_new_liquid(valid_link)
|
||||
rendered_kotlin_iframe = liquid.render
|
||||
Approvals.verify(rendered_kotlin_iframe, name: "kotlin_liquid_tag", format: :html)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,10 +25,12 @@ RSpec.describe StackexchangeTag, type: :liquid_template, vcr: vcr_option do
|
|||
liquid = generate_new_liquid(valid_id)
|
||||
expect(liquid.render).to include("ltag__stackexchange")
|
||||
end
|
||||
|
||||
it "renders basic exchange html" do
|
||||
liquid = generate_exchange_liquid(exchange_id)
|
||||
expect(liquid.render).to include("stackexchange-logo")
|
||||
end
|
||||
|
||||
it "rejects invalid id" do
|
||||
expect do
|
||||
liquid = generate_exchange_liquid(invalid_id)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue