No title Revision 663932343733 (Mon Feb 13 2012 at 15:43) - Diff Link to this snippet: https://friendpaste.com/1H4zOcciVjajGuYTRyrUUB Embed: manni perldoc borland colorful default murphy trac fruity autumn bw emacs pastie friendly Show line numbers Wrap lines 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180From 52804ef907f5c0c4cf9ea45c42714502ba46093f Mon Sep 17 00:00:00 2001From: Filipe David Borba Manana <fdmanana@apache.org>Date: Mon, 13 Feb 2012 15:41:14 +0000Subject: [PATCH] Only validate numbers on JSON decodingLet the encoder validate only the numbers and encode themas the term {json, RawNumberJsonBinary}.COUCHDB-1407--- src/couchdb/couch_db.hrl | 1 + src/couchdb/couch_httpd.erl | 2 +- src/couchdb/couch_httpd_db.erl | 2 +- src/couchdb/couch_query_servers.erl | 2 +- src/ejson/ejson.erl | 60 ++++++++++++++++++++++------------ 5 files changed, 43 insertions(+), 24 deletions(-)diff --git a/src/couchdb/couch_db.hrl b/src/couchdb/couch_db.hrlindex 65eb7f0..6fae38c 100644--- a/src/couchdb/couch_db.hrl+++ b/src/couchdb/couch_db.hrl@@ -23,6 +23,7 @@ -define(JSON_ENCODE(V), ejson:encode(V)). -define(JSON_DECODE(V), ejson:decode(V)).+-define(JSON_DECODE_RAW_NUMBERS(V), ejson:decode(V, [raw_numbers])). -define(b2l(V), binary_to_list(V)). -define(l2b(V), list_to_binary(V)).diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erlindex 8b05076..a9dd65e 100644--- a/src/couchdb/couch_httpd.erl+++ b/src/couchdb/couch_httpd.erl@@ -556,7 +556,7 @@ body(#httpd{req_body=ReqBody}) -> ReqBody. json_body(Httpd) ->- ?JSON_DECODE(body(Httpd)).+ ?JSON_DECODE_RAW_NUMBERS(body(Httpd)). json_body_obj(Httpd) -> case json_body(Httpd) ofdiff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erlindex f669643..f732401 100644--- a/src/couchdb/couch_httpd_db.erl+++ b/src/couchdb/couch_httpd_db.erl@@ -509,7 +509,7 @@ db_doc_req(#httpd{method='POST'}=Req, Db, DocId) -> Rev = couch_doc:parse_rev(couch_util:get_value("_rev", Form)), {ok, [{ok, Doc}]} = couch_db:open_doc_revs(Db, DocId, [Rev], []); Json ->- Doc = couch_doc_from_req(Req, DocId, ?JSON_DECODE(Json))+ Doc = couch_doc_from_req(Req, DocId, ?JSON_DECODE_RAW_NUMBERS(Json)) end, UpdatedAtts = [ #att{name=validate_attachment_name(Name),diff --git a/src/couchdb/couch_query_servers.erl b/src/couchdb/couch_query_servers.erlindex e29f23b..e757edf 100644--- a/src/couchdb/couch_query_servers.erl+++ b/src/couchdb/couch_query_servers.erl@@ -526,7 +526,7 @@ proc_prompt_raw(#proc{prompt_fun = {Mod, Func}} = Proc, Args) -> apply(Mod, Func, [Proc#proc.pid, Args]). raw_to_ejson({json, Json}) ->- ?JSON_DECODE(Json);+ ?JSON_DECODE_RAW_NUMBERS(Json); raw_to_ejson(EJson) -> EJson. diff --git a/src/ejson/ejson.erl b/src/ejson/ejson.erlindex 07a71c2..85e155b 100644--- a/src/ejson/ejson.erl+++ b/src/ejson/ejson.erl@@ -11,7 +11,7 @@ % the License. -module(ejson).--export([encode/1, decode/1]).+-export([encode/1, decode/1, decode/2]). -on_load(init/0). init() ->@@ -34,8 +34,11 @@ init() -> decode(IoList) ->+ decode(IoList, []).++decode(IoList, Options) -> try- nif_decode(IoList)+ nif_decode(IoList, Options) catch exit:ejson_nif_not_loaded -> erl_decode(IoList) end.@@ -48,10 +51,11 @@ encode(EJson) -> end. -nif_decode(IoList) ->+nif_decode(IoList, Options) -> case reverse_tokens(IoList) of {ok, ReverseTokens} ->- [[EJson]] = make_ejson(ReverseTokens, [[]]),+ RawNumbers = lists:member(raw_numbers, Options),+ [[EJson]] = make_ejson(ReverseTokens, [[]], RawNumbers), EJson; Error -> throw({invalid_json, {Error, IoList}})@@ -85,6 +89,8 @@ mochi_encode_handler(Bad) -> % everything in the list is the final output except for tuples with % {0, Strings} and {1, Floats}, which are to be converted to strings % inside the NIF.+encode_rev({json, RawJson}) ->+ RawJson; encode_rev(true) -> <<"true">>; encode_rev(false) ->@@ -132,31 +138,43 @@ as_binary(L) when is_list(L) -> list_to_binary(L). -make_ejson([], Stack) ->+make_ejson([], Stack, _RawNumbers) -> Stack;-make_ejson([0 | RevEvs], [ArrayValues, PrevValues | RestStack]) ->+make_ejson([0 | RevEvs], [ArrayValues, PrevValues | RestStack], RawNumbers) -> % 0 ArrayStart- make_ejson(RevEvs, [[ArrayValues | PrevValues] | RestStack]);-make_ejson([1 | RevEvs], Stack) ->+ make_ejson(RevEvs, [[ArrayValues | PrevValues] | RestStack], RawNumbers);+make_ejson([1 | RevEvs], Stack, RawNumbers) -> % 1 ArrayEnd- make_ejson(RevEvs, [[] | Stack]);-make_ejson([2 | RevEvs], [ObjValues, PrevValues | RestStack]) ->+ make_ejson(RevEvs, [[] | Stack], RawNumbers);+make_ejson([2 | RevEvs], [ObjValues, PrevValues | RestStack], RawNumbers) -> % 2 ObjectStart- make_ejson(RevEvs, [[{ObjValues} | PrevValues] | RestStack]);-make_ejson([3 | RevEvs], Stack) ->+ make_ejson(RevEvs, [[{ObjValues} | PrevValues] | RestStack], RawNumbers);+make_ejson([3 | RevEvs], Stack, RawNumbers) -> % 3 ObjectEnd- make_ejson(RevEvs, [[] | Stack]);-make_ejson([{0, Value} | RevEvs], [Vals | RestStack] = _Stack) ->+ make_ejson(RevEvs, [[] | Stack], RawNumbers);+make_ejson([{0, Value} | RevEvs], [Vals | RestStack] = _Stack, RawNumbers) -> % {0, IntegerString}- make_ejson(RevEvs, [[list_to_integer(binary_to_list(Value)) | Vals] | RestStack]);-make_ejson([{1, Value} | RevEvs], [Vals | RestStack] = _Stack) ->+ EncValue = case RawNumbers of+ true ->+ {json, Value};+ false ->+ list_to_integer(binary_to_list(Value))+ end,+ make_ejson(RevEvs, [[EncValue | Vals] | RestStack], RawNumbers);+make_ejson([{1, Value} | RevEvs], [Vals | RestStack] = _Stack, RawNumbers) -> % {1, FloatString}- make_ejson(RevEvs, [[list_to_float(binary_to_list(Value)) | Vals] | RestStack]);-make_ejson([{3, String} | RevEvs], [[PrevValue|RestObject] | RestStack] = _Stack) ->+ EncValue = case RawNumbers of+ true ->+ {json, Value};+ false ->+ list_to_float(binary_to_list(Value))+ end,+ make_ejson(RevEvs, [[EncValue | Vals] | RestStack], RawNumbers);+make_ejson([{3, String} | RevEvs], [[PrevValue|RestObject] | RestStack] = _Stack, RawNumbers) -> % {3 , ObjectKey}- make_ejson(RevEvs, [[{String, PrevValue}|RestObject] | RestStack]);-make_ejson([Value | RevEvs], [Vals | RestStack] = _Stack) ->- make_ejson(RevEvs, [[Value | Vals] | RestStack]).+ make_ejson(RevEvs, [[{String, PrevValue}|RestObject] | RestStack], RawNumbers);+make_ejson([Value | RevEvs], [Vals | RestStack] = _Stack, RawNumbers) ->+ make_ejson(RevEvs, [[Value | Vals] | RestStack], RawNumbers). reverse_tokens(_) ->-- 1.7.4.4