diff options
author | Eric Avdey <eiri@eiri.ca> | 2017-09-14 10:40:17 -0300 |
---|---|---|
committer | Eric Avdey <eiri@eiri.ca> | 2017-09-14 12:45:53 -0300 |
commit | 369b442e647cf863bbeeb42c6ea8027b0f7b8123 (patch) | |
tree | cffcf9b8bb7f3e25ac2c7a007ec8fb99314aeee4 | |
parent | ed6ec66972f268b6d6d86b55730e73cc4ab54ceb (diff) | |
download | couchdb-369b442e647cf863bbeeb42c6ea8027b0f7b8123.tar.gz |
Catch invalid base64 in inline attachments
-rw-r--r-- | src/couch/src/couch_att.erl | 55 | ||||
-rw-r--r-- | test/javascript/tests/attachments.js | 18 |
2 files changed, 64 insertions, 9 deletions
diff --git a/src/couch/src/couch_att.erl b/src/couch/src/couch_att.erl index e78d6ef11..5c040a8c4 100644 --- a/src/couch/src/couch_att.erl +++ b/src/couch/src/couch_att.erl @@ -413,13 +413,21 @@ follow_from_json(Att, Props) -> inline_from_json(Att, Props) -> B64Data = couch_util:get_value(<<"data">>, Props), - Data = base64:decode(B64Data), - Length = size(Data), - RevPos = couch_util:get_value(<<"revpos">>, Props, 0), - store([ - {data, Data}, {revpos, RevPos}, {disk_len, Length}, - {att_len, Length} - ], Att). + try base64:decode(B64Data) of + Data -> + Length = size(Data), + RevPos = couch_util:get_value(<<"revpos">>, Props, 0), + store([ + {data, Data}, {revpos, RevPos}, {disk_len, Length}, + {att_len, Length} + ], Att) + catch + _:_ -> + Name = fetch(name, Att), + ErrMsg = <<"Invalid attachment data for ", Name/binary>>, + throw({bad_request, ErrMsg}) + end. + encoded_lengths_from_json(Props) -> @@ -787,8 +795,37 @@ attachment_disk_term_test_() -> attachment_json_term_test_() -> - %% We need to create a few variations including stubs and inline data. - {"JSON term tests", []}. + Props = [ + {<<"content_type">>, <<"application/json">>}, + {<<"digest">>, <<"md5-QCNtWUNXV0UzJnEjMk92YUk1JA==">>}, + {<<"length">>, 14}, + {<<"revpos">>, 1} + ], + PropsInline = [{<<"data">>, <<"eyJhbnN3ZXIiOiA0Mn0=">>}] ++ Props, + InvalidProps = [{<<"data">>, <<"!Base64Encoded$">>}] ++ Props, + Att = couch_att:new([ + {name, <<"attachment.json">>}, + {type, <<"application/json">>} + ]), + ResultStub = couch_att:new([ + {name, <<"attachment.json">>}, + {type, <<"application/json">>}, + {att_len, 14}, + {disk_len, 14}, + {md5, <<"@#mYCWWE3&q#2OvaI5$">>}, + {revpos, 1}, + {data, stub}, + {encoding, identity} + ]), + ResultFollows = ResultStub#att{data = follows}, + ResultInline = ResultStub#att{md5 = <<>>, data = <<"{\"answer\": 42}">>}, + {"JSON term tests", [ + ?_assertEqual(ResultStub, stub_from_json(Att, Props)), + ?_assertEqual(ResultFollows, follow_from_json(Att, Props)), + ?_assertEqual(ResultInline, inline_from_json(Att, PropsInline)), + ?_assertThrow({bad_request, _}, inline_from_json(Att, Props)), + ?_assertThrow({bad_request, _}, inline_from_json(Att, InvalidProps)) + ]}. attachment_stub_merge_test_() -> diff --git a/test/javascript/tests/attachments.js b/test/javascript/tests/attachments.js index cd6474d0f..2e831a731 100644 --- a/test/javascript/tests/attachments.js +++ b/test/javascript/tests/attachments.js @@ -33,6 +33,24 @@ couchTests.attachments= function(debug) { var save_response = db.save(binAttDoc); T(save_response.ok); + var badAttDoc = { + _id: "bad_doc", + _attachments: { + "foo.txt": { + content_type: "text/plain", + data: "notBase64Encoded=" + } + } + }; + + try { + db.save(badAttDoc); + T(false && "Shouldn't get here!"); + } catch (e) { + TEquals("bad_request", e.error); + TEquals("Invalid attachment data for foo.txt", e.message); + } + var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt"); T(xhr.responseText == "This is a base64 encoded text"); T(xhr.getResponseHeader("Content-Type") == "application/octet-stream"); |