[DRE-commits] [chef] 02/03: json_create_CVE-2013-0269_workaround
Antonio Terceiro
terceiro at moszumanska.debian.org
Sat Jun 13 18:47:30 UTC 2015
This is an automated email from the git hooks/post-receive script.
terceiro pushed a commit to branch patch-queue/debian/wheezy
in repository chef.
commit 8d856b98f87b4bf3f0f83d74886560f10980bd8e
Author: Debian Ruby Extras Maintainers <pkg-ruby-extras-maintainers at lists.alioth.debian.org>
Date: Sat Feb 21 23:58:35 2015 -0200
json_create_CVE-2013-0269_workaround
---
lib/chef/cookbook_version.rb | 2 +-
lib/chef/json_compat.rb | 98 +++++++++++++++++++++++++++++++++++++++++++-
lib/chef/resource.rb | 18 ++++++++
3 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb
index 1c2deef..c7c9503 100644
--- a/lib/chef/cookbook_version.rb
+++ b/lib/chef/cookbook_version.rb
@@ -807,7 +807,7 @@ class Chef
cookbook_version.manifest = o
# We don't need the following step when we decide to stop supporting deprecated operators in the metadata (e.g. <<, >>)
- cookbook_version.manifest["metadata"] = JSON.parse(cookbook_version.metadata.to_json)
+ cookbook_version.manifest["metadata"] = Chef::JSONCompat.from_json(cookbook_version.metadata.to_json)
cookbook_version.freeze_version if o["frozen?"]
cookbook_version
diff --git a/lib/chef/json_compat.rb b/lib/chef/json_compat.rb
index 9f59a41..4e14a11 100644
--- a/lib/chef/json_compat.rb
+++ b/lib/chef/json_compat.rb
@@ -24,6 +24,22 @@ class Chef
class JSONCompat
JSON_MAX_NESTING = 1000
+ JSON_CLASS = "json_class".freeze
+
+ CHEF_APICLIENT = "Chef::ApiClient".freeze
+ CHEF_CHECKSUM = "Chef::Checksum".freeze
+ CHEF_COOKBOOKVERSION = "Chef::CookbookVersion".freeze
+ CHEF_DATABAG = "Chef::DataBag".freeze
+ CHEF_DATABAGITEM = "Chef::DataBagItem".freeze
+ CHEF_ENVIRONMENT = "Chef::Environment".freeze
+ CHEF_NODE = "Chef::Node".freeze
+ CHEF_ROLE = "Chef::Role".freeze
+ CHEF_SANDBOX = "Chef::Sandbox".freeze
+ CHEF_RESOURCE = "Chef::Resource".freeze
+ CHEF_RESOURCECOLLECTION = "Chef::ResourceCollection".freeze
+ CHEF_WEBUIUSER = "Chef::WebUIUser".freeze
+ CHEF_OPENIDREGISTRAION = "Chef::OpenIDRegistration".freeze
+
class <<self
# See CHEF-1292/PL-538. Increase the max nesting for JSON, which defaults
# to 19, and isn't enough for some (for example, a Node within a Node)
@@ -38,7 +54,49 @@ class Chef
# Just call the JSON gem's parse method with a modified :max_nesting field
def from_json(source, opts = {})
- ::JSON.parse(source, opts_add_max_nesting(opts))
+ obj = ::Yajl::Parser.parse(source)
+
+ unless obj.kind_of?(Hash) || obj.kind_of?(Array)
+ raise JSON::ParserError, "Top level JSON object must be a Hash or Array (actual: #{obj.class})"
+ end
+
+ # The old default in the json gem (which we are mimicing because we
+ # sadly rely on this misfeature) is to "create additions" i.e., convert
+ # JSON objects into ruby objects. Explicit :create_additions => false
+ # is required to turn it off.
+ if opts[:create_additions].nil? || opts[:create_additions]
+ map_to_rb_obj(obj)
+ else
+ obj
+ end
+ rescue Yajl::ParseError => e
+ raise JSON::ParserError, e.message
+ end
+
+ # Look at an object that's a basic type (from json parse) and convert it
+ # to an instance of Chef classes if desired.
+ def map_to_rb_obj(json_obj)
+ res = case json_obj
+ when Hash
+ mapped_hash = map_hash_to_rb_obj(json_obj)
+ if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS]))
+ class_to_inflate.json_create(mapped_hash)
+ else
+ mapped_hash
+ end
+ when Array
+ json_obj.map {|e| map_to_rb_obj(e) }
+ else
+ json_obj
+ end
+ res
+ end
+
+ def map_hash_to_rb_obj(json_hash)
+ json_hash.each do |key, value|
+ json_hash[key] = map_to_rb_obj(value)
+ end
+ json_hash
end
def to_json(obj, opts = nil)
@@ -48,6 +106,44 @@ class Chef
def to_json_pretty(obj, opts = nil)
::JSON.pretty_generate(obj, opts_add_max_nesting(opts))
end
+
+
+ def class_for_json_class(json_class)
+ case json_class
+ when CHEF_APICLIENT
+ Chef::ApiClient
+ when CHEF_CHECKSUM
+ Chef::Checksum
+ when CHEF_COOKBOOKVERSION
+ Chef::CookbookVersion
+ when CHEF_DATABAG
+ Chef::DataBag
+ when CHEF_DATABAGITEM
+ Chef::DataBagItem
+ when CHEF_ENVIRONMENT
+ Chef::Environment
+ when CHEF_NODE
+ Chef::Node
+ when CHEF_ROLE
+ Chef::Role
+ when CHEF_SANDBOX
+ Chef::Sandbox
+ when CHEF_RESOURCE
+ Chef::Resource
+ when CHEF_RESOURCECOLLECTION
+ Chef::ResourceCollection
+ when CHEF_WEBUIUSER
+ Chef::WebUIUser
+ when CHEF_OPENIDREGISTRAION
+ Chef::OpenIDRegistration
+ when /^Chef::Resource/
+ Chef::Resource.find_subclass_by_name(json_class)
+ else
+ raise JSON::ParserError, "Unsupported `json_class` type '#{json_class}'"
+ end
+ end
+
end
end
end
+
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 2fd3942..b8f7603 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -74,6 +74,24 @@ F
FORBIDDEN_IVARS = [:@run_context, :@node, :@not_if, :@only_if]
HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@node]
+ # Track all subclasses of Resource. This is used so names can be looked up
+ # when attempting to deserialize from JSON. (See: json_compat)
+ def self.resource_classes
+ @resource_classes ||= []
+ end
+
+ # Callback when subclass is defined. Adds subclass to list of subclasses.
+ def self.inherited(subclass)
+ resource_classes << subclass
+ end
+
+ # Look up a subclass by +class_name+ which should be a string that matches
+ # `Subclass.name`
+ def self.find_subclass_by_name(class_name)
+ resource_classes.first {|c| c.name == class_name }
+ end
+
+
include Chef::Mixin::CheckHelper
include Chef::Mixin::ParamsValidate
include Chef::Mixin::Language
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/chef.git
More information about the Pkg-ruby-extras-commits
mailing list