switch to Syck earlier in the boot process

particularly, before canvas-jobs loads

Change-Id: Ib80215bd971bad2b4ba53aa8ac65301becf4b572
Reviewed-on: https://gerrit.instructure.com/69244
Reviewed-by: Rob Orton <rob@instructure.com>
Product-Review: August Thornton <august@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
This commit is contained in:
Cody Cutrer 2015-12-18 16:34:04 -07:00
parent 1ab5012f0b
commit fb8d78584a
3 changed files with 79 additions and 56 deletions

View File

@ -1,6 +1,8 @@
# Put this in config/application.rb
require File.expand_path('../boot', __FILE__)
require_relative '../lib/canvas_yaml'
unless CANVAS_RAILS3
# Yes, it doesn't seem DRY to list these both in the if and else
@ -170,62 +172,6 @@ module CanvasRails
end
end
# We need to make sure that safe_yaml is loaded *after* the YAML engine
# is switched to Syck (which DelayedJob needs for now). Otherwise we
# won't have access to (safe|unsafe)_load.
require 'yaml'
if RUBY_VERSION >= '2.0.0'
require 'syck'
end
YAML::ENGINE.yamler = 'syck' if defined?(YAML::ENGINE)
require 'safe_yaml'
# safe_yaml can't whitelist specific instances of scalar values, so just override the loading
# here, and do a weird check
YAML.add_ruby_type("object:Class") do |_type, val|
if SafeYAML.safe_parsing && !Canvas::Migration.valid_converter_classes.include?(val)
raise "Cannot load class #{val} from YAML"
end
val.constantize
end
trusted_tags = SafeYAML::TRUSTED_TAGS.dup
trusted_tags << 'tag:yaml.org,2002:merge'
SafeYAML.send(:remove_const, :TRUSTED_TAGS)
SafeYAML.const_set(:TRUSTED_TAGS, trusted_tags.freeze)
module FixSafeYAMLNullMerge
def merge_into_hash(hash, array)
return unless array
super
end
end
SafeYAML::Resolver.prepend(FixSafeYAMLNullMerge)
SafeYAML::OPTIONS.merge!(
default_mode: :safe,
deserialize_symbols: true,
raise_on_unknown_tag: true,
# This tag whitelist is syck specific. We'll need to tweak it when we upgrade to psych.
# See the tests in spec/lib/safe_yaml_spec.rb
whitelisted_tags: %w[
tag:ruby.yaml.org,2002:symbol
tag:yaml.org,2002:float
tag:yaml.org,2002:str
tag:yaml.org,2002:timestamp
tag:yaml.org,2002:timestamp#iso8601
tag:yaml.org,2002:timestamp#spaced
tag:yaml.org,2002:map:HashWithIndifferentAccess
tag:yaml.org,2002:map:ActiveSupport::HashWithIndifferentAccess
tag:ruby.yaml.org,2002:object:Class
tag:ruby.yaml.org,2002:object:OpenStruct
tag:ruby.yaml.org,2002:object:Scribd::Document
tag:ruby.yaml.org,2002:object:Mime::Type
tag:ruby.yaml.org,2002:object:URI::HTTP
tag:ruby.yaml.org,2002:object:URI::HTTPS
tag:ruby.yaml.org,2002:object:OpenObject
tag:yaml.org,2002:map:WeakParameters
]
)
SafeYAML.singleton_class.send(:attr_accessor, :safe_parsing)
module SafeYAMLWithFlag
def load(*args)
@ -237,6 +183,15 @@ module CanvasRails
end
SafeYAML.singleton_class.prepend(SafeYAMLWithFlag)
# safe_yaml can't whitelist specific instances of scalar values, so just override the loading
# here, and do a weird check
YAML.add_ruby_type("object:Class") do |_type, val|
if SafeYAML.safe_parsing && !Canvas::Migration.valid_converter_classes.include?(val)
raise "Cannot load class #{val} from YAML"
end
val.constantize
end
# Extend any base classes, even gem classes
Dir.glob("#{Rails.root}/lib/ext/**/*.rb").each { |file| require file }

67
lib/canvas_yaml.rb Normal file
View File

@ -0,0 +1,67 @@
#
# Copyright (C) 2015 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This is an initializer, but needs to be required earlier in the load process,
# and before canvas-jobs
# We need to make sure that safe_yaml is loaded *after* the YAML engine
# is switched to Syck. Otherwise we
# won't have access to (safe|unsafe)_load.
require 'yaml'
require 'syck'
YAML::ENGINE.yamler = 'syck' if defined?(YAML::ENGINE)
require 'safe_yaml'
trusted_tags = SafeYAML::TRUSTED_TAGS.dup
trusted_tags << 'tag:yaml.org,2002:merge'
SafeYAML.send(:remove_const, :TRUSTED_TAGS)
SafeYAML.const_set(:TRUSTED_TAGS, trusted_tags.freeze)
module FixSafeYAMLNullMerge
def merge_into_hash(hash, array)
return unless array
super
end
end
SafeYAML::Resolver.prepend(FixSafeYAMLNullMerge)
SafeYAML::OPTIONS.merge!(
default_mode: :safe,
deserialize_symbols: true,
raise_on_unknown_tag: true,
# This tag whitelist is syck specific. We'll need to tweak it when we upgrade to psych.
# See the tests in spec/lib/safe_yaml_spec.rb
whitelisted_tags: %w[
tag:ruby.yaml.org,2002:symbol
tag:yaml.org,2002:float
tag:yaml.org,2002:str
tag:yaml.org,2002:timestamp
tag:yaml.org,2002:timestamp#iso8601
tag:yaml.org,2002:timestamp#spaced
tag:yaml.org,2002:map:HashWithIndifferentAccess
tag:yaml.org,2002:map:ActiveSupport::HashWithIndifferentAccess
tag:ruby.yaml.org,2002:object:Class
tag:ruby.yaml.org,2002:object:OpenStruct
tag:ruby.yaml.org,2002:object:Scribd::Document
tag:ruby.yaml.org,2002:object:Mime::Type
tag:ruby.yaml.org,2002:object:URI::HTTP
tag:ruby.yaml.org,2002:object:URI::HTTPS
tag:ruby.yaml.org,2002:object:OpenObject
tag:yaml.org,2002:map:WeakParameters
]
)

View File

@ -5,6 +5,7 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
# We avoid loading the whole rails environment here, so that commands like
# `status` and `start` return much faster.
require 'bundler/setup'
require_relative '../lib/canvas_yaml'
require 'delayed_job'
Delayed::Pool.new.run()