Replace ^ and $ with \A and \z in Ruby regexps (#4072)

This commit is contained in:
rhymes 2019-09-20 17:28:34 +03:00 committed by Mac Siri
parent c5cb61f932
commit de6129b29c
12 changed files with 56 additions and 18 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)