Maintenance: Rubocop enforces %r{} regular expression style

This commit is contained in:
Mantas Masalskis 2021-05-12 14:37:44 +03:00
parent be115dbb5c
commit 041bf51b52
173 changed files with 644 additions and 641 deletions

View file

@ -273,6 +273,9 @@ Style/StringConcatenation:
Exclude: Exclude:
- "config/routes/**/*" - "config/routes/**/*"
Style/RegexpLiteral:
EnforcedStyle: percent_r
# RSpec tests # RSpec tests
Style/NumericPredicate: Style/NumericPredicate:
Description: >- Description: >-

View file

@ -82,11 +82,11 @@ module ApplicationController::HandlesErrors
error: e.message error: e.message
} }
if e.message =~ /Validation failed: (.+?)(,|$)/i if e.message =~ %r{Validation failed: (.+?)(,|$)}i
data[:error_human] = $1 data[:error_human] = $1
elsif e.message.match?(/(already exists|duplicate key|duplicate entry)/i) elsif e.message.match?(%r{(already exists|duplicate key|duplicate entry)}i)
data[:error_human] = 'Object already exists!' data[:error_human] = 'Object already exists!'
elsif e.message =~ /null value in column "(.+?)" violates not-null constraint/i || e.message =~ /Field '(.+?)' doesn't have a default value/i elsif e.message =~ %r{null value in column "(.+?)" violates not-null constraint}i || e.message =~ %r{Field '(.+?)' doesn't have a default value}i
data[:error_human] = "Attribute '#{$1}' required!" data[:error_human] = "Attribute '#{$1}' required!"
elsif e.message == 'Exceptions::Forbidden' elsif e.message == 'Exceptions::Forbidden'
data[:error] = 'Not authorized' data[:error] = 'Not authorized'

View file

