json.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2011 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #include "json.h"
  36. #include <sstream>
  37. #include "array_fun.h"
  38. #include "DlAbortEx.h"
  39. #include "error_code.h"
  40. #include "a2functional.h"
  41. #include "util.h"
  42. #include "fmt.h"
  43. #include "Base64.h"
  44. namespace aria2 {
  45. namespace json {
  46. // Function prototype declaration
  47. namespace {
  48. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  49. decode
  50. (std::string::const_iterator first,
  51. std::string::const_iterator last,
  52. size_t depth);
  53. } // namespace
  54. namespace {
  55. const char WS[] = { 0x20, 0x09, 0x0a, 0x0d };
  56. const char ESCAPE_CHARS[] = { '"', '\\', '/', '\b', '\f', '\n', '\r', '\t' };
  57. const size_t MAX_STRUCTURE_DEPTH = 100;
  58. } // namespace
  59. namespace {
  60. std::string::const_iterator skipWs
  61. (std::string::const_iterator first,
  62. std::string::const_iterator last)
  63. {
  64. while(first != last && std::find(vbegin(WS), vend(WS), *first) != vend(WS)) {
  65. ++first;
  66. }
  67. return first;
  68. }
  69. } // namespace
  70. namespace {
  71. void checkEof
  72. (std::string::const_iterator first,
  73. std::string::const_iterator last)
  74. {
  75. if(first == last) {
  76. throw DL_ABORT_EX2("JSON decoding failed: unexpected EOF",
  77. error_code::JSON_PARSE_ERROR);
  78. }
  79. }
  80. } // namespace
  81. namespace {
  82. std::string::const_iterator
  83. decodeKeyword
  84. (std::string::const_iterator first,
  85. std::string::const_iterator last,
  86. const std::string& keyword)
  87. {
  88. size_t len = keyword.size();
  89. for(size_t i = 0; i < len; ++i) {
  90. checkEof(first, last);
  91. if(*first != keyword[i]) {
  92. throw DL_ABORT_EX2(fmt("JSON decoding failed: %s not found.",
  93. keyword.c_str()),
  94. error_code::JSON_PARSE_ERROR);
  95. }
  96. ++first;
  97. }
  98. return first;
  99. }
  100. } // namespace
  101. namespace {
  102. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  103. decodeTrue
  104. (std::string::const_iterator first,
  105. std::string::const_iterator last)
  106. {
  107. first = decodeKeyword(first, last, "true");
  108. return std::make_pair(Bool::gTrue(), first);
  109. }
  110. } // namespace
  111. namespace {
  112. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  113. decodeFalse
  114. (std::string::const_iterator first,
  115. std::string::const_iterator last)
  116. {
  117. first = decodeKeyword(first, last, "false");
  118. return std::make_pair(Bool::gFalse(), first);
  119. }
  120. } // namespace
  121. namespace {
  122. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  123. decodeNull
  124. (std::string::const_iterator first,
  125. std::string::const_iterator last)
  126. {
  127. first = decodeKeyword(first, last, "null");
  128. return std::make_pair(Null::g(), first);
  129. }
  130. } // namespace
  131. namespace {
  132. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  133. decodeString
  134. (std::string::const_iterator first,
  135. std::string::const_iterator last)
  136. {
  137. // Consume first char, assuming it is '"'.
  138. ++first;
  139. std::string s;
  140. std::string::const_iterator offset = first;
  141. while(first != last) {
  142. if(*first == '"') {
  143. break;
  144. }
  145. if(*first == '\\') {
  146. s += std::string(offset, first);
  147. ++first;
  148. checkEof(first, last);
  149. if(*first == 'u') {
  150. ++first;
  151. std::string uchars;
  152. for(int i = 0; i < 4; ++i, ++first) {
  153. checkEof(first, last);
  154. uchars += *first;
  155. }
  156. checkEof(first, last);
  157. uint16_t codepoint = util::parseUInt(uchars, 16);
  158. if(codepoint <= 0x007fu) {
  159. s += static_cast<char>(codepoint);
  160. } else if(codepoint <= 0x07ffu) {
  161. unsigned char c2 = 0x80u | (codepoint & 0x003fu);
  162. unsigned char c1 = 0xC0u | (codepoint >> 6);
  163. s += c1;
  164. s += c2;
  165. } else if(in(codepoint, 0xD800u, 0xDBFFu)) {
  166. // surrogate pair
  167. if(*first != '\\' || first+1 == last ||
  168. *(first+1) != 'u') {
  169. throw DL_ABORT_EX2("JSON decoding failed: bad UTF-8 sequence.",
  170. error_code::JSON_PARSE_ERROR);
  171. }
  172. first += 2;
  173. std::string uchars;
  174. for(int i = 0; i < 4; ++i, ++first) {
  175. checkEof(first, last);
  176. uchars += *first;
  177. }
  178. checkEof(first, last);
  179. uint16_t codepoint2 = util::parseUInt(uchars, 16);
  180. if(!in(codepoint2, 0xDC00u, 0xDFFFu)) {
  181. throw DL_ABORT_EX2("JSON decoding failed: bad UTF-8 sequence.",
  182. error_code::JSON_PARSE_ERROR);
  183. }
  184. uint32_t fullcodepoint = 0x010000u;
  185. fullcodepoint += (codepoint & 0x03FFu) << 10;
  186. fullcodepoint += (codepoint2 & 0x03FFu);
  187. unsigned char c4 = 0x80u | (fullcodepoint & 0x003Fu);
  188. unsigned char c3 = 0x80u | ((fullcodepoint >> 6) & 0x003Fu);
  189. unsigned char c2 = 0x80u | ((fullcodepoint >> 12) & 0x003Fu);
  190. unsigned char c1 = 0xf0u | (fullcodepoint >> 18);
  191. s += c1;
  192. s += c2;
  193. s += c3;
  194. s += c4;
  195. } else if(codepoint <= 0xffffu) {
  196. unsigned char c3 = 0x80u | (codepoint & 0x003Fu);
  197. unsigned char c2 = 0x80u | ((codepoint >> 6) & 0x003Fu);
  198. unsigned char c1 = 0xE0u | (codepoint >> 12);
  199. s += c1;
  200. s += c2;
  201. s += c3;
  202. }
  203. offset = first;
  204. } else {
  205. if(*first == 'b') {
  206. s += '\b';
  207. } else if(*first == 'f') {
  208. s += '\f';
  209. } else if(*first == 'n') {
  210. s += '\n';
  211. } else if(*first == 'r') {
  212. s += '\r';
  213. } else if(*first == 't') {
  214. s += '\t';
  215. } else {
  216. s += *first;
  217. }
  218. ++first;
  219. offset = first;
  220. }
  221. } else {
  222. ++first;
  223. }
  224. }
  225. checkEof(first, last);
  226. if(std::distance(offset, first) > 0) {
  227. s += std::string(offset, first);
  228. }
  229. if(!util::isUtf8(s)) {
  230. throw DL_ABORT_EX2("JSON decoding failed: Non UTF-8 string.",
  231. error_code::JSON_PARSE_ERROR);
  232. }
  233. ++first;
  234. return std::make_pair(String::g(s), first);
  235. }
  236. } // namespace
  237. namespace {
  238. void checkEmptyDigit
  239. (std::string::const_iterator first,
  240. std::string::const_iterator last)
  241. {
  242. if(std::distance(first, last) == 0) {
  243. throw DL_ABORT_EX2("JSON decoding failed: zero DIGIT.",
  244. error_code::JSON_PARSE_ERROR);
  245. }
  246. }
  247. } // namespace
  248. namespace {
  249. void checkLeadingZero
  250. (std::string::const_iterator first,
  251. std::string::const_iterator last)
  252. {
  253. if(std::distance(first, last) > 2 && *first == '0') {
  254. throw DL_ABORT_EX2("JSON decoding failed: leading zero.",
  255. error_code::JSON_PARSE_ERROR);
  256. }
  257. }
  258. } // namespace
  259. namespace {
  260. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  261. decodeNumber
  262. (std::string::const_iterator first,
  263. std::string::const_iterator last)
  264. {
  265. std::string s;
  266. if(*first == '-') {
  267. s += *first;
  268. ++first;
  269. }
  270. std::string::const_iterator offset = first;
  271. while(first != last && in(*first, '0', '9')) {
  272. ++first;
  273. }
  274. checkEof(first, last);
  275. checkEmptyDigit(offset, first);
  276. checkLeadingZero(offset, first);
  277. s += std::string(offset, first);
  278. bool fp = false;
  279. if(*first == '.') {
  280. fp = true;
  281. s += *first;
  282. ++first;
  283. offset = first;
  284. while(first != last && in(*first, '0', '9')) {
  285. ++first;
  286. }
  287. checkEof(first, last);
  288. checkEmptyDigit(offset, first);
  289. s += std::string(offset, first);
  290. }
  291. if(*first == 'e') {
  292. fp = true;
  293. s += *first;
  294. ++first;
  295. checkEof(first, last);
  296. if(*first == '+' || *first == '-') {
  297. s += *first;
  298. ++first;
  299. }
  300. offset = first;
  301. while(first != last && in(*first, '0', '9')) {
  302. ++first;
  303. }
  304. checkEof(first, last);
  305. checkEmptyDigit(offset, first);
  306. s += std::string(offset, first);
  307. }
  308. if(fp) {
  309. // Since we don't have floating point coutner part in ValueBase,
  310. // we just treat it as string.
  311. return std::make_pair(String::g(s), first);
  312. } else {
  313. Integer::ValueType val = util::parseLLInt(s);
  314. return std::make_pair(Integer::g(val), first);
  315. }
  316. }
  317. } // namespace
  318. namespace {
  319. void checkDepth(size_t depth)
  320. {
  321. if(depth >= MAX_STRUCTURE_DEPTH) {
  322. throw DL_ABORT_EX2("JSON decoding failed: Structure is too deep.",
  323. error_code::JSON_PARSE_ERROR);
  324. }
  325. }
  326. } // namespace
  327. namespace {
  328. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  329. decodeArray
  330. (std::string::const_iterator first,
  331. std::string::const_iterator last,
  332. size_t depth)
  333. {
  334. checkDepth(depth);
  335. SharedHandle<List> list = List::g();
  336. // Consume first char, assuming it is '['.
  337. ++first;
  338. first = skipWs(first, last);
  339. checkEof(first, last);
  340. if(*first != ']') {
  341. while(1) {
  342. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  343. r = decode(first, last, depth);
  344. list->append(r.first);
  345. first = r.second;
  346. first = skipWs(first, last);
  347. if(first == last || (*first != ',' && *first != ']')) {
  348. throw DL_ABORT_EX2("JSON decoding failed:"
  349. " value-separator ',' or ']' is not found.",
  350. error_code::JSON_PARSE_ERROR);
  351. }
  352. if(*first == ']') {
  353. break;
  354. }
  355. ++first;
  356. }
  357. }
  358. ++first;
  359. return std::make_pair(list, first);
  360. }
  361. } // namespace
  362. namespace {
  363. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  364. decodeObject
  365. (std::string::const_iterator first,
  366. std::string::const_iterator last,
  367. size_t depth)
  368. {
  369. checkDepth(depth);
  370. SharedHandle<Dict> dict = Dict::g();
  371. // Consume first char, assuming it is '{'
  372. ++first;
  373. first = skipWs(first, last);
  374. checkEof(first, last);
  375. if(*first != '}') {
  376. while(1) {
  377. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  378. keyRet = decodeString(first, last);
  379. first = keyRet.second;
  380. first = skipWs(first, last);
  381. if(first == last || *first != ':') {
  382. throw DL_ABORT_EX2("JSON decoding failed:"
  383. " name-separator ':' is not found.",
  384. error_code::JSON_PARSE_ERROR);
  385. }
  386. ++first;
  387. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  388. valueRet = decode(first, last, depth);
  389. dict->put(asString(keyRet.first)->s(), valueRet.first);
  390. first = valueRet.second;
  391. first = skipWs(first, last);
  392. if(first == last || (*first != ',' && *first != '}')) {
  393. throw DL_ABORT_EX2("JSON decoding failed:"
  394. " value-separator ',' or '}' is not found.",
  395. error_code::JSON_PARSE_ERROR);
  396. }
  397. if(*first == '}') {
  398. break;
  399. }
  400. ++first;
  401. first = skipWs(first, last);
  402. checkEof(first, last);
  403. }
  404. }
  405. ++first;
  406. return std::make_pair(dict, first);
  407. }
  408. } // namespace
  409. namespace {
  410. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  411. decode
  412. (std::string::const_iterator first,
  413. std::string::const_iterator last,
  414. size_t depth)
  415. {
  416. first = skipWs(first, last);
  417. if(first == last) {
  418. throw DL_ABORT_EX2("JSON decoding failed:"
  419. " Unexpected EOF in term context.",
  420. error_code::JSON_PARSE_ERROR);
  421. }
  422. if(*first == '[') {
  423. return decodeArray(first, last, depth+1);
  424. } else if(*first == '{') {
  425. return decodeObject(first, last, depth+1);
  426. } else if(*first == '"') {
  427. return decodeString(first, last);
  428. } else if(*first == '-' || in(*first, '0', '9')) {
  429. return decodeNumber(first, last);
  430. } else if(*first == 't') {
  431. return decodeTrue(first, last);
  432. } else if(*first == 'f') {
  433. return decodeFalse(first, last);
  434. } else if(*first == 'n') {
  435. return decodeNull(first, last);
  436. } else {
  437. throw DL_ABORT_EX2("JSON decoding failed:"
  438. " Unexpected character in term context.",
  439. error_code::JSON_PARSE_ERROR);
  440. }
  441. }
  442. } // namespace
  443. SharedHandle<ValueBase> decode(const std::string& json)
  444. {
  445. std::string::const_iterator first = json.begin();
  446. std::string::const_iterator last = json.end();
  447. first = skipWs(first, last);
  448. if(first == last) {
  449. throw DL_ABORT_EX2("JSON decoding failed:"
  450. " Unexpected EOF in term context.",
  451. error_code::JSON_PARSE_ERROR);
  452. }
  453. std::pair<SharedHandle<ValueBase>, std::string::const_iterator> r;
  454. if(*first == '[') {
  455. r = decodeArray(first, last, 1);
  456. } else if(*first == '{') {
  457. r = decodeObject(first, last, 1);
  458. } else {
  459. throw DL_ABORT_EX2("JSON decoding failed:"
  460. " Unexpected EOF in term context.",
  461. error_code::JSON_PARSE_ERROR);
  462. }
  463. return r.first;
  464. }
  465. std::string jsonEscape(const std::string& s)
  466. {
  467. std::string t;
  468. for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi;
  469. ++i) {
  470. if(*i == '"' || *i == '\\' || *i == '/') {
  471. t += '\\';
  472. t += *i;
  473. } else if(*i == '\b') {
  474. t += "\\b";
  475. } else if(*i == '\f') {
  476. t += "\\f";
  477. } else if(*i == '\n') {
  478. t += "\\n";
  479. } else if(*i == '\r') {
  480. t += "\\r";
  481. } else if(*i == '\t') {
  482. t += "\\t";
  483. } else if(in(static_cast<unsigned char>(*i), 0x00u, 0x1Fu)) {
  484. t += "\\u00";
  485. char temp[3];
  486. temp[2] = '\0';
  487. temp[0] = (*i >> 4);
  488. temp[1] = (*i)&0x0Fu;
  489. for(int j = 0; j < 2; ++j) {
  490. if(temp[j] < 10) {
  491. temp[j] += '0';
  492. } else {
  493. temp[j] += 'A'-10;
  494. }
  495. }
  496. t += temp;
  497. } else {
  498. t += *i;
  499. }
  500. }
  501. return t;
  502. }
  503. std::string encode(const ValueBase* vlb)
  504. {
  505. class JsonValueBaseVisitor:public ValueBaseVisitor {
  506. private:
  507. std::ostringstream out_;
  508. public:
  509. virtual void visit(const String& string)
  510. {
  511. const std::string& s = string.s();
  512. std::string t = jsonEscape(s);
  513. out_ << '"';
  514. out_.write(t.data(), t.size());
  515. out_ << '"';
  516. }
  517. virtual void visit(const Integer& integer)
  518. {
  519. out_ << integer.i();
  520. }
  521. virtual void visit(const Bool& boolValue)
  522. {
  523. out_ << (boolValue.val() ? "true" : "false");
  524. }
  525. virtual void visit(const Null& nullValue)
  526. {
  527. out_ << "null";
  528. }
  529. virtual void visit(const List& list)
  530. {
  531. out_ << '[';
  532. List::ValueType::const_iterator i = list.begin();
  533. if(!list.empty()) {
  534. (*i)->accept(*this);
  535. }
  536. ++i;
  537. for(List::ValueType::const_iterator eoi = list.end(); i != eoi; ++i){
  538. out_ << ',';
  539. (*i)->accept(*this);
  540. }
  541. out_ << ']';
  542. }
  543. virtual void visit(const Dict& dict)
  544. {
  545. out_ << '{';
  546. Dict::ValueType::const_iterator i = dict.begin();
  547. if(!dict.empty()) {
  548. std::string key = jsonEscape((*i).first);
  549. out_ << '"';
  550. out_.write(key.data(), key.size());
  551. out_ << "\":";
  552. (*i).second->accept(*this);
  553. }
  554. ++i;
  555. for(Dict::ValueType::const_iterator eoi = dict.end(); i != eoi; ++i){
  556. out_ << ',';
  557. std::string key = jsonEscape((*i).first);
  558. out_ << '"';
  559. out_.write(key.data(), key.size());
  560. out_ << "\":";
  561. (*i).second->accept(*this);
  562. }
  563. out_ << '}';
  564. }
  565. std::string getResult() const
  566. {
  567. return out_.str();
  568. }
  569. };
  570. JsonValueBaseVisitor visitor;
  571. vlb->accept(visitor);
  572. return visitor.getResult();
  573. }
  574. // Serializes JSON object or array.
  575. std::string encode(const SharedHandle<ValueBase>& json)
  576. {
  577. std::ostringstream out;
  578. return encode(out, json.get()).str();
  579. }
  580. JsonGetParam::JsonGetParam
  581. (const std::string& request, const std::string& callback)
  582. : request(request), callback(callback)
  583. {}
  584. JsonGetParam
  585. decodeGetParams(const std::string& query)
  586. {
  587. std::string jsonRequest;
  588. std::string callback;
  589. if(!query.empty() && query[0] == '?') {
  590. std::string method;
  591. std::string id;
  592. std::string params;
  593. std::vector<std::string> getParams;
  594. util::split(query.substr(1), std::back_inserter(getParams), "&");
  595. for(std::vector<std::string>::const_iterator i =
  596. getParams.begin(), eoi = getParams.end(); i != eoi; ++i) {
  597. if(util::startsWith(*i, "method=")) {
  598. method = (*i).substr(7);
  599. } else if(util::startsWith(*i, "id=")) {
  600. id = (*i).substr(3);
  601. } else if(util::startsWith(*i, "params=")) {
  602. params = (*i).substr(7);
  603. } else if(util::startsWith(*i, "jsoncallback=")) {
  604. callback = (*i).substr(13);
  605. }
  606. }
  607. std::string jsonParam =
  608. Base64::decode(util::percentDecode(params));
  609. if(method.empty() && id.empty()) {
  610. // Assume batch call.
  611. jsonRequest = jsonParam;
  612. } else {
  613. jsonRequest = '{';
  614. if(!method.empty()) {
  615. strappend(jsonRequest, "\"method\":\"", method, "\"");
  616. }
  617. if(!id.empty()) {
  618. strappend(jsonRequest, ",\"id\":\"", id, "\"");
  619. }
  620. if(!params.empty()) {
  621. strappend(jsonRequest, ",\"params\":", jsonParam);
  622. }
  623. jsonRequest += '}';
  624. }
  625. }
  626. return JsonGetParam(jsonRequest, callback);
  627. }
  628. } // namespace json
  629. } // namespace aria2