Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zero width #4110

Merged
merged 10 commits into from
Jun 4, 2020
23 changes: 23 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class ApplicationController < ActionController::Base
around_action :handle_api_request, if: proc{|c| request.format.json? || request.format.atom? }
before_action :rewrite_v4_ids, if: proc{|c| request.method_symbol == :get && [params[:id], params[:content]].compact.any? { |i| i =~ /^[a-z]+:[0-9]+$/}}
before_action :set_no_cache_headers, if: proc{|c| request.xhr? }
prepend_before_action :remove_zero_width_chars

def set_no_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store"
Expand Down Expand Up @@ -202,4 +203,26 @@ def authenticate_user!(_opts = {})
def after_invite_path_for(_inviter, _invitee = nil)
main_app.persona_users_path
end

private

def remove_zero_width_chars
# params is a ActionController::Parameters
strip_zero_width_chars!(params)
end

def strip_zero_width_chars!(obj)
case obj
when String
obj.remove_zero_width_chars
when Array
obj.map! { |child| strip_zero_width_chars!(child) }
when Hash
obj.transform_values! { |value| strip_zero_width_chars!(value) }
when ActionController::Parameters
obj.each { |k, v| obj[k] = strip_zero_width_chars!(v) }
else
obj
end
end
end
1 change: 1 addition & 0 deletions config/initializers/avalon.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'string_additions'
require 'avalon/errors'
# Loads configuration information from the YAML file and then sets up the
# dropbox
Expand Down
23 changes: 23 additions & 0 deletions lib/string_additions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2011-2020, The Trustees of Indiana University and Northwestern
# University. Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
# --- END LICENSE_HEADER BLOCK ---

module StringAdditions
ZERO_WIDTH_CHARS = ["\u200B", "\u200C", "\u200D", "\uFEFF", "\u2060"].freeze

# Removes zero-width character from beginning and end of string
def remove_zero_width_chars
gsub(/^[#{String::ZERO_WIDTH_CHARS.join}]/, '').gsub(/[#{String::ZERO_WIDTH_CHARS.join}]$/, '')
end
end
String.prepend(StringAdditions)
11 changes: 11 additions & 0 deletions spec/controllers/admin_collections_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@
collection.reload
expect(manager).not_to be_in(collection.managers)
end

context 'with zero-width characters' do
let(:manager) { FactoryBot.create(:manager) }
let(:manager_key) { "#{manager.user_key}\u200B" }

it "should add users to manager role" do
put 'update', params: { id: collection.id, submit_add_manager: 'Add', add_manager: manager_key }
collection.reload
expect(manager).to be_in(collection.managers)
end
end
end

describe "#edit" do
Expand Down
17 changes: 17 additions & 0 deletions spec/controllers/application_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,21 @@ def show
expect(controller.after_invite_path_for(nil)).to eq('/persona/users')
end
end

describe 'remove_zero_width_chars' do
it 'removes zero-width chars from string params' do
post :create, params: { id: 'abc1234', key: "\u200Bvalue\u2060" }
expect(controller.params[:key]).to eq "value"
end

it 'removes zero-width chars from array params' do
post :create, params: { id: 'abc1234', key: ["\u200Bvalue\u2060"] }
expect(controller.params[:key]).to eq ["value"]
end

it 'removes zero-width chars from hash params' do
post :create, params: { id: 'abc1234', key: { subkey: "\u200Bvalue\u2060" } }
expect(controller.params[:key][:subkey]).to eq "value"
end
end
end
42 changes: 42 additions & 0 deletions spec/lib/string_additions_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2011-2020, The Trustees of Indiana University and Northwestern
# University. Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
# --- END LICENSE_HEADER BLOCK ---

require 'rails_helper'

describe 'StringAdditions' do
describe 'remove_zero_width_chars' do
it 'removes zero-width characters from the beginning and end of strings' do
String::ZERO_WIDTH_CHARS.each do |char|
expect("test#{char}".remove_zero_width_chars).to eq 'test'
expect("#{char}test".remove_zero_width_chars).to eq 'test'
end
end

it 'does not remove zero-width characters from the middle of strings' do
String::ZERO_WIDTH_CHARS.each do |char|
expect("test#{char}test".remove_zero_width_chars).to eq "test#{char}test"
expect("#{char}test#{char}test#{char}".remove_zero_width_chars).to eq "test#{char}test"
end
end

it 'does not remove non-zero-width characters' do
expect('test'.remove_zero_width_chars).to eq 'test'
expect('test '.remove_zero_width_chars).to eq 'test '
expect(' test '.remove_zero_width_chars).to eq ' test '
expect('test test'.remove_zero_width_chars).to eq 'test test'
expect("\ttest\t".remove_zero_width_chars).to eq "\ttest\t"
expect("\ntest\n".remove_zero_width_chars).to eq "\ntest\n"
end
end
end