json.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  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.append(offset, first);
  147. ++first;
  148. checkEof(first, last);
  149. if(*first == 'u') {
  150. ++first;
  151. std::string::const_iterator uchars = first;
  152. for(int i = 0; i < 4; ++i, ++first) {
  153. checkEof(first, last);
  154. }
  155. checkEof(first, last);
  156. uint16_t codepoint = util::parseUInt(uchars, first, 16);
  157. if(codepoint <= 0x007fu) {
  158. s += static_cast<char>(codepoint);
  159. } else if(codepoint <= 0x07ffu) {
  160. unsigned char c2 = 0x80u | (codepoint & 0x003fu);
  161. unsigned char c1 = 0xC0u | (codepoint >> 6);
  162. s += c1;
  163. s += c2;
  164. } else if(in(codepoint, 0xD800u, 0xDBFFu)) {
  165. // surrogate pair
  166. if(*first != '\\' || first+1 == last ||
  167. *(first+1) != 'u') {
  168. throw DL_ABORT_EX2("JSON decoding failed: bad UTF-8 sequence.",
  169. error_code::JSON_PARSE_ERROR);
  170. }
  171. first += 2;
  172. std::string::const_iterator uchars = first;
  173. for(int i = 0; i < 4; ++i, ++first) {
  174. checkEof(first, last);
  175. }
  176. checkEof(first, last);
  177. uint16_t codepoint2 = util::parseUInt(uchars, first, 16);
  178. if(!in(codepoint2, 0xDC00u, 0xDFFFu)) {
  179. throw DL_ABORT_EX2("JSON decoding failed: bad UTF-8 sequence.",
  180. error_code::JSON_PARSE_ERROR);
  181. }
  182. uint32_t fullcodepoint = 0x010000u;
  183. fullcodepoint += (codepoint & 0x03FFu) << 10;
  184. fullcodepoint += (codepoint2 & 0x03FFu);
  185. unsigned char c4 = 0x80u | (fullcodepoint & 0x003Fu);
  186. unsigned char c3 = 0x80u | ((fullcodepoint >> 6) & 0x003Fu);
  187. unsigned char c2 = 0x80u | ((fullcodepoint >> 12) & 0x003Fu);
  188. unsigned char c1 = 0xf0u | (fullcodepoint >> 18);
  189. s += c1;
  190. s += c2;
  191. s += c3;
  192. s += c4;
  193. } else {
  194. unsigned char c3 = 0x80u | (codepoint & 0x003Fu);
  195. unsigned char c2 = 0x80u | ((codepoint >> 6) & 0x003Fu);
  196. unsigned char c1 = 0xE0u | (codepoint >> 12);
  197. s += c1;
  198. s += c2;
  199. s += c3;
  200. }
  201. offset = first;
  202. } else {
  203. if(*first == 'b') {
  204. s += '\b';
  205. } else if(*first == 'f') {
  206. s += '\f';
  207. } else if(*first == 'n') {
  208. s += '\n';
  209. } else if(*first == 'r') {
  210. s += '\r';
  211. } else if(*first == 't') {
  212. s += '\t';
  213. } else {
  214. s += *first;
  215. }
  216. ++first;
  217. offset = first;
  218. }
  219. } else {
  220. ++first;
  221. }
  222. }
  223. checkEof(first, last);
  224. if(std::distance(offset, first) > 0) {
  225. s.append(offset, first);
  226. }
  227. if(!util::isUtf8(s)) {
  228. throw DL_ABORT_EX2("JSON decoding failed: Non UTF-8 string.",
  229. error_code::JSON_PARSE_ERROR);
  230. }
  231. ++first;
  232. return std::make_pair(String::g(s), first);
  233. }
  234. } // namespace
  235. namespace {
  236. void checkEmptyDigit
  237. (std::string::const_iterator first,
  238. std::string::const_iterator last)
  239. {
  240. if(std::distance(first, last) == 0) {
  241. throw DL_ABORT_EX2("JSON decoding failed: zero DIGIT.",
  242. error_code::JSON_PARSE_ERROR);
  243. }
  244. }
  245. } // namespace
  246. namespace {
  247. void checkLeadingZero
  248. (std::string::const_iterator first,
  249. std::string::const_iterator last)
  250. {
  251. if(std::distance(first, last) > 2 && *first == '0') {
  252. throw DL_ABORT_EX2("JSON decoding failed: leading zero.",
  253. error_code::JSON_PARSE_ERROR);
  254. }
  255. }
  256. } // namespace
  257. namespace {
  258. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  259. decodeNumber
  260. (std::string::const_iterator first,
  261. std::string::const_iterator last)
  262. {
  263. std::string s;
  264. if(*first == '-') {
  265. s += *first;
  266. ++first;
  267. }
  268. std::string::const_iterator offset = first;
  269. while(first != last && in(*first, '0', '9')) {
  270. ++first;
  271. }
  272. checkEof(first, last);
  273. checkEmptyDigit(offset, first);
  274. checkLeadingZero(offset, first);
  275. s.append(offset, first);
  276. bool fp = false;
  277. if(*first == '.') {
  278. fp = true;
  279. s += *first;
  280. ++first;
  281. offset = first;
  282. while(first != last && in(*first, '0', '9')) {
  283. ++first;
  284. }
  285. checkEof(first, last);
  286. checkEmptyDigit(offset, first);
  287. s.append(offset, first);
  288. }
  289. if(*first == 'e') {
  290. fp = true;
  291. s += *first;
  292. ++first;
  293. checkEof(first, last);
  294. if(*first == '+' || *first == '-') {
  295. s += *first;
  296. ++first;
  297. }
  298. offset = first;
  299. while(first != last && in(*first, '0', '9')) {
  300. ++first;
  301. }
  302. checkEof(first, last);
  303. checkEmptyDigit(offset, first);
  304. s.append(offset, first);
  305. }
  306. if(fp) {
  307. // Since we don't have floating point coutner part in ValueBase,
  308. // we just treat it as string.
  309. return std::make_pair(String::g(s), first);
  310. } else {
  311. Integer::ValueType val = util::parseLLInt(s.begin(), s.end());
  312. return std::make_pair(Integer::g(val), first);
  313. }
  314. }
  315. } // namespace
  316. namespace {
  317. void checkDepth(size_t depth)
  318. {
  319. if(depth >= MAX_STRUCTURE_DEPTH) {
  320. throw DL_ABORT_EX2("JSON decoding failed: Structure is too deep.",
  321. error_code::JSON_PARSE_ERROR);
  322. }
  323. }
  324. } // namespace
  325. namespace {
  326. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  327. decodeArray
  328. (std::string::const_iterator first,
  329. std::string::const_iterator last,
  330. size_t depth)
  331. {
  332. checkDepth(depth);
  333. SharedHandle<List> list = List::g();
  334. // Consume first char, assuming it is '['.
  335. ++first;
  336. first = skipWs(first, last);
  337. checkEof(first, last);
  338. if(*first != ']') {
  339. while(1) {
  340. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  341. r = decode(first, last, depth);
  342. list->append(r.first);
  343. first = r.second;
  344. first = skipWs(first, last);
  345. if(first == last || (*first != ',' && *first != ']')) {
  346. throw DL_ABORT_EX2("JSON decoding failed:"
  347. " value-separator ',' or ']' is not found.",
  348. error_code::JSON_PARSE_ERROR);
  349. }
  350. if(*first == ']') {
  351. break;
  352. }
  353. ++first;
  354. }
  355. }
  356. ++first;
  357. return std::make_pair(list, first);
  358. }
  359. } // namespace
  360. namespace {
  361. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  362. decodeObject
  363. (std::string::const_iterator first,
  364. std::string::const_iterator last,
  365. size_t depth)
  366. {
  367. checkDepth(depth);
  368. SharedHandle<Dict> dict = Dict::g();
  369. // Consume first char, assuming it is '{'
  370. ++first;
  371. first = skipWs(first, last);
  372. checkEof(first, last);
  373. if(*first != '}') {
  374. while(1) {
  375. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  376. keyRet = decodeString(first, last);
  377. first = keyRet.second;
  378. first = skipWs(first, last);
  379. if(first == last || *first != ':') {
  380. throw DL_ABORT_EX2("JSON decoding failed:"
  381. " name-separator ':' is not found.",
  382. error_code::JSON_PARSE_ERROR);
  383. }
  384. ++first;
  385. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  386. valueRet = decode(first, last, depth);
  387. dict->put(downcast<String>(keyRet.first)->s(), valueRet.first);
  388. first = valueRet.second;
  389. first = skipWs(first, last);
  390. if(first == last || (*first != ',' && *first != '}')) {
  391. throw DL_ABORT_EX2("JSON decoding failed:"
  392. " value-separator ',' or '}' is not found.",
  393. error_code::JSON_PARSE_ERROR);
  394. }
  395. if(*first == '}') {
  396. break;
  397. }
  398. ++first;
  399. first = skipWs(first, last);
  400. checkEof(first, last);
  401. }
  402. }
  403. ++first;
  404. return std::make_pair(dict, first);
  405. }
  406. } // namespace
  407. namespace {
  408. std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
  409. decode
  410. (std::string::const_iterator first,
  411. std::string::const_iterator last,
  412. size_t depth)
  413. {
  414. first = skipWs(first, last);
  415. if(first == last) {
  416. throw DL_ABORT_EX2("JSON decoding failed:"
  417. " Unexpected EOF in term context.",
  418. error_code::JSON_PARSE_ERROR);
  419. }
  420. if(*first == '[') {
  421. return decodeArray(first, last, depth+1);
  422. } else if(*first == '{') {
  423. return decodeObject(first, last, depth+1);
  424. } else if(*first == '"') {
  425. return decodeString(first, last);
  426. } else if(*first == '-' || in(*first, '0', '9')) {
  427. return decodeNumber(first, last);
  428. } else if(*first == 't') {
  429. return decodeTrue(first, last);
  430. } else if(*first == 'f') {
  431. return decodeFalse(first, last);
  432. } else if(*first == 'n') {
  433. return decodeNull(first, last);
  434. } else {
  435. throw DL_ABORT_EX2("JSON decoding failed:"
  436. " Unexpected character in term context.",
  437. error_code::JSON_PARSE_ERROR);
  438. }
  439. }
  440. } // namespace
  441. SharedHandle<ValueBase> decode(const std::string& json)
  442. {
  443. std::string::const_iterator first = json.begin();
  444. std::string::const_iterator last = json.end();
  445. first = skipWs(first, last);
  446. if(first == last) {
  447. throw DL_ABORT_EX2("JSON decoding failed:"
  448. " Unexpected EOF in term context.",
  449. error_code::JSON_PARSE_ERROR);
  450. }
  451. std::pair<SharedHandle<ValueBase>, std::string::const_iterator> r;
  452. if(*first == '[') {
  453. r = decodeArray(first, last, 1);
  454. } else if(*first == '{') {
  455. r = decodeObject(first, last, 1);
  456. } else {
  457. throw DL_ABORT_EX2("JSON decoding failed:"
  458. " Unexpected EOF in term context.",
  459. error_code::JSON_PARSE_ERROR);
  460. }
  461. return r.first;
  462. }
  463. std::string jsonEscape(const std::string& s)
  464. {
  465. std::string t;
  466. for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi;
  467. ++i) {
  468. if(*i == '"' || *i == '\\' || *i == '/') {
  469. t += '\\';
  470. t += *i;
  471. } else if(*i == '\b') {
  472. t += "\\b";
  473. } else if(*i == '\f') {
  474. t += "\\f";
  475. } else if(*i == '\n') {
  476. t += "\\n";
  477. } else if(*i == '\r') {
  478. t += "\\r";
  479. } else if(*i == '\t') {
  480. t += "\\t";
  481. } else if(in(static_cast<unsigned char>(*i), 0x00u, 0x1Fu)) {
  482. t += "\\u00";
  483. char temp[3];
  484. temp[2] = '\0';
  485. temp[0] = (*i >> 4);
  486. temp[1] = (*i)&0x0Fu;
  487. for(int j = 0; j < 2; ++j) {
  488. if(temp[j] < 10) {
  489. temp[j] += '0';
  490. } else {
  491. temp[j] += 'A'-10;
  492. }
  493. }
  494. t += temp;
  495. } else {
  496. t += *i;
  497. }
  498. }
  499. return t;
  500. }
  501. std::string encode(const ValueBase* vlb)
  502. {
  503. class JsonValueBaseVisitor:public ValueBaseVisitor {
  504. private:
  505. std::ostringstream out_;
  506. public:
  507. virtual void visit(const String& string)
  508. {
  509. const std::string& s = string.s();
  510. std::string t = jsonEscape(s);
  511. out_ << '"';
  512. out_.write(t.data(), t.size());
  513. out_ << '"';
  514. }
  515. virtual void visit(const Integer& integer)
  516. {
  517. out_ << integer.i();
  518. }
  519. virtual void visit(const Bool& boolValue)
  520. {
  521. out_ << (boolValue.val() ? "true" : "false");
  522. }
  523. virtual void visit(const Null& nullValue)
  524. {
  525. out_ << "null";
  526. }
  527. virtual void visit(const List& list)
  528. {
  529. out_ << '[';
  530. List::ValueType::const_iterator i = list.begin();
  531. if(!list.empty()) {
  532. (*i)->accept(*this);
  533. }
  534. ++i;
  535. for(List::ValueType::const_iterator eoi = list.end(); i != eoi; ++i){
  536. out_ << ',';
  537. (*i)->accept(*this);
  538. }
  539. out_ << ']';
  540. }
  541. virtual void visit(const Dict& dict)
  542. {
  543. out_ << '{';
  544. Dict::ValueType::const_iterator i = dict.begin();
  545. if(!dict.empty()) {
  546. std::string key = jsonEscape((*i).first);
  547. out_ << '"';
  548. out_.write(key.data(), key.size());
  549. out_ << "\":";
  550. (*i).second->accept(*this);
  551. }
  552. ++i;
  553. for(Dict::ValueType::const_iterator eoi = dict.end(); i != eoi; ++i){
  554. out_ << ',';
  555. std::string key = jsonEscape((*i).first);
  556. out_ << '"';
  557. out_.write(key.data(), key.size());
  558. out_ << "\":";
  559. (*i).second->accept(*this);
  560. }
  561. out_ << '}';
  562. }
  563. std::string getResult() const
  564. {
  565. return out_.str();
  566. }
  567. };
  568. JsonValueBaseVisitor visitor;
  569. vlb->accept(visitor);
  570. return visitor.getResult();
  571. }
  572. // Serializes JSON object or array.
  573. std::string encode(const SharedHandle<ValueBase>& json)
  574. {
  575. std::ostringstream out;
  576. return encode(out, json.get()).str();
  577. }
  578. JsonGetParam::JsonGetParam
  579. (const std::string& request, const std::string& callback)
  580. : request(request), callback(callback)
  581. {}
  582. JsonGetParam
  583. decodeGetParams(const std::string& query)
  584. {
  585. std::string jsonRequest;
  586. std::string callback;
  587. if(!query.empty() && query[0] == '?') {
  588. Scip method;
  589. Scip id;
  590. Scip params;
  591. std::vector<Scip> getParams;
  592. util::splitIter(query.begin()+1, query.end(), std::back_inserter(getParams),
  593. '&');
  594. const char A2_METHOD[] = "method=";
  595. const char A2_ID[] = "id=";
  596. const char A2_PARAMS[] = "params=";
  597. const char A2_JSONCB[] = "jsoncallback=";
  598. for(std::vector<Scip>::const_iterator i =
  599. getParams.begin(), eoi = getParams.end(); i != eoi; ++i) {
  600. if(util::startsWith((*i).first, (*i).second,
  601. A2_METHOD, vend(A2_METHOD)-1)) {
  602. method.first = (*i).first+7;
  603. method.second = (*i).second;
  604. } else if(util::startsWith((*i).first, (*i).second,
  605. A2_ID, vend(A2_ID)-1)) {
  606. id.first = (*i).first+3;
  607. id.second = (*i).second;
  608. } else if(util::startsWith((*i).first, (*i).second,
  609. A2_PARAMS, vend(A2_PARAMS)-1)) {
  610. params.first = (*i).first+7;
  611. params.second = (*i).second;
  612. } else if(util::startsWith((*i).first, (*i).second,
  613. A2_JSONCB, vend(A2_JSONCB)-1)) {
  614. callback.assign((*i).first+13, (*i).second);
  615. }
  616. }
  617. std::string jsonParam =
  618. Base64::decode(util::percentDecode(params.first, params.second));
  619. if(method.first == method.second && id.first == id.second) {
  620. // Assume batch call.
  621. jsonRequest = jsonParam;
  622. } else {
  623. jsonRequest = '{';
  624. if(method.first != method.second) {
  625. jsonRequest += "\"method\":\"";
  626. jsonRequest.append(method.first, method.second);
  627. jsonRequest += '"';
  628. }
  629. if(id.first != id.second) {
  630. jsonRequest += ",\"id\":\"";
  631. jsonRequest.append(id.first, id.second);
  632. jsonRequest += '"';
  633. }
  634. if(params.first != params.second) {
  635. jsonRequest += ",\"params\":";
  636. jsonRequest += jsonParam;
  637. }
  638. jsonRequest += '}';
  639. }
  640. }
  641. return JsonGetParam(jsonRequest, callback);
  642. }
  643. } // namespace json
  644. } // namespace aria2