diff options
Diffstat (limited to 'Bugzilla')
-rw-r--r-- | Bugzilla/WebService/JSON.pm | 64 | ||||
-rw-r--r-- | Bugzilla/WebService/JSON/Box.pm | 43 | ||||
-rw-r--r-- | Bugzilla/WebService/Server/JSONRPC.pm | 14 | ||||
-rw-r--r-- | Bugzilla/WebService/Server/REST.pm | 1 |
4 files changed, 120 insertions, 2 deletions
diff --git a/Bugzilla/WebService/JSON.pm b/Bugzilla/WebService/JSON.pm new file mode 100644 index 000000000..5c28b20f4 --- /dev/null +++ b/Bugzilla/WebService/JSON.pm @@ -0,0 +1,64 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::WebService::JSON; +use 5.10.1; +use Moo; + +use Bugzilla::Logging; +use Bugzilla::WebService::JSON::Box; +use JSON::MaybeXS; +use Scalar::Util qw(refaddr blessed); +use Package::Stash; + +use constant Box => 'Bugzilla::WebService::JSON::Box'; + +has 'json' => ( + init_arg => undef, + is => 'lazy', + handles => {_encode => 'encode', _decode => 'decode'}, +); + +sub encode { + my ($self, $value) = @_; + return Box->new(json => $self, value => $value); +} + +sub decode { + my ($self, $box) = @_; + + if (blessed($box) && $box->isa(Box)) { + return $box->value; + } + else { + return $self->_decode($box); + } +} + +sub _build_json { JSON::MaybeXS->new } + +# delegation all the json options to the real json encoder. +{ + my @json_methods = qw( + utf8 ascii pretty canonical + allow_nonref allow_blessed convert_blessed + ); + my $stash = Package::Stash->new(__PACKAGE__); + foreach my $method (@json_methods) { + my $symbol = '&' . $method; + $stash->add_symbol( + $symbol => sub { + my $self = shift; + $self->json->$method(@_); + return $self; + } + ); + } +} + + +1; diff --git a/Bugzilla/WebService/JSON/Box.pm b/Bugzilla/WebService/JSON/Box.pm new file mode 100644 index 000000000..fc39aeee8 --- /dev/null +++ b/Bugzilla/WebService/JSON/Box.pm @@ -0,0 +1,43 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::WebService::JSON::Box; +use 5.10.1; +use Moo; + +use overload '${}' => 'value', '""' => 'to_string', fallback => 1; + +has 'value' => (is => 'ro', required => 1); +has 'json' => (is => 'ro', required => 1); +has 'label' => (is => 'lazy'); +has 'encode' => (init_arg => undef, is => 'lazy', predicate => 'is_encoded'); + +sub TO_JSON { + my ($self) = @_; + + return $self->to_string; +} + +sub to_string { + my ($self) = @_; + + return $self->is_encoded ? $self->encode : $self->label; +} + +sub _build_encode { + my ($self) = @_; + + return $self->json->_encode($self->value); +} + +sub _build_label { + my ($self) = @_; + + return "" . $self->value; +} + +1; diff --git a/Bugzilla/WebService/Server/JSONRPC.pm b/Bugzilla/WebService/Server/JSONRPC.pm index 093167048..12a3143cc 100644 --- a/Bugzilla/WebService/Server/JSONRPC.pm +++ b/Bugzilla/WebService/Server/JSONRPC.pm @@ -31,7 +31,9 @@ use Bugzilla::Util; use HTTP::Message; use MIME::Base64 qw(decode_base64 encode_base64); +use Scalar::Util qw(blessed); use List::MoreUtils qw(none); +use Bugzilla::WebService::JSON; ##################################### # Public JSON::RPC Method Overrides # @@ -48,7 +50,7 @@ sub new { sub create_json_coder { my $self = shift; - my $json = $self->SUPER::create_json_coder(@_); + my $json = Bugzilla::WebService::JSON->new; $json->allow_blessed(1); $json->convert_blessed(1); $json->allow_nonref(1); @@ -83,6 +85,9 @@ sub response { # Implement JSONP. if (my $callback = $self->_bz_callback) { my $content = $response->content; + if (blessed $content) { + $content = $content->encode; + } # Prepend the JSONP response with /**/ in order to protect # against possible encoding attacks (e.g., affecting Flash). $response->content("/**/$callback($content)"); @@ -110,7 +115,12 @@ sub response { else { push(@header_args, "-ETag", $etag) if $etag; print $cgi->header(-status => $response->code, @header_args); - print $response->content; + my $content = $response->content; + if (blessed $content) { + $content = $content->encode; + utf8::encode($content); + } + print $content; } } diff --git a/Bugzilla/WebService/Server/REST.pm b/Bugzilla/WebService/Server/REST.pm index 13896b248..5d8367410 100644 --- a/Bugzilla/WebService/Server/REST.pm +++ b/Bugzilla/WebService/Server/REST.pm @@ -165,6 +165,7 @@ sub response { my $template = Bugzilla->template; $content = ""; + $result->encode if blessed $result; $template->process("rest.html.tmpl", { result => $result }, \$content) || ThrowTemplateError($template->error()); |