@ -224,7 +224,7 @@ class ChannelsEmailController < ApplicationController
Channel.where(area: 'Email::Notification').each do |channel| Channel.where(area: 'Email::Notification').each do |channel|
active = false active = false
if adapter.match?(/^#{channel.options[:outbound][:adapter]}$/i) if adapter.match?(%r{^#{channel.options[:outbound][:adapter]}$}i)
active = true active = true
channel.options = { channel.options = {
outbound: { outbound: {

View file

@ -37,7 +37,7 @@ module CreatesTicketArticles
clean_params.delete(:sender) clean_params.delete(:sender)
clean_params.delete(:origin_by_id) clean_params.delete(:origin_by_id)
type = Ticket::Article::Type.lookup(id: clean_params[:type_id]) type = Ticket::Article::Type.lookup(id: clean_params[:type_id])
if !type.name.match?(/^(note|web)$/) if !type.name.match?(%r{^(note|web)$})
clean_params[:type_id] = Ticket::Article::Type.lookup(name: 'note').id clean_params[:type_id] = Ticket::Article::Type.lookup(name: 'note').id
end end
clean_params.delete(:type) clean_params.delete(:type)
@ -91,12 +91,12 @@ module CreatesTicketArticles
preferences_keys.each do |key| preferences_keys.each do |key|
next if !attachment[key] next if !attachment[key]
store_key = key.tr('-', '_').camelize.gsub(/(.+)([A-Z])/, '\1_\2').tr('_', '-') store_key = key.tr('-', '_').camelize.gsub(%r{(.+)([A-Z])}, '\1_\2').tr('_', '-')
preferences[store_key] = attachment[key] preferences[store_key] = attachment[key]
end end
begin begin
base64_data = attachment[:data].gsub(/[\r\n]/, '') base64_data = attachment[:data].gsub(%r{[\r\n]}, '')
attachment_data = Base64.strict_decode64(base64_data) attachment_data = Base64.strict_decode64(base64_data)
rescue ArgumentError rescue ArgumentError
raise Exceptions::UnprocessableEntity, "Invalid base64 for attachment with index '#{index}'" raise Exceptions::UnprocessableEntity, "Invalid base64 for attachment with index '#{index}'"

View file

@ -124,7 +124,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
end end
# validate image # validate image
if params[:logo] && params[:logo] =~ /^data:image/i if params[:logo] && params[:logo] =~ %r{^data:image}i
file = StaticAssets.data_url_attributes(params[:logo]) file = StaticAssets.data_url_attributes(params[:logo])
if !file[:content] || !file[:mime_type] if !file[:content] || !file[:mime_type]
messages[:logo] = 'Unable to process image upload.' messages[:logo] = 'Unable to process image upload.'
@ -150,7 +150,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
end end
# save image # save image
if params[:logo] && params[:logo] =~ /^data:image/i if params[:logo] && params[:logo] =~ %r{^data:image}i
# data:image/png;base64 # data:image/png;base64
file = StaticAssets.data_url_attributes(params[:logo]) file = StaticAssets.data_url_attributes(params[:logo])
@ -159,7 +159,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
StaticAssets.store_raw(file[:content], file[:mime_type]) StaticAssets.store_raw(file[:content], file[:mime_type])
end end
if params[:logo_resize] && params[:logo_resize] =~ /^data:image/i if params[:logo_resize] && params[:logo_resize] =~ %r{^data:image}i
# data:image/png;base64 # data:image/png;base64
file = StaticAssets.data_url_attributes(params[:logo_resize]) file = StaticAssets.data_url_attributes(params[:logo_resize])

View file

@ -23,10 +23,10 @@ class ImportOtrsController < ApplicationController
} }
response = UserAgent.request(params[:url]) response = UserAgent.request(params[:url])
if !response.success? && response.code.to_s !~ /^40.$/ if !response.success? && response.code.to_s !~ %r{^40.$}
message_human = '' message_human = ''
translation_map.each do |key, message| translation_map.each do |key, message|
if response.error.to_s.match?(/#{Regexp.escape(key)}/i) if response.error.to_s.match?(%r{#{Regexp.escape(key)}}i)
message_human = message message_human = message
end end
end end
@ -86,7 +86,7 @@ class ImportOtrsController < ApplicationController
message_human: migrator_response['Error'] message_human: migrator_response['Error']
} }
end end
elsif response.body.match?(/(otrs\sag|otrs\.com|otrs\.org)/i) elsif response.body.match?(%r{(otrs\sag|otrs\.com|otrs\.org)}i)
result = { result = {
result: 'invalid', result: 'invalid',
message_human: 'Host found, but no OTRS migrator is installed!' message_human: 'Host found, but no OTRS migrator is installed!'

View file

@ -27,7 +27,7 @@ class ImportZendeskController < ApplicationController
if !response.success? if !response.success?
message_human = '' message_human = ''
translation_map.each do |key, message| translation_map.each do |key, message|
if response.error.to_s.match?(/#{Regexp.escape(key)}/i) if response.error.to_s.match?(%r{#{Regexp.escape(key)}}i)
message_human = message message_human = message
end end
end end
@ -40,7 +40,7 @@ class ImportZendeskController < ApplicationController
end end
# since 2016-10-15 a redirect to a marketing page has been implemented # since 2016-10-15 a redirect to a marketing page has been implemented
if !response.body.match?(/#{params[:url]}/) if !response.body.match?(%r{#{params[:url]}})
render json: { render json: {
result: 'invalid', result: 'invalid',
message_human: 'Hostname not found!', message_human: 'Hostname not found!',

View file

@ -61,7 +61,7 @@ UserAgent: #{request.env['HTTP_USER_AGENT'] || '-'}
internal: false, internal: false,
) )
end end
if (!auto_close && params[:state].match(/#{state_recovery_match}/i)) || !params[:state].match(/#{state_recovery_match}/i) if (!auto_close && params[:state].match(%r{#{state_recovery_match}}i)) || !params[:state].match(%r{#{state_recovery_match}}i)
render json: { render json: {
result: 'ticket already open, added note', result: 'ticket already open, added note',
ticket_ids: ticket_ids_found, ticket_ids: ticket_ids_found,
@ -71,7 +71,7 @@ UserAgent: #{request.env['HTTP_USER_AGENT'] || '-'}
end end
# check if service is recovered # check if service is recovered
if auto_close && params[:state].present? && params[:state].match(/#{state_recovery_match}/i) if auto_close && params[:state].present? && params[:state].match(%r{#{state_recovery_match}}i)
if ticket_ids_found.blank? if ticket_ids_found.blank?
render json: { render json: {
result: 'no open tickets found, ignore action', result: 'no open tickets found, ignore action',

View file

@ -42,7 +42,7 @@ class Integration::SMIMEController < ApplicationController
string = params[:file].read.force_encoding('utf-8') string = params[:file].read.force_encoding('utf-8')
end end
items = string.scan(/.+?-+END(?: TRUSTED)? CERTIFICATE-+/mi).each_with_object([]) do |cert, result| items = string.scan(%r{.+?-+END(?: TRUSTED)? CERTIFICATE-+}mi).each_with_object([]) do |cert, result|
result << SMIMECertificate.create!(public_key: cert) result << SMIMECertificate.create!(public_key: cert)
end end

View file

@ -308,7 +308,7 @@ curl http://localhost/api/v1/monitoring/amount_check?token=XXX&periode=1h
raise Exceptions::UnprocessableEntity, 'periode is missing!' if params[:periode].blank? raise Exceptions::UnprocessableEntity, 'periode is missing!' if params[:periode].blank?
scale = params[:periode][-1, 1] scale = params[:periode][-1, 1]
raise Exceptions::UnprocessableEntity, 'periode need to have s, m, h or d as last!' if !scale.match?(/^(s|m|h|d)$/) raise Exceptions::UnprocessableEntity, 'periode need to have s, m, h or d as last!' if !scale.match?(%r{^(s|m|h|d)$})
periode = params[:periode][0, params[:periode].length - 1] periode = params[:periode][0, params[:periode].length - 1]
raise Exceptions::UnprocessableEntity, 'periode need to be an integer!' if periode.to_i.zero? raise Exceptions::UnprocessableEntity, 'periode need to be an integer!' if periode.to_i.zero?

View file

@ -76,7 +76,7 @@ class ObjectManagerAttributesController < ApplicationController
@permitted_params ||= begin @permitted_params ||= begin
permitted = params.permit!.to_h permitted = params.permit!.to_h
if permitted[:data_type].match?(/^(boolean)$/) && permitted[:data_option][:options] if permitted[:data_type].match?(%r{^(boolean)$}) && permitted[:data_option][:options]
# rubocop:disable Lint/BooleanSymbol # rubocop:disable Lint/BooleanSymbol
if permitted[:data_option][:options][:false] if permitted[:data_option][:options][:false]
permitted[:data_option][:options][false] = permitted[:data_option][:options].delete(:false) permitted[:data_option][:options][false] = permitted[:data_option][:options].delete(:false)
@ -98,7 +98,7 @@ class ObjectManagerAttributesController < ApplicationController
if permitted[:data_option] if permitted[:data_option]
if !permitted[:data_option].key?(:default) if !permitted[:data_option].key?(:default)
permitted[:data_option][:default] = if permitted[:data_type].match?(/^(input|select|tree_select)$/) permitted[:data_option][:default] = if permitted[:data_type].match?(%r{^(input|select|tree_select)$})
'' ''
end end
end end

View file

@ -43,7 +43,7 @@ class SettingsController < ApplicationController
end end
# validate image # validate image
if !clean_params[:logo].match?(/^data:image/i) if !clean_params[:logo].match?(%r{^data:image}i)
render json: { render json: {
result: 'invalid', result: 'invalid',
message: 'Invalid payload, need data:image in logo param', message: 'Invalid payload, need data:image in logo param',
@ -66,7 +66,7 @@ class SettingsController < ApplicationController
# store resized image 1:1 # store resized image 1:1
setting = Setting.lookup(name: 'product_logo') setting = Setting.lookup(name: 'product_logo')
if params[:logo_resize] && params[:logo_resize] =~ /^data:image/i if params[:logo_resize] && params[:logo_resize] =~ %r{^data:image}i
# data:image/png;base64 # data:image/png;base64
file = StaticAssets.data_url_attributes(params[:logo_resize]) file = StaticAssets.data_url_attributes(params[:logo_resize])

View file

@ -96,7 +96,7 @@ class TicketsController < ApplicationController
end end
# try to create customer if needed # try to create customer if needed
if clean_params[:customer_id].present? && clean_params[:customer_id] =~ /^guess:(.+?)$/ if clean_params[:customer_id].present? && clean_params[:customer_id] =~ %r{^guess:(.+?)$}
email_address = $1 email_address = $1
email_address_validation = EmailAddressValidation.new(email_address) email_address_validation = EmailAddressValidation.new(email_address)
if !email_address_validation.valid_format? if !email_address_validation.valid_format?

View file

@ -27,7 +27,7 @@ module KnowledgeBaseRichTextHelper
end end
def prepare_rich_text_videos(input) def prepare_rich_text_videos(input)
input.gsub(/\((\s*)widget:(\s*)video\W([\s\S])+?\)/) do |match| input.gsub(%r{\((\s*)widget:(\s*)video\W([\s\S])+?\)}) do |match|
settings = match settings = match
.slice(1...-1) .slice(1...-1)
.split(',') .split(',')

View file

@ -15,7 +15,7 @@ class CommunicateFacebookJob < ApplicationJob
log_error(article, "Can't find ticket.preferences for Ticket.find(#{article.ticket_id})") if !ticket.preferences log_error(article, "Can't find ticket.preferences for Ticket.find(#{article.ticket_id})") if !ticket.preferences
log_error(article, "Can't find ticket.preferences['channel_id'] for Ticket.find(#{article.ticket_id})") if !ticket.preferences['channel_id'] log_error(article, "Can't find ticket.preferences['channel_id'] for Ticket.find(#{article.ticket_id})") if !ticket.preferences['channel_id']
channel = Channel.lookup(id: ticket.preferences['channel_id']) channel = Channel.lookup(id: ticket.preferences['channel_id'])
log_error(article, "Channel.find(#{channel.id}) isn't a twitter channel!") if !channel.options[:adapter].match?(/\Afacebook/i) log_error(article, "Channel.find(#{channel.id}) isn't a twitter channel!") if !channel.options[:adapter].match?(%r{\Afacebook}i)
# check source object id # check source object id
if !ticket.preferences['channel_fb_object_id'] if !ticket.preferences['channel_fb_object_id']

View file

@ -31,7 +31,7 @@ class CommunicateTelegramJob < ApplicationJob
result = api.sendMessage(chat_id, article.body) result = api.sendMessage(chat_id, article.body)
me = api.getMe() me = api.getMe()
article.attachments.each do |file| article.attachments.each do |file|
parts = file.filename.split(/^(.*)(\..+?)$/) parts = file.filename.split(%r{^(.*)(\..+?)$})
t = Tempfile.new([parts[1], parts[2]]) t = Tempfile.new([parts[1], parts[2]])
t.binmode t.binmode
t.write(file.content) t.write(file.content)

View file

@ -30,7 +30,7 @@ class CommunicateTwitterJob < ApplicationJob
end end
log_error(article, "No such channel id #{ticket.preferences['channel_id']}") if !channel log_error(article, "No such channel id #{ticket.preferences['channel_id']}") if !channel
log_error(article, "Channel.find(#{channel.id}) isn't a twitter channel!") if !channel.options[:adapter].try(:match?, /\Atwitter/i) log_error(article, "Channel.find(#{channel.id}) isn't a twitter channel!") if !channel.options[:adapter].try(:match?, %r{\Atwitter}i)
begin begin
tweet = channel.deliver( tweet = channel.deliver(

View file

@ -81,12 +81,12 @@ get assets and record_ids of selector
attribute_ref_class = ::User attribute_ref_class = ::User
item_ids = [] item_ids = []
Array(content['recipient']).each do |identifier| Array(content['recipient']).each do |identifier|
next if identifier !~ /\Auserid_(\d+)\z/ next if identifier !~ %r{\Auserid_(\d+)\z}
item_ids.push($1) item_ids.push($1)
end end
else else
reflection = attribute[1].sub(/_id$/, '') reflection = attribute[1].sub(%r{_id$}, '')
next if !models[attribute_class] next if !models[attribute_class]
next if !models[attribute_class][:reflections] next if !models[attribute_class][:reflections]
next if !models[attribute_class][:reflections][reflection] next if !models[attribute_class][:reflections][reflection]

View file

@ -110,10 +110,10 @@ add avatar by url
content = data[:url].read content = data[:url].read
filename = data[:url].path filename = data[:url].path
mime_type = 'image' mime_type = 'image'
if filename.match?(/\.png/i) if filename.match?(%r{\.png}i)
mime_type = 'image/png' mime_type = 'image/png'
end end
if filename.match?(/\.(jpg|jpeg)/i) if filename.match?(%r{\.(jpg|jpeg)}i)
mime_type = 'image/jpeg' mime_type = 'image/jpeg'
end end
data[:resize] ||= {} data[:resize] ||= {}
@ -132,7 +132,7 @@ add avatar by url
# twitter workaround to get bigger avatar images # twitter workaround to get bigger avatar images
# see also https://dev.twitter.com/overview/general/user-profile-images-and-banners # see also https://dev.twitter.com/overview/general/user-profile-images-and-banners
if url.match?(%r{//pbs.twimg.com/}i) if url.match?(%r{//pbs.twimg.com/}i)
url.sub!(/normal\.(png|jpg|gif)$/, 'bigger.\1') url.sub!(%r{normal\.(png|jpg|gif)$}, 'bigger.\1')
end end
# fetch image # fetch image
@ -151,10 +151,10 @@ add avatar by url
end end
logger.info "Fetchd image '#{url}', http code: #{response.code}" logger.info "Fetchd image '#{url}', http code: #{response.code}"
mime_type = 'image' mime_type = 'image'
if url.match?(/\.png/i) if url.match?(%r{\.png}i)
mime_type = 'image/png' mime_type = 'image/png'
end end
if url.match?(/\.(jpg|jpeg)/i) if url.match?(%r{\.(jpg|jpeg)}i)
mime_type = 'image/jpeg' mime_type = 'image/jpeg'
end end

View file

@ -27,7 +27,7 @@ returns calendar object
def self.init_setup(ip = nil) def self.init_setup(ip = nil)
# ignore client ip if not public ip # ignore client ip if not public ip
if ip && ip =~ /^(::1|127\.|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.|192\.168\.)/ if ip && ip =~ %r{^(::1|127\.|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.|192\.168\.)}
ip = nil ip = nil
end end
@ -214,7 +214,7 @@ returns
end end
def self.fetch_parse(location) def self.fetch_parse(location)
if location.match?(/^http/i) if location.match?(%r{^http}i)
result = UserAgent.get(location) result = UserAgent.get(location)
if !result.success? if !result.success?
raise result.error raise result.error
@ -262,7 +262,7 @@ returns
comment = comment.to_utf8(fallback: :read_as_sanitized_binary) comment = comment.to_utf8(fallback: :read_as_sanitized_binary)
# ignore daylight saving time entries # ignore daylight saving time entries
return if comment.match?(/(daylight saving|sommerzeit|summertime)/i) return if comment.match?(%r{(daylight saving|sommerzeit|summertime)}i)
[day, comment] [day, comment]
end end

View file

@ -226,7 +226,7 @@ example
headers = self.class.extract_rfc822_headers(message_meta) headers = self.class.extract_rfc822_headers(message_meta)
subject = headers['Subject'] subject = headers['Subject']
next if !subject next if !subject
next if !subject.match?(/#{verify_string}/) next if !subject.match?(%r{#{verify_string}})
Rails.logger.info " - verify email #{verify_string} found" Rails.logger.info " - verify email #{verify_string} found"
timeout(600) do timeout(600) do
@ -406,7 +406,7 @@ returns
array = string array = string
.gsub("\r\n\t", ' ') # Some servers (e.g. microsoft365) may put attribute value on a separate line and tab it .gsub("\r\n\t", ' ') # Some servers (e.g. microsoft365) may put attribute value on a separate line and tab it
.lines(chomp: true) .lines(chomp: true)
.map { |line| line.split(/:\s*/, 2).map(&:strip) } .map { |line| line.split(%r{:\s*}, 2).map(&:strip) }
array.each { |elem| elem.append(nil) if elem.one? } array.each { |elem| elem.append(nil) if elem.one? }

View file

@ -91,7 +91,7 @@ returns
next if !mail next if !mail
# check how many content messages we have, for notice used # check how many content messages we have, for notice used
if !mail.match?(/(X-Zammad-Ignore: true|X-Zammad-Verify: true)/) if !mail.match?(%r{(X-Zammad-Ignore: true|X-Zammad-Verify: true)})
content_messages += 1 content_messages += 1
break if content_max_check < content_messages break if content_max_check < content_messages
end end
@ -117,7 +117,7 @@ returns
next if !mail next if !mail
# check if verify message exists # check if verify message exists
next if !mail.match?(/#{verify_string}/) next if !mail.match?(%r{#{verify_string}})
Rails.logger.info " - verify email #{verify_string} found" Rails.logger.info " - verify email #{verify_string} found"
m.delete m.delete
@ -149,7 +149,7 @@ returns
next if !mail next if !mail
# ignore verify messages # ignore verify messages
if mail.match?(/(X-Zammad-Ignore: true|X-Zammad-Verify: true)/) && mail =~ /X-Zammad-Verify-Time:\s(.+?)\s/ if mail.match?(%r{(X-Zammad-Ignore: true|X-Zammad-Verify: true)}) && mail =~ %r{X-Zammad-Verify-Time:\s(.+?)\s}
begin begin
verify_time = Time.zone.parse($1) verify_time = Time.zone.parse($1)
if verify_time > Time.zone.now - 30.minutes if verify_time > Time.zone.now - 30.minutes

View file

@ -36,7 +36,7 @@ class Channel::Driver::Smtp
if !options.key?(:domain) if !options.key?(:domain)
# set fqdn, if local fqdn - use domain of sender # set fqdn, if local fqdn - use domain of sender
fqdn = Setting.get('fqdn') fqdn = Setting.get('fqdn')
if fqdn =~ /(localhost|\.local^|\.loc^)/i && (attr['from'] || attr[:from]) if fqdn =~ %r{(localhost|\.local^|\.loc^)}i && (attr['from'] || attr[:from])
domain = Mail::Address.new(attr['from'] || attr[:from]).domain domain = Mail::Address.new(attr['from'] || attr[:from]).domain
if domain if domain
fqdn = domain fqdn = domain

View file

@ -157,7 +157,7 @@ returns
=end =end
def self.recipient_line(realname, email) def self.recipient_line(realname, email)
return "#{realname} <#{email}>" if realname.match?(/^[A-z]+$/i) return "#{realname} <#{email}>" if realname.match?(%r{^[A-z]+$}i)
"\"#{realname.gsub('"', '\"')}\" <#{email}>" "\"#{realname.gsub('"', '\"')}\" <#{email}>"
end end
@ -175,7 +175,7 @@ Check if string is a complete html document. If not, add head and css styles.
# apply mail client fixes # apply mail client fixes
html = Channel::EmailBuild.html_mail_client_fixes(html) html = Channel::EmailBuild.html_mail_client_fixes(html)
return html if html.match?(/<html>/i) return html if html.match?(%r{<html>}i)
html_email_body = File.read(Rails.root.join('app/views/mailer/application_wrapper.html.erb').to_s) html_email_body = File.read(Rails.root.join('app/views/mailer/application_wrapper.html.erb').to_s)
@ -198,7 +198,7 @@ Add/change markup to display html in any mail client nice.
# https://github.com/martini/zammad/issues/165 # https://github.com/martini/zammad/issues/165
new_html = html.gsub('<blockquote type="cite">', '<blockquote type="cite" style="border-left: 2px solid blue; margin: 0 0 16px; padding: 8px 12px 8px 12px;">') new_html = html.gsub('<blockquote type="cite">', '<blockquote type="cite" style="border-left: 2px solid blue; margin: 0 0 16px; padding: 8px 12px 8px 12px;">')
new_html.gsub!(/<p>/mxi, '<p style="margin: 0;">') new_html.gsub!(%r{<p>}mxi, '<p style="margin: 0;">')
new_html.gsub!(%r{</?hr>}mxi, '<hr style="margin-top: 6px; margin-bottom: 6px; border: 0; border-top: 1px solid #dfdfdf;">') new_html.gsub!(%r{</?hr>}mxi, '<hr style="margin-top: 6px; margin-bottom: 6px; border: 0; border-top: 1px solid #dfdfdf;">')
new_html new_html
end end

View file

@ -4,7 +4,7 @@
class Channel::EmailParser class Channel::EmailParser
PROZESS_TIME_MAX = 180 PROZESS_TIME_MAX = 180
EMAIL_REGEX = /.+@.+/.freeze EMAIL_REGEX = %r{.+@.+}.freeze
RECIPIENT_FIELDS = %w[to cc delivered-to x-original-to envelope-to].freeze RECIPIENT_FIELDS = %w[to cc delivered-to x-original-to envelope-to].freeze
SENDER_FIELDS = %w[from reply-to return-path sender].freeze SENDER_FIELDS = %w[from reply-to return-path sender].freeze
EXCESSIVE_LINKS_MSG = 'This message cannot be displayed because it contains over 5,000 links. Download the raw message below and open it via an Email client if you still wish to view it.'.freeze EXCESSIVE_LINKS_MSG = 'This message cannot be displayed because it contains over 5,000 links. Download the raw message below and open it via an Email client if you still wish to view it.'.freeze
@ -351,7 +351,7 @@ returns
# skip check attributes if it is tags # skip check attributes if it is tags
return true if header_name == 'x-zammad-ticket-tags' return true if header_name == 'x-zammad-ticket-tags'
if header_name =~ /^x-zammad-(.+?)-(followup-|)(.*)$/i if header_name =~ %r{^x-zammad-(.+?)-(followup-|)(.*)$}i
class_name = $1 class_name = $1
attribute = $3 attribute = $3
end end
@ -401,7 +401,7 @@ returns
data[:from_local] = mail_address.local data[:from_local] = mail_address.local
data[:from_domain] = mail_address.domain data[:from_domain] = mail_address.domain
data[:from_display_name] = mail_address.display_name || mail_address.comments&.first data[:from_display_name] = mail_address.display_name || mail_address.comments&.first
elsif from =~ /^(.+?)<((.+?)@(.+?))>/ elsif from =~ %r{^(.+?)<((.+?)@(.+?))>}
data[:from_email] = $2 data[:from_email] = $2
data[:from_local] = $3 data[:from_local] = $3
data[:from_domain] = $4 data[:from_domain] = $4
@ -419,7 +419,7 @@ returns
.to_s .to_s
.delete('"') .delete('"')
.strip .strip
.gsub(/(^'|'$)/, '') .gsub(%r{(^'|'$)}, '')
data data
end end
@ -539,7 +539,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
part.body = force_japanese_encoding part.body.encoded.unpack1('M') part.body = force_japanese_encoding part.body.encoded.unpack1('M')
end end
ISO2022JP_REGEXP = /=\?ISO-2022-JP\?B\?(.+?)\?=/.freeze ISO2022JP_REGEXP = %r{=\?ISO-2022-JP\?B\?(.+?)\?=}.freeze
# https://github.com/zammad/zammad/issues/3115 # https://github.com/zammad/zammad/issues/3115
def header_field_unpack_japanese(field) def header_field_unpack_japanese(field)
@ -630,7 +630,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
return body_text if !options[:strict_html] return body_text if !options[:strict_html]
# Issue #2390 - emails with >5k HTML links should be rejected # Issue #2390 - emails with >5k HTML links should be rejected
return EXCESSIVE_LINKS_MSG if body_text.scan(/<a[[:space:]]/i).count >= 5_000 return EXCESSIVE_LINKS_MSG if body_text.scan(%r{<a[[:space:]]}i).count >= 5_000
body_text.html2html_strict body_text.html2html_strict
end end
@ -717,7 +717,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
rescue rescue
begin begin
case file.header[:content_disposition].to_s case file.header[:content_disposition].to_s
when /(filename|name)(\*{0,1})="(.+?)"/i, /(filename|name)(\*{0,1})='(.+?)'/i, /(filename|name)(\*{0,1})=(.+?);/i when %r{(filename|name)(\*{0,1})="(.+?)"}i, %r{(filename|name)(\*{0,1})='(.+?)'}i, %r{(filename|name)(\*{0,1})=(.+?);}i
filename = $3 filename = $3
end end
rescue rescue
@ -727,7 +727,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
begin begin
case file.header[:content_disposition].to_s case file.header[:content_disposition].to_s
when /(filename|name)(\*{0,1})="(.+?)"/i, /(filename|name)(\*{0,1})='(.+?)'/i, /(filename|name)(\*{0,1})=(.+?);/i when %r{(filename|name)(\*{0,1})="(.+?)"}i, %r{(filename|name)(\*{0,1})='(.+?)'}i, %r{(filename|name)(\*{0,1})=(.+?);}i
filename = $3 filename = $3
end end
rescue rescue
@ -737,7 +737,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
# as fallback, use raw values # as fallback, use raw values
if filename.blank? if filename.blank?
case headers_store['Content-Disposition'].to_s case headers_store['Content-Disposition'].to_s
when /(filename|name)(\*{0,1})="(.+?)"/i, /(filename|name)(\*{0,1})='(.+?)'/i, /(filename|name)(\*{0,1})=(.+?);/i when %r{(filename|name)(\*{0,1})="(.+?)"}i, %r{(filename|name)(\*{0,1})='(.+?)'}i, %r{(filename|name)(\*{0,1})=(.+?);}i
filename = $3 filename = $3
end end
end end
@ -767,7 +767,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
# e. g. Content-Type: video/quicktime; name="Video.MOV"; # e. g. Content-Type: video/quicktime; name="Video.MOV";
if filename.blank? if filename.blank?
['(filename|name)(\*{0,1})="(.+?)"(;|$)', '(filename|name)(\*{0,1})=\'(.+?)\'(;|$)', '(filename|name)(\*{0,1})=(.+?)(;|$)'].each do |regexp| ['(filename|name)(\*{0,1})="(.+?)"(;|$)', '(filename|name)(\*{0,1})=\'(.+?)\'(;|$)', '(filename|name)(\*{0,1})=(.+?)(;|$)'].each do |regexp|
if headers_store['Content-Type'] =~ /#{regexp}/i if headers_store['Content-Type'] =~ %r{#{regexp}}i
filename = $3 filename = $3
break break
end end
@ -785,7 +785,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
end end
# generate file name based on content-id with file extention # generate file name based on content-id with file extention
if filename.blank? && headers_store['Content-ID'].present? && headers_store['Content-ID'] =~ /(.+?\..{2,6})@.+?/i if filename.blank? && headers_store['Content-ID'].present? && headers_store['Content-ID'] =~ %r{(.+?\..{2,6})@.+?}i
filename = $1 filename = $1
end end
@ -802,7 +802,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
'image/gif': %w[gif image], 'image/gif': %w[gif image],
} }
map.each do |type, ext| map.each do |type, ext|
next if !content_type.match?(/^#{Regexp.quote(type)}/i) next if !content_type.match?(%r{^#{Regexp.quote(type)}}i)
filename = if headers_store['Content-Description'].present? filename = if headers_store['Content-Description'].present?
"#{headers_store['Content-Description']}.#{ext[0]}".to_s.force_encoding('utf-8') "#{headers_store['Content-Description']}.#{ext[0]}".to_s.force_encoding('utf-8')
@ -814,7 +814,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
end end
# generate file name based on content-id without file extention # generate file name based on content-id without file extention
if filename.blank? && headers_store['Content-ID'].present? && headers_store['Content-ID'] =~ /(.+?)@.+?/i if filename.blank? && headers_store['Content-ID'].present? && headers_store['Content-ID'] =~ %r{(.+?)@.+?}i
filename = $1 filename = $1
end end
@ -826,7 +826,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
# create uniq filename # create uniq filename
local_filename = '' local_filename = ''
local_extention = '' local_extention = ''
if filename =~ /^(.*?)\.(.+?)$/ if filename =~ %r{^(.*?)\.(.+?)$}
local_filename = $1 local_filename = $1
local_extention = $2 local_extention = $2
end end
@ -925,7 +925,7 @@ process unprocessable_mails (tmp/unprocessable_mail/*.eml) again
reply.merge( reply.merge(
to: parsed_incoming_mail[:from_email], to: parsed_incoming_mail[:from_email],
body: reply[:body].gsub(/\n/, "\r\n"), body: reply[:body].gsub(%r{\n}, "\r\n"),
content_type: 'text/plain', content_type: 'text/plain',
References: parsed_incoming_mail[:message_id], References: parsed_incoming_mail[:message_id],
'In-Reply-To': parsed_incoming_mail[:message_id], 'In-Reply-To': parsed_incoming_mail[:message_id],
@ -978,7 +978,7 @@ module Mail
end end
return value if value.blank? return value if value.blank?
value.sub(/^.+?:(\s|)/, '') value.sub(%r{^.+?:(\s|)}, '')
end end
end end

View file

@ -15,17 +15,17 @@ module Channel::Filter::AutoResponseCheck
mail[ :'x-zammad-article-preferences' ]['is-auto-response'] = true mail[ :'x-zammad-article-preferences' ]['is-auto-response'] = true
# do not send an auto response if one of the following headers exists # do not send an auto response if one of the following headers exists
return if mail[ :'list-unsubscribe' ] && mail[ :'list-unsubscribe' ] =~ /.../ return if mail[ :'list-unsubscribe' ] && mail[ :'list-unsubscribe' ] =~ %r{...}
return if mail[ :'x-loop' ] && mail[ :'x-loop' ] =~ /(yes|true)/i return if mail[ :'x-loop' ] && mail[ :'x-loop' ] =~ %r{(yes|true)}i
return if mail[ :precedence ] && mail[ :precedence ] =~ /(bulk|list|junk)/i return if mail[ :precedence ] && mail[ :precedence ] =~ %r{(bulk|list|junk)}i
return if mail[ :'auto-submitted' ] && mail[ :'auto-submitted' ] =~ /auto-(generated|replied)/i return if mail[ :'auto-submitted' ] && mail[ :'auto-submitted' ] =~ %r{auto-(generated|replied)}i
return if mail[ :'x-auto-response-suppress' ] && mail[ :'x-auto-response-suppress' ] =~ /all/i return if mail[ :'x-auto-response-suppress' ] && mail[ :'x-auto-response-suppress' ] =~ %r{all}i
# do not send an auto response if sender is system itself # do not send an auto response if sender is system itself
message_id = mail[ :message_id ] message_id = mail[ :message_id ]
if message_id if message_id
fqdn = Setting.get('fqdn') fqdn = Setting.get('fqdn')
return if message_id.match?(/@#{Regexp.quote(fqdn)}/i) return if message_id.match?(%r{@#{Regexp.quote(fqdn)}}i)
end end
mail[ :'x-zammad-send-auto-response' ] = true mail[ :'x-zammad-send-auto-response' ] = true

View file

@ -53,7 +53,7 @@ module Channel::Filter::BounceDeliveryPermanentFailed
# get recipient bounce mail, mark this user to not sent notifications anymore # get recipient bounce mail, mark this user to not sent notifications anymore
final_recipient = mail[:mail_instance].final_recipient final_recipient = mail[:mail_instance].final_recipient
if final_recipient.present? if final_recipient.present?
final_recipient.sub!(/rfc822;\s{0,10}/, '') final_recipient.sub!(%r{rfc822;\s{0,10}}, '')
if final_recipient.present? if final_recipient.present?
recipients.push final_recipient.downcase recipients.push final_recipient.downcase
end end

View file

@ -72,7 +72,7 @@ module Channel::Filter::FollowUpCheck
references += mail[:'in-reply-to'] references += mail[:'in-reply-to']
end end
if references != '' if references != ''
message_ids = references.split(/\s+/) message_ids = references.split(%r{\s+})
message_ids.each do |message_id| message_ids.each do |message_id|
message_id_md5 = Digest::MD5.hexdigest(message_id) message_id_md5 = Digest::MD5.hexdigest(message_id)
article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first article = Ticket::Article.where(message_id_md5: message_id_md5).order('created_at DESC, id DESC').limit(1).first
@ -86,7 +86,7 @@ module Channel::Filter::FollowUpCheck
# remove leading "..:\s" and "..[\d+]:\s" e. g. "Re: " or "Re[5]: " # remove leading "..:\s" and "..[\d+]:\s" e. g. "Re: " or "Re[5]: "
subject_to_check = mail[:subject] subject_to_check = mail[:subject]
subject_to_check.gsub!(/^(..(\[\d+\])?:\s+)+/, '') subject_to_check.gsub!(%r{^(..(\[\d+\])?:\s+)+}, '')
# if subject is different, it's no followup # if subject is different, it's no followup
next if subject_to_check != article_first.subject next if subject_to_check != article_first.subject
@ -119,7 +119,7 @@ module Channel::Filter::FollowUpCheck
def self.follow_up_by_md5(mail) def self.follow_up_by_md5(mail)
return if mail[:'x-zammad-ticket-id'] return if mail[:'x-zammad-ticket-id']
mail_references(mail).split(/\s+/).each do |message_id| mail_references(mail).split(%r{\s+}).each do |message_id|
article = message_id_article(message_id) article = message_id_article(message_id)
next if article.blank? next if article.blank?

View file

@ -8,7 +8,7 @@ module Channel::Filter::FollowUpPossibleCheck
ticket = Ticket.lookup(id: ticket_id) ticket = Ticket.lookup(id: ticket_id)
return true if !ticket return true if !ticket
return true if !ticket.state.state_type.name.match?(/^(closed|merged|removed)/i) return true if !ticket.state.state_type.name.match?(%r{^(closed|merged|removed)}i)
# in case of closed tickets, remove follow-up information # in case of closed tickets, remove follow-up information
case ticket.group.follow_up_possible case ticket.group.follow_up_possible

View file

@ -123,10 +123,10 @@ module Channel::Filter::IdentifySender
recipients.each do |recipient| recipients.each do |recipient|
address = nil address = nil
display_name = nil display_name = nil
if recipient =~ /.*<(.+?)>/ if recipient =~ %r{.*<(.+?)>}
address = $1 address = $1
end end
if recipient =~ /^(.+?)<(.+?)>/ if recipient =~ %r{^(.+?)<(.+?)>}
display_name = $1 display_name = $1
end end
@ -162,7 +162,7 @@ module Channel::Filter::IdentifySender
end end
def self.populate_attributes!(attrs, **extras) def self.populate_attributes!(attrs, **extras)
if attrs[:email].match?(/\S\s+\S/) || attrs[:email].match?(/^<|>$/) if attrs[:email].match?(%r{\S\s+\S}) || attrs[:email].match?(%r{^<|>$})
attrs[:preferences] = { mail_delivery_failed: true, attrs[:preferences] = { mail_delivery_failed: true,
mail_delivery_failed_reason: 'invalid email', mail_delivery_failed_reason: 'invalid email',
mail_delivery_failed_data: Time.zone.now } mail_delivery_failed_data: Time.zone.now }
@ -187,7 +187,7 @@ module Channel::Filter::IdentifySender
.delete('"') .delete('"')
.delete_prefix("'") .delete_prefix("'")
.delete_suffix("'") .delete_suffix("'")
.gsub(/.+?\s\(.+?\)$/, '') .gsub(%r{.+?\s\(.+?\)$}, '')
end end
def self.sanitize_email(string) def self.sanitize_email(string)
@ -198,9 +198,9 @@ module Channel::Filter::IdentifySender
.delete('"') .delete('"')
.delete("'") .delete("'")
.delete(' ') # see https://github.com/zammad/zammad/issues/2254 .delete(' ') # see https://github.com/zammad/zammad/issues/2254
.sub(/^<|>$/, '') # see https://github.com/zammad/zammad/issues/2254 .sub(%r{^<|>$}, '') # see https://github.com/zammad/zammad/issues/2254
.sub(/\A'(.*)'\z/, '\1') # see https://github.com/zammad/zammad/issues/2154 .sub(%r{\A'(.*)'\z}, '\1') # see https://github.com/zammad/zammad/issues/2154
.gsub(/\s/, '') # see https://github.com/zammad/zammad/issues/2198 .gsub(%r{\s}, '') # see https://github.com/zammad/zammad/issues/2198
.delete_suffix('.') .delete_suffix('.')
end end

View file

@ -2,20 +2,20 @@ module Channel::Filter::Match::EmailRegex
def self.match(value:, match_rule:, check_mode: false) def self.match(value:, match_rule:, check_mode: false)
regexp = false regexp = false
if match_rule =~ /^(regex:)(.+?)$/ if match_rule =~ %r{^(regex:)(.+?)$}
regexp = true regexp = true
match_rule = $2 match_rule = $2
end end
if regexp == false if regexp == false
match_rule_quoted = Regexp.quote(match_rule).gsub(/\\\*/, '.*') match_rule_quoted = Regexp.quote(match_rule).gsub(%r{\\\*}, '.*')
return true if value.match?(/#{match_rule_quoted}/i) return true if value.match?(%r{#{match_rule_quoted}}i)
return false return false
end end
begin begin
return true if value.match?(/#{match_rule}/i) return true if value.match?(%r{#{match_rule}}i)
return false return false
rescue => e rescue => e

View file

@ -47,26 +47,26 @@ class Channel::Filter::MonitoringBase
return if result['host'].blank? return if result['host'].blank?
# icinga - get state by body - new templates # icinga - get state by body - new templates
if result['state'].blank? && mail[:body] =~ /.+?\sis\s(.+?)!/ if result['state'].blank? && mail[:body] =~ %r{.+?\sis\s(.+?)!}
result['state'] = $1 result['state'] = $1
end end
# icinga - get state by subject - new templates "state:" is not in body anymore # icinga - get state by subject - new templates "state:" is not in body anymore
# Subject: [PROBLEM] Ping IPv4 on host1234.dc.example.com is WARNING! # Subject: [PROBLEM] Ping IPv4 on host1234.dc.example.com is WARNING!
# Subject: [PROBLEM] Host host1234.dc.example.com is DOWN! # Subject: [PROBLEM] Host host1234.dc.example.com is DOWN!
if result['state'].blank? && mail[:subject] =~ /(on|Host)\s.+?\sis\s(.+?)!/ if result['state'].blank? && mail[:subject] =~ %r{(on|Host)\s.+?\sis\s(.+?)!}
result['state'] = $2 result['state'] = $2
end end
# monit - get missing attributes from body # monit - get missing attributes from body
if result['service'].blank? && mail[:body] =~ /\sService\s(.+?)\s/ if result['service'].blank? && mail[:body] =~ %r{\sService\s(.+?)\s}
result['service'] = $1 result['service'] = $1
end end
# possible event types https://mmonit.com/monit/documentation/#Setting-an-event-filter # possible event types https://mmonit.com/monit/documentation/#Setting-an-event-filter
if result['state'].blank? if result['state'].blank?
result['state'] = case mail[:body] result['state'] = case mail[:body]
when /\s(done|recovery|succeeded|bytes\sok|packets\sok)\s/, /(instance\schanged\snot|Link\sup|Exists|Saturation\sok|Speed\sok)/ when %r{\s(done|recovery|succeeded|bytes\sok|packets\sok)\s}, %r{(instance\schanged\snot|Link\sup|Exists|Saturation\sok|Speed\sok)}
'OK' 'OK'
else else
'CRITICAL' 'CRITICAL'
@ -89,7 +89,7 @@ class Channel::Filter::MonitoringBase
mail[ :'x-zammad-ticket-id' ] = ticket.id mail[ :'x-zammad-ticket-id' ] = ticket.id
# check if service is recovered # check if service is recovered
if auto_close && result['state'].present? && result['state'].match(/#{state_recovery_match}/i) if auto_close && result['state'].present? && result['state'].match(%r{#{state_recovery_match}}i)
Rails.logger.info "MonitoringBase.#{integration} set autoclose to state_id #{auto_close_state_id}" Rails.logger.info "MonitoringBase.#{integration} set autoclose to state_id #{auto_close_state_id}"
state = Ticket::State.lookup(id: auto_close_state_id) state = Ticket::State.lookup(id: auto_close_state_id)
if state if state
@ -112,13 +112,13 @@ class Channel::Filter::MonitoringBase
end end
# ignore states # ignore states
if state_ignore_match.present? && result['state'].present? && result['state'].match(/#{state_ignore_match}/i) if state_ignore_match.present? && result['state'].present? && result['state'].match(%r{#{state_ignore_match}}i)
mail[ :'x-zammad-ignore' ] = true mail[ :'x-zammad-ignore' ] = true
return true return true
end end
# if now problem exists, just ignore the email # if now problem exists, just ignore the email
if result['state'].present? && result['state'].match(/#{state_recovery_match}/i) if result['state'].present? && result['state'].match(%r{#{state_recovery_match}}i)
mail[ :'x-zammad-ignore' ] = true mail[ :'x-zammad-ignore' ] = true
return true return true
end end

View file

@ -8,7 +8,7 @@ module Channel::Filter::OutOfOfficeCheck
# check ms out of office characteristics # check ms out of office characteristics
if mail[ :'x-auto-response-suppress' ] if mail[ :'x-auto-response-suppress' ]
return if !mail[ :'x-auto-response-suppress' ].match?(/all/i) return if !mail[ :'x-auto-response-suppress' ].match?(%r{all}i)
return if !mail[ :'x-ms-exchange-inbox-rules-loop' ] return if !mail[ :'x-ms-exchange-inbox-rules-loop' ]
mail[ :'x-zammad-out-of-office' ] = true mail[ :'x-zammad-out-of-office' ] = true
@ -18,17 +18,17 @@ module Channel::Filter::OutOfOfficeCheck
if mail[ :'auto-submitted' ] if mail[ :'auto-submitted' ]
# check zimbra out of office characteristics # check zimbra out of office characteristics
if mail[ :'auto-submitted' ].match?(/vacation/i) if mail[ :'auto-submitted' ].match?(%r{vacation}i)
mail[ :'x-zammad-out-of-office' ] = true mail[ :'x-zammad-out-of-office' ] = true
end end
# check cloud out of office characteristics # check cloud out of office characteristics
if mail[ :'auto-submitted' ].match?(/auto-replied;\sowner-email=/i) if mail[ :'auto-submitted' ].match?(%r{auto-replied;\sowner-email=}i)
mail[ :'x-zammad-out-of-office' ] = true mail[ :'x-zammad-out-of-office' ] = true
end end
# gmail check out of office characteristics # gmail check out of office characteristics
if mail[ :'auto-submitted' ] =~ /auto-replied/i && mail[ :subject ] =~ /vacation/i if mail[ :'auto-submitted' ] =~ %r{auto-replied}i && mail[ :subject ] =~ %r{vacation}i
mail[ :'x-zammad-out-of-office' ] = true mail[ :'x-zammad-out-of-office' ] = true
end end

View file

@ -9,10 +9,10 @@ module Channel::Filter::OwnNotificationLoopDetection
recedence = mail[:precedence] recedence = mail[:precedence]
return if !recedence return if !recedence
return if !recedence.match?(/bulk/i) return if !recedence.match?(%r{bulk}i)
fqdn = Setting.get('fqdn') fqdn = Setting.get('fqdn')
return if !message_id.match?(/@#{Regexp.quote(fqdn)}>/i) return if !message_id.match?(%r{@#{Regexp.quote(fqdn)}>}i)
mail[ :'x-zammad-ignore' ] = true mail[ :'x-zammad-ignore' ] = true
Rails.logger.info "Detected own sent notification mail and dropped it to prevent loops (message_id: #{message_id}, from: #{mail[:from]}, to: #{mail[:to]})" Rails.logger.info "Detected own sent notification mail and dropped it to prevent loops (message_id: #{message_id}, from: #{mail[:from]}, to: #{mail[:to]})"

View file

@ -44,7 +44,7 @@ returns:
# check if we can find the service now relation # check if we can find the service now relation
source_id = nil source_id = nil
if subject =~ /\s(INC\d+)\s/ if subject =~ %r{\s(INC\d+)\s}
source_id = $1 source_id = $1
end end

View file

@ -8,7 +8,7 @@ module Channel::Filter::Trusted
# check if trust x-headers # check if trust x-headers
if !trusted(channel) if !trusted(channel)
mail.each_key do |key| mail.each_key do |key|
next if !key.match?(/^x-zammad/i) next if !key.match?(%r{^x-zammad}i)
mail.delete(key) mail.delete(key)
end end
@ -17,7 +17,7 @@ module Channel::Filter::Trusted
# verify values # verify values
mail.each do |key, value| mail.each do |key, value|
next if !key.match?(/^x-zammad/i) next if !key.match?(%r{^x-zammad}i)
# no assoc exists, remove header # no assoc exists, remove header
next if Channel::EmailParser.check_attributes_by_x_headers(key, value) next if Channel::EmailParser.check_attributes_by_x_headers(key, value)

View file

@ -611,7 +611,7 @@ check if ip address is blocked for chat
ips = block_ip.split(';') ips = block_ip.split(';')
ips.each do |local_ip| ips.each do |local_ip|
return true if ip == local_ip.strip return true if ip == local_ip.strip
return true if ip.match?(/#{local_ip.strip.gsub(/\*/, '.+?')}/) return true if ip.match?(%r{#{local_ip.strip.gsub(%r{\*}, '.+?')}})
end end
false false
end end

View file

@ -37,7 +37,7 @@ returns
if options[:only_attached_attachments] == true && is_html_content == true if options[:only_attached_attachments] == true && is_html_content == true
content_id = new_attachment.preferences['Content-ID'] || new_attachment.preferences['content_id'] content_id = new_attachment.preferences['Content-ID'] || new_attachment.preferences['content_id']
next if content_id.present? && body.present? && body.match?(/#{Regexp.quote(content_id)}/i) next if content_id.present? && body.present? && body.match?(%r{#{Regexp.quote(content_id)}}i)
end end
# only_inline_attachments mode is used when quoting HTML mail with #{article.body_as_html} # only_inline_attachments mode is used when quoting HTML mail with #{article.body_as_html}
@ -46,11 +46,11 @@ returns
next if body.blank? next if body.blank?
content_disposition = new_attachment.preferences['Content-Disposition'] || new_attachment.preferences['content_disposition'] content_disposition = new_attachment.preferences['Content-Disposition'] || new_attachment.preferences['content_disposition']
next if content_disposition.present? && content_disposition !~ /inline/ next if content_disposition.present? && content_disposition !~ %r{inline}
content_id = new_attachment.preferences['Content-ID'] || new_attachment.preferences['content_id'] content_id = new_attachment.preferences['Content-ID'] || new_attachment.preferences['content_id']
next if content_id.blank? next if content_id.blank?
next if !body.match?(/#{Regexp.quote(content_id)}/i) next if !body.match?(%r{#{Regexp.quote(content_id)}}i)
end end
already_added = false already_added = false

View file

@ -12,7 +12,7 @@ module ChecksClientNotification
def notify_clients_data(event) def notify_clients_data(event)
class_name = self.class.name class_name = self.class.name
class_name.gsub!(/::/, '') class_name.gsub!(%r{::}, '')
{ {
message: { message: {

View file

@ -58,7 +58,7 @@ Checks if file is used inline
node.remove node.remove
when 'div' when 'div'
node.children.to_a.select { |t| t.text.match?(/\A([\n\r]+)\z/) }.each(&:remove) node.children.to_a.select { |t| t.text.match?(%r{\A([\n\r]+)\z}) }.each(&:remove)
node.remove if node.children.none? && node.classes.none? node.remove if node.children.none? && node.classes.none?
end end
@ -138,7 +138,7 @@ Checks if file is used inline
next if node.name != 'img' next if node.name != 'img'
next if !node['src']&.start_with?('cid:') next if !node['src']&.start_with?('cid:')
cid = node['src'].sub(/^cid:/, '') cid = node['src'].sub(%r{^cid:}, '')
lookup_cids = [cid, "<#{cid}>"] lookup_cids = [cid, "<#{cid}>"]
attachment = attachments.find do |file| attachment = attachments.find do |file|
@ -164,7 +164,7 @@ Checks if file is used inline
next if node.name != 'img' next if node.name != 'img'
next if !node['src']&.start_with? 'cid:' next if !node['src']&.start_with? 'cid:'
cid = node['src'].sub(/^cid:/, '') cid = node['src'].sub(%r{^cid:}, '')
inline_cids << cid inline_cids << cid
end end

View file

@ -226,19 +226,19 @@ returns
# see specs for example # see specs for example
return [] if !text.is_a?(String) return [] if !text.is_a?(String)
text.scan(/([\d\s\-(|)]{6,26})/).map do |match| text.scan(%r{([\d\s\-(|)]{6,26})}).map do |match|
normalize_number(match[0]) normalize_number(match[0])
end end
end end
def self.normalize_number(number) def self.normalize_number(number)
number = number.gsub(/[\s-]/, '') number = number.gsub(%r{[\s-]}, '')
number.gsub!(/^(00)?(\+?\d\d)\(0?(\d*)\)/, '\\1\\2\\3') number.gsub!(%r{^(00)?(\+?\d\d)\(0?(\d*)\)}, '\\1\\2\\3')
number.gsub!(/\D/, '') number.gsub!(%r{\D}, '')
case number case number
when /^00/ when %r{^00}
number[2..] number[2..]
when /^0/ when %r{^0}
DEFAULT_COUNTRY_ID + number[1..] DEFAULT_COUNTRY_ID + number[1..]
else else
number number

View file

@ -97,8 +97,8 @@ class Cti::Driver::Base
if routing_table.present? if routing_table.present?
routing_table.each do |row| routing_table.each do |row|
dest = row[:dest].gsub(/\*/, '.+?') dest = row[:dest].gsub(%r{\*}, '.+?')
next if !to.match?(/^#{dest}$/) next if !to.match?(%r{^#{dest}$})
return { return {
action: 'set_caller_id', action: 'set_caller_id',

View file

@ -6,7 +6,7 @@ module Cti
store :preferences, accessors: %i[from_pretty to_pretty] store :preferences, accessors: %i[from_pretty to_pretty]
validates :state, format: { with: /\A(newCall|answer|hangup)\z/,  message: 'newCall|answer|hangup is allowed' } validates :state, format: { with: %r{\A(newCall|answer|hangup)\z},  message: 'newCall|answer|hangup is allowed' }
before_create :set_pretty before_create :set_pretty
before_update :set_pretty before_update :set_pretty
@ -506,7 +506,7 @@ optional you can put the max oldest chat entries as argument
def set_pretty def set_pretty
%i[from to].each do |field| %i[from to].each do |field|
parsed = TelephoneNumber.parse(send(field)&.sub(/^\+?/, '+')) parsed = TelephoneNumber.parse(send(field)&.sub(%r{^\+?}, '+'))
preferences[:"#{field}_pretty"] = parsed.send(parsed.valid? ? :international_number : :original_number) preferences[:"#{field}_pretty"] = parsed.send(parsed.valid? ? :international_number : :original_number)
end end
end end

View file

@ -264,7 +264,7 @@ job.run(true)
def match_minutes(minutes) def match_minutes(minutes)
return 0 if minutes < 10 return 0 if minutes < 10
"#{minutes.to_s.gsub(/(\d)\d/, '\\1')}0".to_i "#{minutes.to_s.gsub(%r{(\d)\d}, '\\1')}0".to_i
end end
end end

View file

@ -569,22 +569,22 @@ to send no browser reload event, pass false
data_type = nil data_type = nil
case attribute.data_type case attribute.data_type
when /^input|select|tree_select|richtext|textarea|checkbox$/ when %r{^input|select|tree_select|richtext|textarea|checkbox$}
data_type = :string data_type = :string
when /^integer|user_autocompletion$/ when %r{^integer|user_autocompletion$}
data_type = :integer data_type = :integer
when /^boolean|active$/ when %r{^boolean|active$}
data_type = :boolean data_type = :boolean
when /^datetime$/ when %r{^datetime$}
data_type = :datetime data_type = :datetime
when /^date$/ when %r{^date$}
data_type = :date data_type = :date
end end
# change field # change field
if model.column_names.include?(attribute.name) if model.column_names.include?(attribute.name)
case attribute.data_type case attribute.data_type
when /^input|select|tree_select|richtext|textarea|checkbox$/ when %r{^input|select|tree_select|richtext|textarea|checkbox$}
ActiveRecord::Migration.change_column( ActiveRecord::Migration.change_column(
model.table_name, model.table_name,
attribute.name, attribute.name,
@ -592,7 +592,7 @@ to send no browser reload event, pass false
limit: attribute.data_option[:maxlength], limit: attribute.data_option[:maxlength],
null: true null: true
) )
when /^integer|user_autocompletion|datetime|date$/, /^boolean|active$/ when %r{^integer|user_autocompletion|datetime|date$}, %r{^boolean|active$}
ActiveRecord::Migration.change_column( ActiveRecord::Migration.change_column(
model.table_name, model.table_name,
attribute.name, attribute.name,
@ -616,7 +616,7 @@ to send no browser reload event, pass false
# create field # create field
case attribute.data_type case attribute.data_type
when /^input|select|tree_select|richtext|textarea|checkbox$/ when %r{^input|select|tree_select|richtext|textarea|checkbox$}
ActiveRecord::Migration.add_column( ActiveRecord::Migration.add_column(
model.table_name, model.table_name,
attribute.name, attribute.name,
@ -624,7 +624,7 @@ to send no browser reload event, pass false
limit: attribute.data_option[:maxlength], limit: attribute.data_option[:maxlength],
null: true null: true
) )
when /^integer|user_autocompletion$/, /^boolean|active$/, /^datetime|date$/ when %r{^integer|user_autocompletion$}, %r{^boolean|active$}, %r{^datetime|date$}
ActiveRecord::Migration.add_column( ActiveRecord::Migration.add_column(
model.table_name, model.table_name,
attribute.name, attribute.name,
@ -780,22 +780,22 @@ is certain attribute used by triggers, overviews or schedulers
def check_name def check_name
return if !name return if !name
if name.match?(/.+?_(id|ids)$/i) if name.match?(%r{.+?_(id|ids)$}i)
errors.add(:name, "can't get used because *_id and *_ids are not allowed") errors.add(:name, "can't get used because *_id and *_ids are not allowed")
end end
if name.match?(/\s/) if name.match?(%r{\s})
errors.add(:name, 'spaces are not allowed') errors.add(:name, 'spaces are not allowed')
end end
if !name.match?(/^[a-z0-9_]+$/) if !name.match?(%r{^[a-z0-9_]+$})
errors.add(:name, 'Only letters from a-z because numbers from 0-9 and _ are allowed') errors.add(:name, 'Only letters from a-z because numbers from 0-9 and _ are allowed')
end end
if !name.match?(/[a-z]/) if !name.match?(%r{[a-z]})
errors.add(:name, 'At least one letters is needed') errors.add(:name, 'At least one letters is needed')
end end
# do not allow model method names as attributes # do not allow model method names as attributes
reserved_words = %w[destroy true false integer select drop create alter index table varchar blob date datetime timestamp url icon initials avatar permission validate subscribe unsubscribe translate search _type _doc _id id] reserved_words = %w[destroy true false integer select drop create alter index table varchar blob date datetime timestamp url icon initials avatar permission validate subscribe unsubscribe translate search _type _doc _id id]
if name.match?(/^(#{reserved_words.join('|')})$/) if name.match?(%r{^(#{reserved_words.join('|')})$})
errors.add(:name, "#{name} is a reserved word! (1)") errors.add(:name, "#{name} is a reserved word! (1)")
end end
@ -833,7 +833,7 @@ is certain attribute used by triggers, overviews or schedulers
local_data_option[:null] = true if local_data_option[:null].nil? local_data_option[:null] = true if local_data_option[:null].nil?
case data_type case data_type
when /^((tree_)?select|checkbox)$/ when %r{^((tree_)?select|checkbox)$}
local_data_option[:nulloption] = true if local_data_option[:nulloption].nil? local_data_option[:nulloption] = true if local_data_option[:nulloption].nil?
local_data_option[:maxlength] ||= 255 local_data_option[:maxlength] ||= 255
end end
@ -882,17 +882,17 @@ is certain attribute used by triggers, overviews or schedulers
when 'input' when 'input'
[{ failed: %w[text password tel fax email url].exclude?(local_data_option[:type]), [{ failed: %w[text password tel fax email url].exclude?(local_data_option[:type]),
message: 'must have one of text/password/tel/fax/email/url for :type' }, message: 'must have one of text/password/tel/fax/email/url for :type' },
{ failed: !local_data_option[:maxlength].to_s.match?(/^\d+$/), { failed: !local_data_option[:maxlength].to_s.match?(%r{^\d+$}),
message: 'must have integer for :maxlength' }] message: 'must have integer for :maxlength' }]
when 'richtext' when 'richtext'
[{ failed: !local_data_option[:maxlength].to_s.match?(/^\d+$/), [{ failed: !local_data_option[:maxlength].to_s.match?(%r{^\d+$}),
message: 'must have integer for :maxlength' }] message: 'must have integer for :maxlength' }]
when 'integer' when 'integer'
[{ failed: !local_data_option[:min].to_s.match?(/^\d+$/), [{ failed: !local_data_option[:min].to_s.match?(%r{^\d+$}),
message: 'must have integer for :min' }, message: 'must have integer for :min' },
{ failed: !local_data_option[:max].to_s.match?(/^\d+$/), { failed: !local_data_option[:max].to_s.match?(%r{^\d+$}),
message: 'must have integer for :max' }] message: 'must have integer for :max' }]
when /^((tree_)?select|checkbox)$/ when %r{^((tree_)?select|checkbox)$}
[{ failed: !local_data_option.key?(:default), [{ failed: !local_data_option.key?(:default),
message: 'must have value for :default' }, message: 'must have value for :default' },
{ failed: local_data_option[:options].nil? && local_data_option[:relation].nil?, { failed: local_data_option[:options].nil? && local_data_option[:relation].nil?,

View file

@ -38,8 +38,8 @@ class Organization < ApplicationModel
def domain_cleanup def domain_cleanup
return true if domain.blank? return true if domain.blank?
domain.gsub!(/@/, '') domain.gsub!(%r{@}, '')
domain.gsub!(/\s*/, '') domain.gsub!(%r{\s*}, '')
domain.strip! domain.strip!
domain.downcase! domain.downcase!
true true

View file

@ -98,7 +98,7 @@ class Overview < ApplicationModel
def link_name(name) def link_name(name)
local_link = name.downcase local_link = name.downcase
local_link = local_link.parameterize(separator: '_') local_link = local_link.parameterize(separator: '_')
local_link.gsub!(/\s/, '_') local_link.gsub!(%r{\s}, '_')
local_link.squeeze!('_') local_link.squeeze!('_')
local_link = CGI.escape(local_link) local_link = CGI.escape(local_link)
if local_link.blank? if local_link.blank?

View file

@ -64,7 +64,7 @@ install all packages located under auto_install/*.zpm
data = [] data = []
Dir.foreach(path) do |entry| Dir.foreach(path) do |entry|
if entry.include?('.zpm') && entry !~ /^\./ if entry.include?('.zpm') && entry !~ %r{^\.}
data.push entry data.push entry
end end
end end
@ -133,7 +133,7 @@ execute migration down + unlink files
Dir.glob("#{package_base_dir}/**/*") do |entry| Dir.glob("#{package_base_dir}/**/*") do |entry|
entry = entry.sub('//', '/') entry = entry.sub('//', '/')
file = entry file = entry
file = file.sub(/#{package_base_dir}/, '') file = file.sub(%r{#{package_base_dir}}, '')
dest = "#{@@root}/#{file}" dest = "#{@@root}/#{file}"
if File.symlink?(dest.to_s) if File.symlink?(dest.to_s)
@ -166,7 +166,7 @@ link files + execute migration up
Dir.glob("#{package_base_dir}/**/*") do |entry| Dir.glob("#{package_base_dir}/**/*") do |entry|
entry = entry.sub('//', '/') entry = entry.sub('//', '/')
file = entry file = entry
file = file.sub(/#{package_base_dir}/, '') file = file.sub(%r{#{package_base_dir}}, '')
file = file.sub(%r{^/}, '') file = file.sub(%r{^/}, '')
# ignore files # ignore files

View file

@ -41,7 +41,7 @@ class Package::Migration < ApplicationModel
version = nil version = nil
name = nil name = nil
if migration =~ /^(.+?)_(.*)\.rb$/ if migration =~ %r{^(.+?)_(.*)\.rb$}
version = $1 version = $1
name = $2 name = $2
end end

View file

@ -12,7 +12,7 @@ class PostmasterFilter < ApplicationModel
raise Exceptions::UnprocessableEntity, 'Min. one match rule needed!' if match.blank? raise Exceptions::UnprocessableEntity, 'Min. one match rule needed!' if match.blank?
match.each_value do |meta| match.each_value do |meta|
raise Exceptions::UnprocessableEntity, 'operator invalid, ony "contains" and "contains not" is supported' if meta['operator'].blank? || meta['operator'] !~ /^(contains|contains not)$/ raise Exceptions::UnprocessableEntity, 'operator invalid, ony "contains" and "contains not" is supported' if meta['operator'].blank? || meta['operator'] !~ %r{^(contains|contains not)$}
raise Exceptions::UnprocessableEntity, 'value invalid/empty' if meta['value'].blank? raise Exceptions::UnprocessableEntity, 'value invalid/empty' if meta['value'].blank?
begin begin

View file

@ -120,7 +120,7 @@ reload config settings
@@current[key] = value @@current[key] = value
next next
end end
@@current[key] = value.gsub(/\#\{config\.(.+?)\}/) do @@current[key] = value.gsub(%r{\#\{config\.(.+?)\}}) do
@@raw[$1].to_s @@raw[$1].to_s
end end
end end

View file

@ -4,7 +4,7 @@ class SMIMECertificate < ApplicationModel
validates :fingerprint, uniqueness: true validates :fingerprint, uniqueness: true
def self.parse(raw) def self.parse(raw)
OpenSSL::X509::Certificate.new(raw.gsub(/(?:TRUSTED\s)?(CERTIFICATE---)/, '\1')) OpenSSL::X509::Certificate.new(raw.gsub(%r{(?:TRUSTED\s)?(CERTIFICATE---)}, '\1'))
end end
# Search for the certificate of the given sender email address # Search for the certificate of the given sender email address
@ -94,7 +94,7 @@ class SMIMECertificate < ApplicationModel
def email_addresses_from_subject_alt_name(subject_alt_name) def email_addresses_from_subject_alt_name(subject_alt_name)
# ["IP Address:192.168.7.23", "IP Address:192.168.7.42", "email:jd@example.com", "email:John.Doe@example.com", "dirName:dir_sect"] # ["IP Address:192.168.7.23", "IP Address:192.168.7.42", "email:jd@example.com", "email:John.Doe@example.com", "dirName:dir_sect"]
entries = subject_alt_name.value.split(/,\s?/) entries = subject_alt_name.value.split(%r{,\s?})
entries.each_with_object([]) do |entry, result| entries.each_with_object([]) do |entry, result|
# ["email:jd@example.com", "email:John.Doe@example.com"] # ["email:jd@example.com", "email:John.Doe@example.com"]

View file

@ -114,9 +114,9 @@ push text_modules to online
def validate_content def validate_content
return true if content.blank? return true if content.blank?
return true if content.match?(/<.+?>/) return true if content.match?(%r{<.+?>})
content.gsub!(/(\r\n|\n\r|\r)/, "\n") content.gsub!(%r{(\r\n|\n\r|\r)}, "\n")
self.content = content.text2html self.content = content.text2html
true true
end end

View file

@ -627,7 +627,7 @@ condition example
selector = selector_raw.stringify_keys selector = selector_raw.stringify_keys
raise "Invalid selector, operator missing #{selector.inspect}" if !selector['operator'] raise "Invalid selector, operator missing #{selector.inspect}" if !selector['operator']
raise "Invalid selector, operator #{selector['operator']} is invalid #{selector.inspect}" if !selector['operator'].match?(/^(is|is\snot|contains|contains\s(not|all|one|all\snot|one\snot)|(after|before)\s\(absolute\)|(within\snext|within\slast|after|before|till|from)\s\(relative\))|(is\sin\sworking\stime|is\snot\sin\sworking\stime)$/) raise "Invalid selector, operator #{selector['operator']} is invalid #{selector.inspect}" if !selector['operator'].match?(%r{^(is|is\snot|contains|contains\s(not|all|one|all\snot|one\snot)|(after|before)\s\(absolute\)|(within\snext|within\slast|after|before|till|from)\s\(relative\))|(is\sin\sworking\stime|is\snot\sin\sworking\stime)$})
# validate value / allow blank but only if pre_condition exists and is not specific # validate value / allow blank but only if pre_condition exists and is not specific
if !selector.key?('value') || if !selector.key?('value') ||
@ -639,7 +639,7 @@ condition example
end end
# validate pre_condition values # validate pre_condition values
return nil if selector['pre_condition'] && selector['pre_condition'] !~ /^(not_set|current_user\.|specific)/ return nil if selector['pre_condition'] && selector['pre_condition'] !~ %r{^(not_set|current_user\.|specific)}
# get attributes # get attributes
attributes = attribute.split('.') attributes = attribute.split('.')
@ -699,7 +699,7 @@ condition example
if selector['operator'] == 'is' if selector['operator'] == 'is'
if selector['pre_condition'] == 'not_set' if selector['pre_condition'] == 'not_set'
if attributes[1].match?(/^(created_by|updated_by|owner|customer|user)_id/) if attributes[1].match?(%r{^(created_by|updated_by|owner|customer|user)_id})
query += "(#{attribute} IS NULL OR #{attribute} IN (?))" query += "(#{attribute} IS NULL OR #{attribute} IN (?))"
bind_params.push 1 bind_params.push 1
else else
@ -744,7 +744,7 @@ condition example
end end
elsif selector['operator'] == 'is not' elsif selector['operator'] == 'is not'
if selector['pre_condition'] == 'not_set' if selector['pre_condition'] == 'not_set'
if attributes[1].match?(/^(created_by|updated_by|owner|customer|user)_id/) if attributes[1].match?(%r{^(created_by|updated_by|owner|customer|user)_id})
query += "(#{attribute} IS NOT NULL AND #{attribute} NOT IN (?))" query += "(#{attribute} IS NOT NULL AND #{attribute} NOT IN (?))"
bind_params.push 1 bind_params.push 1
else else
@ -1444,7 +1444,7 @@ result
def check_title def check_title
return true if !title return true if !title
title.gsub!(/\s|\t|\r/, ' ') title.gsub!(%r{\s|\t|\r}, ' ')
true true
end end
@ -1476,7 +1476,7 @@ result
current_state_type = Ticket::StateType.lookup(id: current_state.state_type_id) current_state_type = Ticket::StateType.lookup(id: current_state.state_type_id)
# in case, set pending_time to nil # in case, set pending_time to nil
return true if current_state_type.name.match?(/^pending/i) return true if current_state_type.name.match?(%r{^pending}i)
self.pending_time = nil self.pending_time = nil
true true
@ -1561,7 +1561,7 @@ result
User.group_access(group_id, 'full').sort_by(&:login).each do |user| User.group_access(group_id, 'full').sort_by(&:login).each do |user|
recipients_raw.push(user.email) recipients_raw.push(user.email)
end end
when /\Auserid_(\d+)\z/ when %r{\Auserid_(\d+)\z}
user = User.lookup(id: $1) user = User.lookup(id: $1)
if !user if !user
logger.warn "Can't find configured Trigger Email recipient User with ID '#{$1}'" logger.warn "Can't find configured Trigger Email recipient User with ID '#{$1}'"
@ -1592,7 +1592,7 @@ result
end end
rescue rescue
if recipient_email.present? if recipient_email.present?
if recipient_email !~ /^(.+?)<(.+?)@(.+?)>$/ if recipient_email !~ %r{^(.+?)<(.+?)@(.+?)>$}
next # no usable format found next # no usable format found
end end
@ -1609,15 +1609,15 @@ result
# do not sent notifications to this recipients # do not sent notifications to this recipients
send_no_auto_response_reg_exp = Setting.get('send_no_auto_response_reg_exp') send_no_auto_response_reg_exp = Setting.get('send_no_auto_response_reg_exp')
begin begin
next if recipient_email.match?(/#{send_no_auto_response_reg_exp}/i) next if recipient_email.match?(%r{#{send_no_auto_response_reg_exp}}i)
rescue => e rescue => e
logger.error "Invalid regex '#{send_no_auto_response_reg_exp}' in setting send_no_auto_response_reg_exp" logger.error "Invalid regex '#{send_no_auto_response_reg_exp}' in setting send_no_auto_response_reg_exp"
logger.error e logger.error e
next if recipient_email.match?(/(mailer-daemon|postmaster|abuse|root|noreply|noreply.+?|no-reply|no-reply.+?)@.+?/i) next if recipient_email.match?(%r{(mailer-daemon|postmaster|abuse|root|noreply|noreply.+?|no-reply|no-reply.+?)@.+?}i)
end end
# check if notification should be send because of customer emails # check if notification should be send because of customer emails
if article.present? && article.preferences.fetch('is-auto-response', false) == true && article.from && article.from =~ /#{Regexp.quote(recipient_email)}/i if article.present? && article.preferences.fetch('is-auto-response', false) == true && article.from && article.from =~ %r{#{Regexp.quote(recipient_email)}}i
logger.info "Send no trigger based notification to #{recipient_email} because of auto response tagged incoming email" logger.info "Send no trigger based notification to #{recipient_email} because of auto response tagged incoming email"
next next
end end
@ -1812,7 +1812,7 @@ result
owner_id owner_id
when 'ticket_agents' when 'ticket_agents'
User.group_access(group_id, 'full').sort_by(&:login) User.group_access(group_id, 'full').sort_by(&:login)
when /\Auserid_(\d+)\z/ when %r{\Auserid_(\d+)\z}
return $1 if User.exists?($1) return $1 if User.exists?($1)
logger.warn "Can't find configured Trigger SMS recipient User with ID '#{$1}'" logger.warn "Can't find configured Trigger SMS recipient User with ID '#{$1}'"

View file

@ -85,10 +85,10 @@ returns
def self.insert_urls(article) def self.insert_urls(article)
return article if article['attachments'].blank? return article if article['attachments'].blank?
return article if !article['content_type'].match?(%r{text/html}i) return article if !article['content_type'].match?(%r{text/html}i)
return article if article['body'] !~ /<img/i return article if article['body'] !~ %r{<img}i
inline_attachments = {} inline_attachments = {}
article['body'].gsub!( /(<img[[:space:]](|.+?)src=")cid:(.+?)"(|.+?)>/im ) do |item| article['body'].gsub!( %r{(<img[[:space:]](|.+?)src=")cid:(.+?)"(|.+?)>}im ) do |item|
tag_start = $1 tag_start = $1
cid = $3 cid = $3
tag_end = $4 tag_end = $4
@ -129,7 +129,7 @@ returns
def attachments_inline def attachments_inline
inline_attachments = {} inline_attachments = {}
body.gsub( /<img[[:space:]](|.+?)src="cid:(.+?)"(|.+?)>/im ) do |_item| body.gsub( %r{<img[[:space:]](|.+?)src="cid:(.+?)"(|.+?)>}im ) do |_item|
cid = $2 cid = $2
# look for attachment # look for attachment
@ -251,7 +251,7 @@ returns:
return true if attribute != :body return true if attribute != :body
return false if content_type.blank? return false if content_type.blank?
content_type =~ /html/i content_type =~ %r{html}i
end end
=begin =begin
@ -306,7 +306,7 @@ returns
def check_subject def check_subject
return true if subject.blank? return true if subject.blank?
subject.gsub!(/\s|\t|\r/, ' ') subject.gsub!(%r{\s|\t|\r}, ' ')
true true
end end

View file

@ -26,7 +26,7 @@ module Ticket::Article::EnqueueCommunicateTelegramJob
return true if !type_id return true if !type_id
type = Ticket::Article::Type.lookup(id: type_id) type = Ticket::Article::Type.lookup(id: type_id)
return true if !type.name.match?(/\Atelegram/i) return true if !type.name.match?(%r{\Atelegram}i)
CommunicateTelegramJob.perform_later(id) CommunicateTelegramJob.perform_later(id)
end end

View file

@ -31,7 +31,7 @@ module Ticket::Article::EnqueueCommunicateTwitterJob
type = Ticket::Article::Type.lookup(id: type_id) type = Ticket::Article::Type.lookup(id: type_id)
return true if type.nil? return true if type.nil?
return true if !type.name.match?(/\Atwitter/i) return true if !type.name.match?(%r{\Atwitter}i)
raise Exceptions::UnprocessableEntity, 'twitter to: parameter is missing' if to.blank? && type['name'] == 'twitter direct-message' raise Exceptions::UnprocessableEntity, 'twitter to: parameter is missing' if to.blank? && type['name'] == 'twitter direct-message'

View file

@ -40,12 +40,12 @@ module Ticket::Number::Date
# probe format # probe format
# NOTE: we use `(?<=\W|^)` at the start of the regular expressions below # NOTE: we use `(?<=\W|^)` at the start of the regular expressions below
# because `\b` fails when ticket_hook begins with a non-word character (like '#') # because `\b` fails when ticket_hook begins with a non-word character (like '#')
string.scan(/(?<=\W|^)#{Regexp.quote(ticket_hook)}#{Regexp.quote(ticket_hook_divider)}(\d{4,10}#{system_id}\d{2,40})\b/i) do string.scan(%r{(?<=\W|^)#{Regexp.quote(ticket_hook)}#{Regexp.quote(ticket_hook_divider)}(\d{4,10}#{system_id}\d{2,40})\b}i) do
ticket = Ticket.find_by(number: $1) ticket = Ticket.find_by(number: $1)
break if ticket break if ticket
end end
if !ticket if !ticket
string.scan(/(?<=\W|^)#{Regexp.quote(ticket_hook)}\s{0,2}(\d{4,10}#{system_id}\d{2,40})\b/i) do string.scan(%r{(?<=\W|^)#{Regexp.quote(ticket_hook)}\s{0,2}(\d{4,10}#{system_id}\d{2,40})\b}i) do
ticket = Ticket.find_by(number: $1) ticket = Ticket.find_by(number: $1)
break if ticket break if ticket
end end

View file

@ -38,13 +38,13 @@ module Ticket::Number::Increment
# probe format # probe format
# NOTE: we use `(?<=\W|^)` at the start of the regular expressions below # NOTE: we use `(?<=\W|^)` at the start of the regular expressions below
# because `\b` fails when ticket_hook begins with a non-word character (like '#') # because `\b` fails when ticket_hook begins with a non-word character (like '#')
string.scan(/(?<=\W|^)#{Regexp.quote(ticket_hook)}#{Regexp.quote(ticket_hook_divider)}(#{system_id}\d{2,48})\b/i) do string.scan(%r{(?<=\W|^)#{Regexp.quote(ticket_hook)}#{Regexp.quote(ticket_hook_divider)}(#{system_id}\d{2,48})\b}i) do
ticket = Ticket.find_by(number: $1) ticket = Ticket.find_by(number: $1)
break if ticket break if ticket
end end
if !ticket if !ticket
string.scan(/(?<=\W|^)#{Regexp.quote(ticket_hook)}\s{0,2}(#{system_id}\d{2,48})\b/i) do string.scan(%r{(?<=\W|^)#{Regexp.quote(ticket_hook)}\s{0,2}(#{system_id}\d{2,48})\b}i) do
ticket = Ticket.find_by(number: $1) ticket = Ticket.find_by(number: $1)
break if ticket break if ticket
end end

View file

@ -103,7 +103,7 @@ returns
order_by = overview.order[:by] order_by = overview.order[:by]
# validate direction # validate direction
raise "Invalid order direction '#{direction}'" if direction && direction !~ /^(ASC|DESC)$/i raise "Invalid order direction '#{direction}'" if direction && direction !~ %r{^(ASC|DESC)$}i
# check if order by exists # check if order by exists
if !ticket_attributes.key?(order_by) if !ticket_attributes.key?(order_by)

View file

@ -98,7 +98,7 @@ module Ticket::SearchIndex
return true if attachment.filename.blank? return true if attachment.filename.blank?
filename_extention = attachment.filename.downcase filename_extention = attachment.filename.downcase
filename_extention.gsub!(/^.*(\..+?)$/, '\\1') filename_extention.gsub!(%r{^.*(\..+?)$}, '\\1')
# list ignored file extensions # list ignored file extensions
attachments_ignore = Setting.get('es_attachment_ignore') || [ '.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe' ] attachments_ignore = Setting.get('es_attachment_ignore') || [ '.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe' ]

View file

@ -57,17 +57,17 @@ returns
ticket_subject_size = Setting.get('ticket_subject_size') ticket_subject_size = Setting.get('ticket_subject_size')
# remove all possible ticket hook formats with [] # remove all possible ticket hook formats with []
subject = subject.gsub(/\[#{ticket_hook}: #{number}\](\s+?|)/, '') subject = subject.gsub(%r{\[#{ticket_hook}: #{number}\](\s+?|)}, '')
subject = subject.gsub(/\[#{ticket_hook}:#{number}\](\s+?|)/, '') subject = subject.gsub(%r{\[#{ticket_hook}:#{number}\](\s+?|)}, '')
subject = subject.gsub(/\[#{ticket_hook}#{ticket_hook_divider}#{number}\](\s+?|)/, '') subject = subject.gsub(%r{\[#{ticket_hook}#{ticket_hook_divider}#{number}\](\s+?|)}, '')
# remove all possible ticket hook formats without [] # remove all possible ticket hook formats without []
subject = subject.gsub(/#{ticket_hook}: #{number}(\s+?|)/, '') subject = subject.gsub(%r{#{ticket_hook}: #{number}(\s+?|)}, '')
subject = subject.gsub(/#{ticket_hook}:#{number}(\s+?|)/, '') subject = subject.gsub(%r{#{ticket_hook}:#{number}(\s+?|)}, '')
subject = subject.gsub(/#{ticket_hook}#{ticket_hook_divider}#{number}(\s+?|)/, '') subject = subject.gsub(%r{#{ticket_hook}#{ticket_hook_divider}#{number}(\s+?|)}, '')
# remove leading "..:\s" and "..[\d+]:\s" e. g. "Re: " or "Re[5]: " # remove leading "..:\s" and "..[\d+]:\s" e. g. "Re: " or "Re[5]: "
subject = subject.gsub(/^(..(\[\d+\])?:\s)+/, '') subject = subject.gsub(%r{^(..(\[\d+\])?:\s)+}, '')
# resize subject based on config # resize subject based on config
if subject.length > ticket_subject_size.to_i if subject.length > ticket_subject_size.to_i

View file

@ -106,7 +106,7 @@ class Transaction::Slack
if ticket.pending_time && ticket.pending_time < Time.zone.now if ticket.pending_time && ticket.pending_time < Time.zone.now
color = '#faab00' color = '#faab00'
end end
elsif ticket_state_type.match?(/^(new|open)$/) elsif ticket_state_type.match?(%r{^(new|open)$})
color = '#faab00' color = '#faab00'
elsif ticket_state_type == 'closed' elsif ticket_state_type == 'closed'
color = '#38ad69' color = '#38ad69'

View file

@ -416,7 +416,7 @@ Get source file at https://i18n.zammad.com/api/v1/translations_empty_translation
next next
end end
raise "Can't import translation, format is missing" if row[2].blank? raise "Can't import translation, format is missing" if row[2].blank?
raise "Can't import translation, format is invalid (#{row[2]})" if !row[2].match?(/^(time|string)$/) raise "Can't import translation, format is invalid (#{row[2]})" if !row[2].match?(%r{^(time|string)$})
item = { item = {
'locale' => locale.locale, 'locale' => locale.locale,

View file

@ -841,7 +841,7 @@ try to find correct name
end end
# "Firstname Lastname" # "Firstname Lastname"
if string =~ /^(((Dr\.|Prof\.)[[:space:]]|).+?)[[:space:]](.+?)$/i if string =~ %r{^(((Dr\.|Prof\.)[[:space:]]|).+?)[[:space:]](.+?)$}i
if $1.present? if $1.present?
firstname = $1.strip firstname = $1.strip
end end
@ -853,7 +853,7 @@ try to find correct name
# -no name- "firstname.lastname@example.com" # -no name- "firstname.lastname@example.com"
if string.blank? && email.present? if string.blank? && email.present?
scan = email.scan(/^(.+?)\.(.+?)@.+?$/) scan = email.scan(%r{^(.+?)\.(.+?)@.+?$})
if scan[0].present? if scan[0].present?
if scan[0][0].present? if scan[0][0].present?
firstname = scan[0][0].strip firstname = scan[0][0].strip
@ -900,10 +900,10 @@ try to find correct name
self.firstname = local_firstname if local_firstname.present? self.firstname = local_firstname if local_firstname.present?
self.lastname = local_lastname if local_lastname.present? self.lastname = local_lastname if local_lastname.present?
if firstname.present? && firstname.match(/^[A-z]+$/) && (firstname.downcase == firstname || firstname.upcase == firstname) if firstname.present? && firstname.match(%r{^[A-z]+$}) && (firstname.downcase == firstname || firstname.upcase == firstname)
firstname.capitalize! firstname.capitalize!
end end
if lastname.present? && lastname.match(/^[A-z]+$/) && (lastname.downcase == lastname || lastname.upcase == lastname) if lastname.present? && lastname.match(%r{^[A-z]+$}) && (lastname.downcase == lastname || lastname.upcase == lastname)
lastname.capitalize! lastname.capitalize!
end end
true true

View file

@ -19,7 +19,7 @@ ActiveSupport::Inflector.inflections(:en) do |inflect|
# Rails thinks the singularized version of knowledge_bases is knowledge_basis?! # Rails thinks the singularized version of knowledge_bases is knowledge_basis?!
# see: KnowledgeBase.table_name.singularize # see: KnowledgeBase.table_name.singularize
inflect.singular(/(knowledge_base)s$/i, '\1') inflect.singular(%r{(knowledge_base)s$}i, '\1')
inflect.acronym 'SMIME' inflect.acronym 'SMIME'
inflect.acronym 'GitLab' inflect.acronym 'GitLab'
inflect.acronym 'GitHub' inflect.acronym 'GitHub'

View file

@ -2,7 +2,7 @@ Zammad::Application.routes.draw do
api_path = Rails.configuration.api_path api_path = Rails.configuration.api_path
match api_path + '/http_logs', to: 'http_logs#index', via: :get match api_path + '/http_logs', to: 'http_logs#index', via: :get
match api_path + '/http_logs/:facility', to: 'http_logs#index', via: :get, constraints: { facility: /.*/ } match api_path + '/http_logs/:facility', to: 'http_logs#index', via: :get, constraints: { facility: %r{.*} }
match api_path + '/http_logs', to: 'http_logs#create', via: :post match api_path + '/http_logs', to: 'http_logs#create', via: :post
end end

View file

@ -9,7 +9,7 @@ class CalendarSubscriptions
default_preferences = Setting.where(area: 'Defaults::CalendarSubscriptions') default_preferences = Setting.where(area: 'Defaults::CalendarSubscriptions')
default_preferences.each do |calendar_subscription| default_preferences.each do |calendar_subscription|
next if calendar_subscription.name !~ /\Adefaults_calendar_subscriptions_(.*)\z/ next if calendar_subscription.name !~ %r{\Adefaults_calendar_subscriptions_(.*)\z}
object_name = $1 # rubocop:disable Lint/OutOfRangeRegexpRef object_name = $1 # rubocop:disable Lint/OutOfRangeRegexpRef
@preferences[ object_name ] = calendar_subscription.state_current[:value] @preferences[ object_name ] = calendar_subscription.state_current[:value]

View file

@ -1,8 +1,8 @@
class ColorValidator < ActiveModel::EachValidator class ColorValidator < ActiveModel::EachValidator
REGEXP = { REGEXP = {
RGB: /^rgb\((((((((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5]),\s?)){2}|((((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5])\s)){2})((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5]))|((((([1-9]?\d(\.\d+)?)|100|(\.\d+))%,\s?){2}|((([1-9]?\d(\.\d+)?)|100|(\.\d+))%\s){2})(([1-9]?\d(\.\d+)?)|100|(\.\d+))%))\)$/i, RGB: %r{^rgb\((((((((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5]),\s?)){2}|((((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5])\s)){2})((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5]))|((((([1-9]?\d(\.\d+)?)|100|(\.\d+))%,\s?){2}|((([1-9]?\d(\.\d+)?)|100|(\.\d+))%\s){2})(([1-9]?\d(\.\d+)?)|100|(\.\d+))%))\)$}i,
HSL: /^hsl\(((((([12]?[1-9]?\d)|[12]0\d|(3[0-6]\d))(\.\d+)?)|(\.\d+))(deg)?|(0|0?\.\d+)turn|(([0-6](\.\d+)?)|(\.\d+))rad)((,\s?(([1-9]?\d(\.\d+)?)|100|(\.\d+))%){2}|(\s(([1-9]?\d(\.\d+)?)|100|(\.\d+))%){2})\)$/i, HSL: %r{^hsl\(((((([12]?[1-9]?\d)|[12]0\d|(3[0-6]\d))(\.\d+)?)|(\.\d+))(deg)?|(0|0?\.\d+)turn|(([0-6](\.\d+)?)|(\.\d+))rad)((,\s?(([1-9]?\d(\.\d+)?)|100|(\.\d+))%){2}|(\s(([1-9]?\d(\.\d+)?)|100|(\.\d+))%){2})\)$}i,
HEX: /^#([\da-f]{3}){1,2}$/i HEX: %r{^#([\da-f]{3}){1,2}$}i
}.freeze }.freeze
def validate_each(record, attribute, value) def validate_each(record, attribute, value)

View file

@ -13,7 +13,7 @@ module ActiveRecord
if column_names.instance_of?(Array) if column_names.instance_of?(Array)
index_columns_new = [] index_columns_new = []
column_names.each do |i| column_names.each do |i|
if i =~ /^"(name|login|locale|alias)"$/ || i.end_with?('name"') if i =~ %r{^"(name|login|locale|alias)"$} || i.end_with?('name"')
index_columns_new.push "LOWER(#{i})" index_columns_new.push "LOWER(#{i})"
else else
index_columns_new.push i index_columns_new.push i

View file

@ -1,15 +1,15 @@
class Class class Class
def to_app_model_url def to_app_model_url
@to_app_model_url ||= begin @to_app_model_url ||= begin
to_s.gsub(/::/, '_') to_s.gsub(%r{::}, '_')
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') .gsub(%r{([A-Z]+)([A-Z][a-z])}, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2') .gsub(%r{([a-z\d])([A-Z])}, '\1_\2')
.tr('-', '_') .tr('-', '_')
.downcase .downcase
end end
end end
def to_app_model def to_app_model
@to_app_model ||= to_s.gsub(/::/, '').to_sym @to_app_model ||= to_s.gsub(%r{::}, '').to_sym
end end
end end

View file

@ -6,8 +6,8 @@ class String
def strip! def strip!
begin begin
sub!(/\A[[[:space:]]\u{200B}\u{FEFF}]+/, '') sub!(%r{\A[[[:space:]]\u{200B}\u{FEFF}]+}, '')
sub!(/[[[:space:]]\u{200B}\u{FEFF}]+\Z/, '') sub!(%r{[[[:space:]]\u{200B}\u{FEFF}]+\Z}, '')
# if incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError), use default # if incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError), use default
rescue Encoding::CompatibilityError rescue Encoding::CompatibilityError
@ -18,8 +18,8 @@ class String
def strip def strip
begin begin
new_string = sub(/\A[[[:space:]]\u{200B}\u{FEFF}]+/, '') new_string = sub(%r{\A[[[:space:]]\u{200B}\u{FEFF}]+}, '')
new_string.sub!(/[[[:space:]]\u{200B}\u{FEFF}]+\Z/, '') new_string.sub!(%r{[[[:space:]]\u{200B}\u{FEFF}]+\Z}, '')
# if incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError), use default # if incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string) (Encoding::CompatibilityError), use default
rescue Encoding::CompatibilityError rescue Encoding::CompatibilityError
@ -46,7 +46,7 @@ class String
lines = self lines = self
lines.split("\n").collect do |line| lines.split("\n").collect do |line|
line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line line.length > options[:line_width] ? line.gsub(%r{(.{1,#{options[:line_width]}})(\s+|$)}, "\\1\n").strip : line
end * "\n" end * "\n"
end end
@ -61,9 +61,9 @@ class String
def to_filename def to_filename
camel_cased_word = dup camel_cased_word = dup
camel_cased_word.gsub(/::/, '/') camel_cased_word.gsub(%r{::}, '/')
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') .gsub(%r{([A-Z]+)([A-Z][a-z])}, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2') .gsub(%r{([a-z\d])([A-Z])}, '\1_\2')
.tr('-', '_').downcase .tr('-', '_').downcase
end end
@ -119,7 +119,7 @@ class String
end end
# remove html comments # remove html comments
string.gsub!(/<!--.+?-->/m, '') string.gsub!(%r{<!--.+?-->}m, '')
# find <a href=....> and replace it with [x] # find <a href=....> and replace it with [x]
link_list = '' link_list = ''
@ -128,7 +128,7 @@ class String
string.gsub!(%r{<a[[:space:]]+(|\S+[[:space:]]+)href=("|')(.+?)("|')([[:space:]]*|[[:space:]]+[^>]*)>(.+?)<[[:space:]]*/a[[:space:]]*>}mxi) do |_placeholder| string.gsub!(%r{<a[[:space:]]+(|\S+[[:space:]]+)href=("|')(.+?)("|')([[:space:]]*|[[:space:]]+[^>]*)>(.+?)<[[:space:]]*/a[[:space:]]*>}mxi) do |_placeholder|
link = $3 link = $3
text = $6 text = $6
text.gsub!(/<.+?>/, '') text.gsub!(%r{<.+?>}, '')
link_compare = link.dup link_compare = link.dup
if link_compare.present? if link_compare.present?
@ -147,18 +147,18 @@ class String
if link_compare.present? && text_compare.blank? if link_compare.present? && text_compare.blank?
link link
elsif (link_compare.blank? && text_compare.present?) || (link_compare && link_compare =~ /^mailto/i) elsif (link_compare.blank? && text_compare.present?) || (link_compare && link_compare =~ %r{^mailto}i)
text text
elsif link_compare.present? && text_compare.present? && (link_compare == text_compare || link_compare == "mailto:#{text}".downcase || link_compare == "http://#{text}".downcase) elsif link_compare.present? && text_compare.present? && (link_compare == text_compare || link_compare == "mailto:#{text}".downcase || link_compare == "http://#{text}".downcase)
"######LINKEXT:#{link}/TEXT:#{text}######" "######LINKEXT:#{link}/TEXT:#{text}######"
elsif text !~ /^http/ elsif text !~ %r{^http}
"#{text} (######LINKRAW:#{link}######)" "#{text} (######LINKRAW:#{link}######)"
else else
"#{link} (######LINKRAW:#{text}######)" "#{link} (######LINKRAW:#{text}######)"
end end
end end
elsif string.scan(/<a[[:space:]]/i).count < 5_000 elsif string.scan(%r{<a[[:space:]]}i).count < 5_000
string.gsub!(/<a[[:space:]].*?href=("|')(.+?)("|').*?>/ix) do string.gsub!(%r{<a[[:space:]].*?href=("|')(.+?)("|').*?>}ix) do
link = $2 link = $2
counter = counter + 1 counter = counter + 1
link_list += "[#{counter}] #{link}\n" link_list += "[#{counter}] #{link}\n"
@ -170,35 +170,35 @@ class String
string.gsub!(%r{<style(|[[:space:]].+?)>(.+?)</style>}im, '') string.gsub!(%r{<style(|[[:space:]].+?)>(.+?)</style>}im, '')
# remove empty lines # remove empty lines
string.gsub!(/^[[:space:]]*/m, '') string.gsub!(%r{^[[:space:]]*}m, '')
if strict if strict
string.gsub!(%r{< [[:space:]]* (/*) [[:space:]]* (b|i|ul|ol|li|u|h1|h2|h3|hr) ([[:space:]]*|[[:space:]]+[^>]*) >}mxi, '######\1\2######') string.gsub!(%r{< [[:space:]]* (/*) [[:space:]]* (b|i|ul|ol|li|u|h1|h2|h3|hr) ([[:space:]]*|[[:space:]]+[^>]*) >}mxi, '######\1\2######')
end end
# pre/code handling 1/2 # pre/code handling 1/2
string.gsub!(%r{<pre>(.+?)</pre>}m) do |placeholder| string.gsub!(%r{<pre>(.+?)</pre>}m) do |placeholder|
placeholder.gsub(/\n/, '###BR###') placeholder.gsub(%r{\n}, '###BR###')
end end
string.gsub!(%r{<code>(.+?)</code>}m) do |placeholder| string.gsub!(%r{<code>(.+?)</code>}m) do |placeholder|
placeholder.gsub(/\n/, '###BR###') placeholder.gsub(%r{\n}, '###BR###')
end end
# insert spaces on [A-z]\n[A-z] # insert spaces on [A-z]\n[A-z]
string.gsub!(/([A-z])[[:space:]]([A-z])/m, '\1 \2') string.gsub!(%r{([A-z])[[:space:]]([A-z])}m, '\1 \2')
# remove all new lines # remove all new lines
string.gsub!(/(\n\r|\r\r\n|\r\n|\n)/, '') string.gsub!(%r{(\n\r|\r\r\n|\r\n|\n)}, '')
# blockquote handling # blockquote handling
string.gsub!(%r{<blockquote(| [^>]*)>(.+?)</blockquote>}m) do string.gsub!(%r{<blockquote(| [^>]*)>(.+?)</blockquote>}m) do
"\n#{$2.html2text(true).gsub(/^(.*)$/, '&gt; \1')}\n" "\n#{$2.html2text(true).gsub(%r{^(.*)$}, '&gt; \1')}\n"
end end
# pre/code handling 2/2 # pre/code handling 2/2
string.gsub!(/###BR###/, "\n") string.gsub!(%r{###BR###}, "\n")
# add counting # add counting
string.gsub!(/<li(| [^>]*)>/i, "\n* ") string.gsub!(%r{<li(| [^>]*)>}i, "\n* ")
# add hr # add hr
string.gsub!(%r{<hr(|/| [^>]*)>}i, "\n___\n") string.gsub!(%r{<hr(|/| [^>]*)>}i, "\n___\n")
@ -214,10 +214,10 @@ class String
string.gsub!(%r{</td>}i, ' ') string.gsub!(%r{</td>}i, ' ')
# strip all other tags # strip all other tags
string.gsub!(/<.+?>/, '') string.gsub!(%r{<.+?>}, '')
# replace multiple spaces with one # replace multiple spaces with one
string.gsub!(/ /, ' ') string.gsub!(%r{ }, ' ')
# add hyperlinks # add hyperlinks
if strict if strict
@ -225,11 +225,11 @@ class String
pre = $1 pre = $1
content = $2 content = $2
post = $5 post = $5
if content.match?(/^www/i) if content.match?(%r{^www}i)
content = "http://#{content}" content = "http://#{content}"
end end
if content =~ /^(http|https|ftp|tel)/i if content =~ %r{^(http|https|ftp|tel)}i
"#{pre}######LINKRAW:#{content}#######{post}" "#{pre}######LINKRAW:#{content}#######{post}"
else else
"#{pre}#{content}#{post}" "#{pre}#{content}#{post}"
@ -250,12 +250,12 @@ class String
string.gsub!('&nbsp;', ' ') string.gsub!('&nbsp;', ' ')
# encode html entities like "&#8211;" # encode html entities like "&#8211;"
string.gsub!(/(&\#(\d+);?)/x) do string.gsub!(%r{(&\#(\d+);?)}x) do
$2.chr $2.chr
end end
# encode html entities like "&#3d;" # encode html entities like "&#3d;"
string.gsub!(/(&\#[xX]([0-9a-fA-F]+);?)/x) do string.gsub!(%r{(&\#[xX]([0-9a-fA-F]+);?)}x) do
chr_orig = $1 chr_orig = $1
hex = $2.hex hex = $2.hex
if hex if hex
@ -283,10 +283,10 @@ class String
string = string.utf8_encode(fallback: :read_as_sanitized_binary) string = string.utf8_encode(fallback: :read_as_sanitized_binary)
# remove tailing empty spaces # remove tailing empty spaces
string.gsub!(/[[:blank:]]+$/, '') string.gsub!(%r{[[:blank:]]+$}, '')
# remove double multiple empty lines # remove double multiple empty lines
string.gsub!(/\n\n\n+/, "\n\n") string.gsub!(%r{\n\n\n+}, "\n\n")
# add extracted links # add extracted links
if link_list != '' if link_list != ''
@ -294,7 +294,7 @@ class String
end end
# remove double multiple empty lines # remove double multiple empty lines
string.gsub!(/\n\n\n+/, "\n\n") string.gsub!(%r{\n\n\n+}, "\n\n")
string.strip string.strip
end end
@ -307,7 +307,7 @@ class String
def text2html def text2html
text = CGI.escapeHTML(self) text = CGI.escapeHTML(self)
text.gsub!(/\n/, '<br>') text.gsub!(%r{\n}, '<br>')
text.chomp text.chomp
end end
@ -327,8 +327,8 @@ class String
string = html2text.text2html string = html2text.text2html
string.signature_identify('text') string.signature_identify('text')
marker_template = '<span class="js-signatureMarker"></span>' marker_template = '<span class="js-signatureMarker"></span>'
string.sub!(/######SIGNATURE_MARKER######/, marker_template) string.sub!(%r{######SIGNATURE_MARKER######}, marker_template)
string.gsub!(/######SIGNATURE_MARKER######/, '') string.gsub!(%r{######SIGNATURE_MARKER######}, '')
return string.chomp return string.chomp
end end
string.gsub!(%r{(<p>[[:space:]]*</p>([[:space:]]*)){2,}}im, '<p>&nbsp;</p>\2') string.gsub!(%r{(<p>[[:space:]]*</p>([[:space:]]*)){2,}}im, '<p>&nbsp;</p>\2')
@ -340,7 +340,7 @@ class String
string.gsub!(%r{<p>[[:space:]]*</p>(<br(|/)>[[:space:]]*)+<p>[[:space:]]*</p>}im, '<p> </p><p> </p>') string.gsub!(%r{<p>[[:space:]]*</p>(<br(|/)>[[:space:]]*)+<p>[[:space:]]*</p>}im, '<p> </p><p> </p>')
string.gsub!(%r\(<div>[[:space:]]*</div>[[:space:]]*){2,}\im, '<div> </div>') string.gsub!(%r\(<div>[[:space:]]*</div>[[:space:]]*){2,}\im, '<div> </div>')
string.gsub!(%r{<div>&nbsp;</div>[[:space:]]*(<div>&nbsp;</div>){1,}}im, '<div>&nbsp;</div>') string.gsub!(%r{<div>&nbsp;</div>[[:space:]]*(<div>&nbsp;</div>){1,}}im, '<div>&nbsp;</div>')
string.gsub!(/(<br>[[:space:]]*){3,}/im, '<br><br>') string.gsub!(%r{(<br>[[:space:]]*){3,}}im, '<br><br>')
string.gsub!(%r\(<br(|/)>[[:space:]]*){3,}\im, '<br/><br/>') string.gsub!(%r\(<br(|/)>[[:space:]]*){3,}\im, '<br/><br/>')
string.gsub!(%r{<p>[[:space:]]+</p>}im, '<p>&nbsp;</p>') string.gsub!(%r{<p>[[:space:]]+</p>}im, '<p>&nbsp;</p>')
string.gsub!(%r{\A(<br(|/)>[[:space:]]*)*}i, '') string.gsub!(%r{\A(<br(|/)>[[:space:]]*)*}i, '')
@ -350,8 +350,8 @@ class String
string.signature_identify('html') string.signature_identify('html')
marker_template = '<span class="js-signatureMarker"></span>' marker_template = '<span class="js-signatureMarker"></span>'
string.sub!(/######SIGNATURE_MARKER######/, marker_template) string.sub!(%r{######SIGNATURE_MARKER######}, marker_template)
string.gsub!(/######SIGNATURE_MARKER######/, '') string.gsub!(%r{######SIGNATURE_MARKER######}, '')
string.chomp string.chomp
end end
@ -371,7 +371,7 @@ class String
'<div(|.+?)>[[:space:]]*<br>[[:space:]]*(On|Am|Le|El|Den|Dňa|W dniu|Il|Op|Dne|Dana)[[:space:]].{1,500}<blockquote', '<div(|.+?)>[[:space:]]*<br>[[:space:]]*(On|Am|Le|El|Den|Dňa|W dniu|Il|Op|Dne|Dana)[[:space:]].{1,500}<blockquote',
] ]
map.each do |regexp| map.each do |regexp|
string.sub!(/#{regexp}/m) do |placeholder| string.sub!(%r{#{regexp}}m) do |placeholder|
"#{marker}#{placeholder}" "#{marker}#{placeholder}"
end end
end end
@ -385,7 +385,7 @@ class String
end end
# search for signature separator "--\n" # search for signature separator "--\n"
string.sub!(/^\s{0,2}--\s{0,2}$/) do |placeholder| string.sub!(%r{^\s{0,2}--\s{0,2}$}) do |placeholder|
"#{marker}#{placeholder}" "#{marker}#{placeholder}"
end end
@ -442,7 +442,7 @@ class String
#map['word-en-de'] = "[^#{marker}].{1,250}\s(wrote|schrieb):" #map['word-en-de'] = "[^#{marker}].{1,250}\s(wrote|schrieb):"
map.each_value do |regexp| map.each_value do |regexp|
string.sub!(/#{regexp}/) do |placeholder| string.sub!(%r{#{regexp}}) do |placeholder|
"#{marker}#{placeholder}" "#{marker}#{placeholder}"
rescue rescue
# regexp was not possible because of some string encoding issue, use next # regexp was not possible because of some string encoding issue, use next

View file

@ -60,7 +60,7 @@ returns
def self.parse_email(email) def self.parse_email(email)
user = nil user = nil
domain = nil domain = nil
if email =~ /^(.+?)@(.+?)$/ if email =~ %r{^(.+?)@(.+?)$}
user = $1 user = $1
domain = $2 domain = $2
end end

View file

@ -71,7 +71,7 @@ returns on fail
provider_map.each_value do |settings| provider_map.each_value do |settings|
domains.each do |domain_to_check| domains.each do |domain_to_check|
next if !domain_to_check.match?(/#{settings[:domain]}/i) next if !domain_to_check.match?(%r{#{settings[:domain]}}i)
# add folder to config if needed # add folder to config if needed
if params[:folder].present? && settings[:inbound] && settings[:inbound][:options] if params[:folder].present? && settings[:inbound] && settings[:inbound][:options]
@ -347,7 +347,7 @@ returns on fail
} }
white_map.each_key do |key| white_map.each_key do |key|
next if !e.message.match?(/#{Regexp.escape(key)}/i) next if !e.message.match?(%r{#{Regexp.escape(key)}}i)
return { return {
result: 'ok', result: 'ok',
@ -372,7 +372,7 @@ returns on fail
def self.invalid_field(message_backend) def self.invalid_field(message_backend)
invalid_fields.each do |key, fields| invalid_fields.each do |key, fields|
return fields if message_backend.match?(/#{Regexp.escape(key)}/i) return fields if message_backend.match?(%r{#{Regexp.escape(key)}}i)
end end
{} {}
end end
@ -397,7 +397,7 @@ returns on fail
def self.translation(message_backend) def self.translation(message_backend)
translations.each do |key, message_human| translations.each do |key, message_human|
return message_human if message_backend.match?(/#{Regexp.escape(key)}/i) return message_human if message_backend.match?(%r{#{Regexp.escape(key)}}i)
end end
nil nil
end end

View file

@ -62,7 +62,7 @@ satinize html string based on whiltelist
# prepare src attribute # prepare src attribute
if node['src'] if node['src']
src = cleanup_target(CGI.unescape(node['src'])) src = cleanup_target(CGI.unescape(node['src']))
if src =~ /(javascript|livescript|vbscript):/i || src.downcase.start_with?('http', 'ftp', '//') if src =~ %r{(javascript|livescript|vbscript):}i || src.downcase.start_with?('http', 'ftp', '//')
node.remove node.remove
Loofah::Scrubber::STOP Loofah::Scrubber::STOP
end end
@ -70,7 +70,7 @@ satinize html string based on whiltelist
# clean class / only use allowed classes # clean class / only use allowed classes
if node['class'] if node['class']
classes = node['class'].gsub(/\t|\n|\r/, '').split classes = node['class'].gsub(%r{\t|\n|\r}, '').split
class_new = '' class_new = ''
classes.each do |local_class| classes.each do |local_class|
next if classes_whitelist.exclude?(local_class.to_s.strip) next if classes_whitelist.exclude?(local_class.to_s.strip)
@ -100,13 +100,13 @@ satinize html string based on whiltelist
node.delete(key) node.delete(key)
next if value.blank? next if value.blank?
value += 'px' if !value.match?(/%|px|em/i) value += 'px' if !value.match?(%r{%|px|em}i)
node['style'] += "#{key}:#{value}" node['style'] += "#{key}:#{value}"
end end
# clean style / only use allowed style properties # clean style / only use allowed style properties
if node['style'] if node['style']
pears = node['style'].downcase.gsub(/\t|\n|\r/, '').split(';') pears = node['style'].downcase.gsub(%r{\t|\n|\r}, '').split(';')
style = '' style = ''
pears.each do |local_pear| pears.each do |local_pear|
prop = local_pear.split(':') prop = local_pear.split(':')
@ -115,7 +115,7 @@ satinize html string based on whiltelist
key = prop[0].strip key = prop[0].strip
next if css_properties_whitelist.exclude?(node.name) next if css_properties_whitelist.exclude?(node.name)
next if css_properties_whitelist[node.name].exclude?(key) next if css_properties_whitelist[node.name].exclude?(key)
next if css_values_blacklist[node.name]&.include?(local_pear.gsub(/[[:space:]]/, '').strip) next if css_values_blacklist[node.name]&.include?(local_pear.gsub(%r{[[:space:]]}, '').strip)
style += "#{local_pear};" style += "#{local_pear};"
end end
@ -130,7 +130,7 @@ satinize html string based on whiltelist
next if !node[attribute_name] next if !node[attribute_name]
href = cleanup_target(node[attribute_name]) href = cleanup_target(node[attribute_name])
next if !href.match?(/(javascript|livescript|vbscript):/i) next if !href.match?(%r{(javascript|livescript|vbscript):}i)
node.delete(attribute_name) node.delete(attribute_name)
end end
@ -159,8 +159,8 @@ satinize html string based on whiltelist
# wrap plain-text URLs in <a> tags # wrap plain-text URLs in <a> tags
if node.is_a?(Nokogiri::XML::Text) && node.content.present? && node.content.include?(':') && node.ancestors.map(&:name).exclude?('a') if node.is_a?(Nokogiri::XML::Text) && node.content.present? && node.content.include?(':') && node.ancestors.map(&:name).exclude?('a')
urls = URI.extract(node.content, LINKABLE_URL_SCHEMES) urls = URI.extract(node.content, LINKABLE_URL_SCHEMES)
.map { |u| u.sub(/[,.]$/, '') } # URI::extract captures trailing dots/commas .map { |u| u.sub(%r{[,.]$}, '') } # URI::extract captures trailing dots/commas
.reject { |u| u.match?(/^[^:]+:$/) } # URI::extract will match, e.g., 'tel:' .reject { |u| u.match?(%r{^[^:]+:$}) } # URI::extract will match, e.g., 'tel:'
next if urls.blank? next if urls.blank?
@ -170,14 +170,14 @@ satinize html string based on whiltelist
# prepare links # prepare links
if node['href'] if node['href']
href = cleanup_target(node['href'], keep_spaces: true) href = cleanup_target(node['href'], keep_spaces: true)
href_without_spaces = href.gsub(/[[:space:]]/, '') href_without_spaces = href.gsub(%r{[[:space:]]}, '')
if external && href_without_spaces.present? && !href_without_spaces.downcase.start_with?('mailto:') && !href_without_spaces.downcase.start_with?('//') && href_without_spaces.downcase !~ %r{^.{1,6}://.+?} if external && href_without_spaces.present? && !href_without_spaces.downcase.start_with?('mailto:') && !href_without_spaces.downcase.start_with?('//') && href_without_spaces.downcase !~ %r{^.{1,6}://.+?}
node['href'] = "http://#{node['href']}" node['href'] = "http://#{node['href']}"
href = node['href'] href = node['href']
href_without_spaces = href.gsub(/[[:space:]]/, '') href_without_spaces = href.gsub(%r{[[:space:]]}, '')
end end
next if !CGI.unescape(href_without_spaces).utf8_encode(fallback: :read_as_sanitized_binary).gsub(/[[:space:]]/, '').downcase.start_with?('http', 'ftp', '//') next if !CGI.unescape(href_without_spaces).utf8_encode(fallback: :read_as_sanitized_binary).gsub(%r{[[:space:]]}, '').downcase.start_with?('http', 'ftp', '//')
node.set_attribute('href', href) node.set_attribute('href', href)
node.set_attribute('rel', 'nofollow noreferrer noopener') node.set_attribute('rel', 'nofollow noreferrer noopener')
@ -219,15 +219,15 @@ cleanup html string:
def self.cleanup(string, timeout: true) def self.cleanup(string, timeout: true)
Timeout.timeout(timeout ? PROCESSING_TIMEOUT : nil) do Timeout.timeout(timeout ? PROCESSING_TIMEOUT : nil) do
string.gsub!(/<[A-z]:[A-z]>/, '') string.gsub!(%r{<[A-z]:[A-z]>}, '')
string.gsub!(%r{</[A-z]:[A-z]>}, '') string.gsub!(%r{</[A-z]:[A-z]>}, '')
string.delete!("\t") string.delete!("\t")
# remove all new lines # remove all new lines
string.gsub!(/(\n\r|\r\r\n|\r\n|\n)/, "\n") string.gsub!(%r{(\n\r|\r\r\n|\r\n|\n)}, "\n")
# remove double multiple empty lines # remove double multiple empty lines
string.gsub!(/\n\n\n+/, "\n\n") string.gsub!(%r{\n\n\n+}, "\n\n")
string = cleanup_structure(string, 'pre') string = cleanup_structure(string, 'pre')
string = cleanup_structure(string) string = cleanup_structure(string)
@ -302,7 +302,7 @@ cleanup html string:
content = node.content content = node.content
if content if content
if content != ' ' && content != "\n" if content != ' ' && content != "\n"
content.gsub!(/[[:space:]]+/, ' ') content.gsub!(%r{[[:space:]]+}, ' ')
end end
if node.previous if node.previous
if node.previous.name == 'div' || node.previous.name == 'p' if node.previous.name == 'div' || node.previous.name == 'p'
@ -329,11 +329,11 @@ cleanup html string:
end end
url = urls.shift url = urls.shift
if content =~ /^(.*)#{Regexp.quote(url)}(.*)$/mx if content =~ %r{^(.*)#{Regexp.quote(url)}(.*)$}mx
pre = $1 pre = $1
post = $2 post = $2
if url.match?(/^www/i) if url.match?(%r{^www}i)
url = "http://#{url}" url = "http://#{url}"
end end
@ -367,11 +367,11 @@ cleanup html string:
def self.cleanup_target(string, **options) def self.cleanup_target(string, **options)
cleaned_string = string.utf8_encode(fallback: :read_as_sanitized_binary) cleaned_string = string.utf8_encode(fallback: :read_as_sanitized_binary)
cleaned_string = cleaned_string.gsub(/[[:space:]]/, '') if !options[:keep_spaces] cleaned_string = cleaned_string.gsub(%r{[[:space:]]}, '') if !options[:keep_spaces]
cleaned_string = cleaned_string.strip cleaned_string = cleaned_string.strip
.delete("\t\n\r\u0000") .delete("\t\n\r\u0000")
.gsub(%r{/\*.*?\*/}, '') .gsub(%r{/\*.*?\*/}, '')
.gsub(/<!--.*?-->/, '') .gsub(%r{<!--.*?-->}, '')
sanitize_attachment_disposition(cleaned_string) sanitize_attachment_disposition(cleaned_string)
end end
@ -392,8 +392,8 @@ cleanup html string:
end end
def self.url_same?(url_new, url_old) def self.url_same?(url_new, url_old)
url_new = CGI.unescape(url_new.to_s).utf8_encode(fallback: :read_as_sanitized_binary).downcase.delete_suffix('/').gsub(/[[:space:]]|\t|\n|\r/, '').strip url_new = CGI.unescape(url_new.to_s).utf8_encode(fallback: :read_as_sanitized_binary).downcase.delete_suffix('/').gsub(%r{[[:space:]]|\t|\n|\r}, '').strip
url_old = CGI.unescape(url_old.to_s).utf8_encode(fallback: :read_as_sanitized_binary).downcase.delete_suffix('/').gsub(/[[:space:]]|\t|\n|\r/, '').strip url_old = CGI.unescape(url_old.to_s).utf8_encode(fallback: :read_as_sanitized_binary).downcase.delete_suffix('/').gsub(%r{[[:space:]]|\t|\n|\r}, '').strip
url_new = html_decode(url_new).sub('/?', '?') url_new = html_decode(url_new).sub('/?', '?')
url_old = html_decode(url_old).sub('/?', '?') url_old = html_decode(url_old).sub('/?', '?')
return true if url_new == url_old return true if url_new == url_old
@ -460,7 +460,7 @@ satinize style of img tags
if node['src'] if node['src']
style = 'max-width:100%;' style = 'max-width:100%;'
if node['style'] if node['style']
pears = node['style'].downcase.gsub(/\t|\n|\r/, '').split(';') pears = node['style'].downcase.gsub(%r{\t|\n|\r}, '').split(';')
pears.each do |local_pear| pears.each do |local_pear|
prop = local_pear.split(':') prop = local_pear.split(':')
next if !prop[0] next if !prop[0]

View file

@ -124,7 +124,7 @@ or with filter:
}, },
) )
raise "Can't fetch objects from #{url}: Unable to parse response from server. Invalid JSON response." if !result.success? && result.error =~ /JSON::ParserError:.+?\s+unexpected\s+token\s+at\s+'<!DOCTYPE\s+html/i raise "Can't fetch objects from #{url}: Unable to parse response from server. Invalid JSON response." if !result.success? && result.error =~ %r{JSON::ParserError:.+?\s+unexpected\s+token\s+at\s+'<!DOCTYPE\s+html}i
raise "Can't fetch objects from #{url}: #{result.error}" if !result.success? raise "Can't fetch objects from #{url}: #{result.error}" if !result.success?
# add link to idoit # add link to idoit

View file

@ -39,7 +39,7 @@ module Import
end end
def module_name def module_name
name.to_s.sub(/Import::/, '').sub(/Factory/, '') name.to_s.sub(%r{Import::}, '').sub(%r{Factory}, '')
end end
end end
end end

View file

@ -60,7 +60,7 @@ module Import
next if value.nil? next if value.nil?
example = value.to_utf8(fallback: :read_as_sanitized_binary) example = value.to_utf8(fallback: :read_as_sanitized_binary)
example.gsub!(/^(.{20,}?).*$/m, '\1...') example.gsub!(%r{^(.{20,}?).*$}m, '\1...')
@examples[attribute] = "#{attribute} (e. g. #{example})" @examples[attribute] = "#{attribute} (e. g. #{example})"
end end

View file

@ -92,7 +92,7 @@ module Import
mapped.delete(:content_type) if mapped[:content_type].blank? mapped.delete(:content_type) if mapped[:content_type].blank?
return mapped if !mapped[:content_type] return mapped if !mapped[:content_type]
mapped[:content_type].sub!(/[;,]\s?.+?$/, '') mapped[:content_type].sub!(%r{[;,]\s?.+?$}, '')
mapped mapped
end end

View file

@ -33,7 +33,7 @@ module Import
def extract_email(from) def extract_email(from)
Mail::Address.new(from).address Mail::Address.new(from).address
rescue rescue
return from if from !~ /<\s*([^>]+)/ return from if from !~ %r{<\s*([^>]+)}
$1.strip $1.strip
end end

View file

@ -14,7 +14,7 @@ module Import
end end
def self.convert_name(dynamic_field_name) def self.convert_name(dynamic_field_name)
dynamic_field_name.underscore.sub(/_id(s)?\z/, '_no\1') dynamic_field_name.underscore.sub(%r{_id(s)?\z}, '_no\1')
end end
private private

View file

@ -7,7 +7,7 @@ module Import
# "%%Queue1%%5%%Postmaster%%1" # "%%Queue1%%5%%Postmaster%%1"
from = nil from = nil
to = nil to = nil
if data =~ /%%(.+?)%%(.+?)%%(.+?)%%(.+?)$/ if data =~ %r{%%(.+?)%%(.+?)%%(.+?)%%(.+?)$}
from = $1 from = $1
from_id = $2 from_id = $2
to = $3 to = $3

View file

@ -7,7 +7,7 @@ module Import
# "%%3 normal%%3%%5 very high%%5" # "%%3 normal%%3%%5 very high%%5"
from = nil from = nil
to = nil to = nil
if data =~ /%%(.+?)%%(.+?)%%(.+?)%%(.+?)$/ if data =~ %r{%%(.+?)%%(.+?)%%(.+?)%%(.+?)$}
from = $1 from = $1
from_id = $2 from_id = $2
to = $3 to = $3

View file

@ -7,7 +7,7 @@ module Import
# "%%new%%open%%" # "%%new%%open%%"
from = nil from = nil
to = nil to = nil
if data =~ /%%(.+?)%%(.+?)%%/ if data =~ %r{%%(.+?)%%(.+?)%%}
from = $1 from = $1
to = $2 to = $2
state_from = ::Ticket::State.lookup(name: from) state_from = ::Ticket::State.lookup(name: from)

View file

@ -161,7 +161,7 @@ module Import
result.push 'Admin' result.push 'Admin'
end end
return result if !group['Name'].match?(/^(stats|report)/) return result if !group['Name'].match?(%r{^(stats|report)})
return result if !( permissions.include?('ro') || permissions.include?('rw') ) return result if !( permissions.include?('ro') || permissions.include?('rw') )
result.push 'Report' result.push 'Report'

View file

@ -189,7 +189,7 @@ class Ldap
end end
def parse_host def parse_host
return if @host !~ /\A([^:]+):(.+?)\z/ return if @host !~ %r{\A([^:]+):(.+?)\z}
@host = $1 @host = $1
@port = $2.to_i @port = $2.to_i

View file

@ -16,7 +16,7 @@ class Ldap
# #
# @return [Boolean] # @return [Boolean]
def self.valid?(string) def self.valid?(string)
string.match?(/\w{8}-\w{4}-\w{4}-\w{4}-\w+/) string.match?(%r{\w{8}-\w{4}-\w{4}-\w{4}-\w+})
end end
# Convers a given GUID string into the HEX equivalent. # Convers a given GUID string into the HEX equivalent.
@ -88,7 +88,7 @@ class Ldap
string.delete!('-') string.delete!('-')
# split every two chars # split every two chars
parts = string.scan(/.{1,2}/) parts = string.scan(%r{.{1,2}})
# re-order according to oracle format index and join # re-order according to oracle format index and join
oracle_format_indices = [3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15] oracle_format_indices = [3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15]

View file

@ -30,7 +30,7 @@ module Mixin
if File.directory?(sub_path) if File.directory?(sub_path)
sub_paths.push(sub_path) sub_paths.push(sub_path)
elsif sub_path =~ /\A(.*)\.rb\z/ elsif sub_path =~ %r{\A(.*)\.rb\z}
require_path = $1 require_path = $1
require_dependency(require_path) require_dependency(require_path)
end end

View file

@ -30,7 +30,7 @@ returns
dir = Rails.root.join('app/models').to_s dir = Rails.root.join('app/models').to_s
tables = ActiveRecord::Base.connection.tables tables = ActiveRecord::Base.connection.tables
Dir.glob("#{dir}/**/*.rb") do |entry| Dir.glob("#{dir}/**/*.rb") do |entry|
next if entry.match?(/application_model/i) next if entry.match?(%r{application_model}i)
next if entry.match?(%r{channel/}i) next if entry.match?(%r{channel/}i)
next if entry.match?(%r{observer/}i) next if entry.match?(%r{observer/}i)
next if entry.match?(%r{store/provider/}i) next if entry.match?(%r{store/provider/}i)

View file

@ -244,8 +244,8 @@ retunes
result.each do |item| result.each do |item|
next if item['type'] != 'notification' next if item['type'] != 'notification'
next if item['object'] != 'Ticket' next if item['object'] != 'Ticket'
next if !item['value_to'].match?(/#{recipient.email}/i) next if !item['value_to'].match?(%r{#{recipient.email}}i)
next if !item['value_to'].match?(/#{type}/i) next if !item['value_to'].match?(%r{#{type}}i)
count += 1 count += 1
end end

View file

@ -106,7 +106,7 @@ examples how to use
end end
arguments = nil arguments = nil
if /\A(?<method_id>[^(]+)\((?<parameter>[^)]+)\)\z/ =~ method if %r{\A(?<method_id>[^(]+)\((?<parameter>[^)]+)\)\z} =~ method
if parameter != parameter.to_i.to_s if parameter != parameter.to_i.to_s
value = "\#{#{object_name}.#{object_methods_s} / invalid parameter: #{parameter}}" value = "\#{#{object_name}.#{object_methods_s} / invalid parameter: #{parameter}}"
@ -185,7 +185,7 @@ examples how to use
end end
def data_key_valid?(key) def data_key_valid?(key)
return false if key =~ /`|\.(|\s*)(save|destroy|delete|remove|drop|update|create|new|all|where|find|raise|dump|rollback|freeze)/i && key !~ /(update|create)d_(at|by)/i return false if key =~ %r{`|\.(|\s*)(save|destroy|delete|remove|drop|update|create|new|all|where|find|raise|dump|rollback|freeze)}i && key !~ %r{(update|create)d_(at|by)}i
true true
end end

View file

@ -17,17 +17,17 @@ examples how to use
end end
def to_s def to_s
@template.gsub(/\#{\s*(.*?)\s*}/m) do @template.gsub(%r{\#{\s*(.*?)\s*}}m) do
# some browsers start adding HTML tags # some browsers start adding HTML tags
# fixes https://github.com/zammad/zammad/issues/385 # fixes https://github.com/zammad/zammad/issues/385
input_template = $1.gsub(/\A<.+?>\s*|\s*<.+?>\z/, '') input_template = $1.gsub(%r{\A<.+?>\s*|\s*<.+?>\z}, '')
case input_template case input_template
when /\At\('(.+?)'\)\z/m when %r{\At\('(.+?)'\)\z}m
%(<%= t "#{sanitize_text($1)}", #{@escape} %>) %(<%= t "#{sanitize_text($1)}", #{@escape} %>)
when /\At\((.+?)\)\z/m when %r{\At\((.+?)\)\z}m
%(<%= t d"#{sanitize_object_name($1)}", #{@escape} %>) %(<%= t d"#{sanitize_object_name($1)}", #{@escape} %>)
when /\Aconfig\.(.+?)\z/m when %r{\Aconfig\.(.+?)\z}m
%(<%= c "#{sanitize_object_name($1)}", #{@escape} %>) %(<%= c "#{sanitize_object_name($1)}", #{@escape} %>)
else else
%(<%= d "#{sanitize_object_name(input_template)}", #{@escape} %>) %(<%= d "#{sanitize_object_name(input_template)}", #{@escape} %>)
@ -37,7 +37,7 @@ examples how to use
def sanitize_text(string) def sanitize_text(string)
string&.tr("\t\r\n", '') string&.tr("\t\r\n", '')
&.gsub(/(?<!\\)(?=")/, '\\') &.gsub(%r{(?<!\\)(?=")}, '\\')
end end
def sanitize_object_name(string) def sanitize_object_name(string)

View file

@ -44,7 +44,7 @@ module PasswordHash
def hashed_argon2i?(pw_hash, password) def hashed_argon2i?(pw_hash, password)
# taken from: https://github.com/technion/ruby-argon2/blob/7e1f4a2634316e370ab84150e4f5fd91d9263713/lib/argon2.rb#L33 # taken from: https://github.com/technion/ruby-argon2/blob/7e1f4a2634316e370ab84150e4f5fd91d9263713/lib/argon2.rb#L33
return false if !pw_hash.match?(/^\$argon2i\$.{,112}/) return false if !pw_hash.match?(%r{^\$argon2i\$.{,112}})
# Argon2::Password.verify_password verifies argon2i hashes, too # Argon2::Password.verify_password verifies argon2i hashes, too
verified?(pw_hash, password) verified?(pw_hash, password)

View file

@ -1,7 +1,7 @@
class PasswordPolicy class PasswordPolicy
class Digit < PasswordPolicy::Backend class Digit < PasswordPolicy::Backend
NEED_DIGIT_REGEXP = /\d/.freeze NEED_DIGIT_REGEXP = %r{\d}.freeze
def valid? def valid?
@password.match? NEED_DIGIT_REGEXP @password.match? NEED_DIGIT_REGEXP

View file

@ -1,7 +1,7 @@
class PasswordPolicy class PasswordPolicy
class SpecialCharacter < PasswordPolicy::Backend class SpecialCharacter < PasswordPolicy::Backend
NEED_SPECIAL_CHARACTER_REGEXP = /\W/.freeze NEED_SPECIAL_CHARACTER_REGEXP = %r{\W}.freeze
def valid? def valid?
@password.match? NEED_SPECIAL_CHARACTER_REGEXP @password.match? NEED_SPECIAL_CHARACTER_REGEXP

View file

@ -1,7 +1,7 @@
class PasswordPolicy class PasswordPolicy
class UpperAndLowerCaseCharacters < PasswordPolicy::Backend class UpperAndLowerCaseCharacters < PasswordPolicy::Backend
UPPER_LOWER_REGEXPS = [/\p{Upper}.*\p{Upper}/, /\p{Lower}.*\p{Lower}/].freeze UPPER_LOWER_REGEXPS = [%r{\p{Upper}.*\p{Upper}}, %r{\p{Lower}.*\p{Lower}}].freeze
def valid? def valid?
UPPER_LOWER_REGEXPS.all? { |regexp| @password.match?(regexp) } UPPER_LOWER_REGEXPS.all? { |regexp| @password.match?(regexp) }

View file

@ -88,7 +88,7 @@ returns
replace = '\d\d:\d\d:\d\dZ$' replace = '\d\d:\d\d:\d\dZ$'
end end
next if key_as_string.iso8601.sub(/#{replace}/, '') != params[:range_start].iso8601.sub(/#{replace}/, '') next if key_as_string.iso8601.sub(%r{#{replace}}, '') != params[:range_start].iso8601.sub(%r{#{replace}}, '')
next if match next if match
match = true match = true

View file

@ -342,7 +342,7 @@ remove whole data from index
next if order_by&.at(index).blank? next if order_by&.at(index).blank?
# for sorting values use .keyword values (no analyzer is used - plain values) # for sorting values use .keyword values (no analyzer is used - plain values)
if value !~ /\./ && value !~ /_(time|date|till|id|ids|at)$/ if value !~ %r{\.} && value !~ %r{_(time|date|till|id|ids|at)$}
value += '.keyword' value += '.keyword'
end end
result.push( result.push(
@ -511,7 +511,7 @@ example for aggregations within one year
case data['pre_condition'] case data['pre_condition']
when 'not_set' when 'not_set'
data['value'] = if key_tmp.match?(/^(created_by|updated_by|owner|customer|user)_id/) data['value'] = if key_tmp.match?(%r{^(created_by|updated_by|owner|customer|user)_id})
1 1
end end
when 'current_user.id' when 'current_user.id'
@ -534,12 +534,12 @@ example for aggregations within one year
if data['value'].is_a?(Array) if data['value'].is_a?(Array)
data['value'].each do |value| data['value'].each do |value|
next if !value.is_a?(String) || value !~ /[A-z]/ next if !value.is_a?(String) || value !~ %r{[A-z]}
key_tmp += '.keyword' key_tmp += '.keyword'
break break
end end
elsif data['value'].is_a?(String) && /[A-z]/.match?(data['value']) elsif data['value'].is_a?(String) && %r{[A-z]}.match?(data['value'])
key_tmp += '.keyword' key_tmp += '.keyword'
end end
end end
@ -549,14 +549,14 @@ example for aggregations within one year
if data['value'].is_a?(Array) if data['value'].is_a?(Array)
data['value'].each_with_index do |value, index| data['value'].each_with_index do |value, index|
next if !value.is_a?(String) || value !~ /[A-z]/ next if !value.is_a?(String) || value !~ %r{[A-z]}
data['value'][index] = "*#{value}*" data['value'][index] = "*#{value}*"
key_tmp += '.keyword' key_tmp += '.keyword'
wildcard_or_term = 'wildcards' wildcard_or_term = 'wildcards'
break break
end end
elsif data['value'].is_a?(String) && /[A-z]/.match?(data['value']) elsif data['value'].is_a?(String) && %r{[A-z]}.match?(data['value'])
data['value'] = "*#{data['value']}*" data['value'] = "*#{data['value']}*"
key_tmp += '.keyword' key_tmp += '.keyword'
wildcard_or_term = 'wildcard' wildcard_or_term = 'wildcard'

View file

@ -18,7 +18,7 @@ class Sequencer
# model_name # model_name
# model_name_ # model_name_
# model_name # model_name
without_double_underscores.gsub(/_id(s?)$/, '_no\1') without_double_underscores.gsub(%r{_id(s?)$}, '_no\1')
end end
def without_double_underscores def without_double_underscores
@ -29,7 +29,7 @@ class Sequencer
# model_name # model_name
# model_name_ # model_name_
# model_name # model_name
only_supported_chars.gsub(/_{2,}/, '_') only_supported_chars.gsub(%r{_{2,}}, '_')
end end
def only_supported_chars def only_supported_chars
@ -40,7 +40,7 @@ class Sequencer
# model__name # model__name
# model_name_ # model_name_
# model_name # model_name
downcased.split('').map { |char| char.match?(/[a-z0-9_]/) ? char : '_' }.join downcased.split('').map { |char| char.match?(%r{[a-z0-9_]}) ? char : '_' }.join
end end
def downcased def downcased

View file

@ -30,13 +30,13 @@ class Sequencer
def extract_email(source) def extract_email(source)
# Support format like "Bob Smith (bob@example.com)" # Support format like "Bob Smith (bob@example.com)"
if source =~ /\((.+@.+)\)/ if source =~ %r{\((.+@.+)\)}
source = $1 source = $1
end end
Mail::Address.new(source).address Mail::Address.new(source).address
rescue rescue
return source if source !~ /<\s*([^>]+)/ return source if source !~ %r{<\s*([^>]+)}
$1.strip $1.strip
end end

Some files were not shown because too many files have changed in this diff Show more