The sad state of Bitcoin code
There's been discussion on this topic for many years now, and a solid consensus in the Republic on the matter. Yet it never ceases to shock and disturb :
mircea_popescu unsigned char pchSig[10000]; // Can anyone explain why 10`000 ? Enough with the magic numbers already. 0)
./bitcoinrpc.cpp- {
./bitcoinrpc.cpp- if (!pwalletMain->Unlock(strWalletPass))
./bitcoinrpc.cpp: throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
./bitcoinrpc.cpp- }
--
./bitcoinrpc.cpp- if (!pwalletMain->IsCrypted())
./bitcoinrpc.cpp: throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
./bitcoinrpc.cpp-
./bitcoinrpc.cpp- // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
./bitcoinrpc.cpp: // Alternately, find a way to make params[0] mlock()'d to begin with.
./bitcoinrpc.cpp- SecureString strOldWalletPass;
./bitcoinrpc.cpp: strOldWalletPass.reserve(100);
./bitcoinrpc.cpp: strOldWalletPass = params[0].get_str().c_str();
./bitcoinrpc.cpp-
./bitcoinrpc.cpp- SecureString strNewWalletPass;
./bitcoinrpc.cpp: strNewWalletPass.reserve(100);
./bitcoinrpc.cpp: strNewWalletPass = params[1].get_str().c_str();
./bitcoinrpc.cpp-
./bitcoinrpc.cpp: if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
./bitcoinrpc.cpp- throw runtime_error(
--
./bitcoinrpc.cpp- if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
./bitcoinrpc.cpp: throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
./bitcoinrpc.cpp-
--
./bitcoinrpc.cpp- if (!pwalletMain->IsCrypted())
./bitcoinrpc.cpp: throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
./bitcoinrpc.cpp-
--
./bitcoinrpc.cpp- if (pwalletMain->IsCrypted())
./bitcoinrpc.cpp: throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called.");
./bitcoinrpc.cpp-
./bitcoinrpc.cpp- // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
./bitcoinrpc.cpp: // Alternately, find a way to make params[0] mlock()'d to begin with.
./bitcoinrpc.cpp- SecureString strWalletPass;
./bitcoinrpc.cpp: strWalletPass.reserve(100);
./bitcoinrpc.cpp: strWalletPass = params[0].get_str().c_str();
--
./bitcoinrpc.cpp- if (!pwalletMain->EncryptWallet(strWalletPass))
./bitcoinrpc.cpp: throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
./bitcoinrpc.cpp-
--
./bitcoinrpc.cpp- if (vNodes.empty())
./bitcoinrpc.cpp: throw JSONRPCError(-9, "Bitcoin is not connected!");
./bitcoinrpc.cpp-
./bitcoinrpc.cpp- if (IsInitialBlockDownload())
./bitcoinrpc.cpp: throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
--
./bitcoinrpc.cpp- if (pindexPrev != pindexBest ||
./bitcoinrpc.cpp: (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
./bitcoinrpc.cpp- {
--
./bitcoinrpc.cpp- if (!pblock)
./bitcoinrpc.cpp: throw JSONRPCError(-7, "Out of memory");
./bitcoinrpc.cpp- vNewBlock.push_back(pblock);
--
./bitcoinrpc.cpp- // Prebuild hash buffers
./bitcoinrpc.cpp: char pmidstate[32];
./bitcoinrpc.cpp: char pdata[128];
./bitcoinrpc.cpp: char phash1[64];
./bitcoinrpc.cpp: FormatHashBuffers(pblock, pmidstate, pdata, phash1);
--
./bitcoinrpc.cpp- // Parse parameters
./bitcoinrpc.cpp: vector vchData = ParseHex(params[0].get_str());
./bitcoinrpc.cpp: if (vchData.size() != 128)
./bitcoinrpc.cpp: throw JSONRPCError(-8, "Invalid parameter");
./bitcoinrpc.cpp: CBlock* pdata = (CBlock*)&vchData[0];
./bitcoinrpc.cpp-
./bitcoinrpc.cpp- // Byte reverse
./bitcoinrpc.cpp: for (int i = 0; i < 128/4; i++)
./bitcoinrpc.cpp- ( (unsigned int*)pdata)[i] = ByteReverse( ( (unsigned int*)pdata)[i]);
--
./bitcoinrpc.cpp- if (vNodes.empty())
./bitcoinrpc.cpp: throw JSONRPCError(-9, "Bitcoin is not connected!");
./bitcoinrpc.cpp-
./bitcoinrpc.cpp- if (IsInitialBlockDownload())
./bitcoinrpc.cpp: throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
./bitcoinrpc.cpp-
--
./bitcoinrpc.cpp- if (!pblock)
./bitcoinrpc.cpp: throw JSONRPCError(-7, "Out of memory");
./bitcoinrpc.cpp- }
--
./bitcoinrpc.cpp-
./bitcoinrpc.cpp:string rfc1123Time()
./bitcoinrpc.cpp-{
./bitcoinrpc.cpp: char buffer[64];
./bitcoinrpc.cpp- time_t now;
--
./bitcoinrpc.cpp-{
./bitcoinrpc.cpp: if (nStatus == 401)
./bitcoinrpc.cpp: return strprintf("HTTP/1.0 401 Authorization Required\r\n"
./bitcoinrpc.cpp- "Date: %s\r\n"
--
./bitcoinrpc.cpp- "Content-Type: text/html\r\n"
./bitcoinrpc.cpp: "Content-Length: 296\r\n"
./bitcoinrpc.cpp- "\r\n"
./bitcoinrpc.cpp: "\r\n"
./bitcoinrpc.cpp- "\r\n"
--
./bitcoinrpc.cpp- "Error\r\n"
./bitcoinrpc.cpp: "\r\n"
./bitcoinrpc.cpp- "\r\n"
./bitcoinrpc.cpp: "401 Unauthorized.\r\n"
./bitcoinrpc.cpp: "\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
./bitcoinrpc.cpp- const char *cStatus;
./bitcoinrpc.cpp: if (nStatus == 200) cStatus = "OK";
./bitcoinrpc.cpp: else if (nStatus == 400) cStatus = "Bad Request";
./bitcoinrpc.cpp: else if (nStatus == 403) cStatus = "Forbidden";
./bitcoinrpc.cpp: else if (nStatus == 404) cStatus = "Not Found";
./bitcoinrpc.cpp: else if (nStatus == 500) cStatus = "Internal Server Error";
./bitcoinrpc.cpp- else cStatus = "";
./bitcoinrpc.cpp- return strprintf(
./bitcoinrpc.cpp: "HTTP/1.1 %d %s\r\n"
./bitcoinrpc.cpp- "Date: %s\r\n"
--
./bitcoinrpc.cpp- boost::split(vWords, str, boost::is_any_of(" "));
./bitcoinrpc.cpp: if (vWords.size() < 2)
./bitcoinrpc.cpp: return 500;
./bitcoinrpc.cpp: return atoi(vWords[1].c_str());
./bitcoinrpc.cpp-}
--
./bitcoinrpc.cpp- int nLen = ReadHTTPHeader(stream, mapHeadersRet);
./bitcoinrpc.cpp: if (nLen < 0 || nLen > MAX_SIZE)
./bitcoinrpc.cpp: return 500;
--
./bitcoinrpc.cpp- string strAuth = mapHeaders["authorization"];
./bitcoinrpc.cpp: if (strAuth.substr(0,6) != "Basic ")
./bitcoinrpc.cpp- return false;
./bitcoinrpc.cpp: string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
./bitcoinrpc.cpp: string strUserPass = DecodeBase64(strUserPass64);
./bitcoinrpc.cpp- return strUserPass == strRPCUserColonPass;
--
./bitcoinrpc.cpp-//
./bitcoinrpc.cpp:// JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
./bitcoinrpc.cpp:// but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
./bitcoinrpc.cpp-// unspecified (HTTP errors and contents of 'error').
./bitcoinrpc.cpp-//
./bitcoinrpc.cpp:// 1.0 spec: http://json-rpc.org/wiki/specification
./bitcoinrpc.cpp:// 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http
./bitcoinrpc.cpp-// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
--
./bitcoinrpc.cpp- // Send error reply from json-rpc error object
./bitcoinrpc.cpp: int nStatus = 500;
./bitcoinrpc.cpp- int code = find_value(objError, "code").get_int();
./bitcoinrpc.cpp: if (code == -32600) nStatus = 400;
./bitcoinrpc.cpp: else if (code == -32601) nStatus = 404;
./bitcoinrpc.cpp- string strReply = JSONRPCReply(Value::null, objError, id);
--
./bitcoinrpc.cpp- {
./bitcoinrpc.cpp: vnThreadsRunning[4]++;
./bitcoinrpc.cpp: ThreadRPCServer2(parg);
./bitcoinrpc.cpp: vnThreadsRunning[4]--;
./bitcoinrpc.cpp- }
./bitcoinrpc.cpp- catch (std::exception& e) {
./bitcoinrpc.cpp: vnThreadsRunning[4]--;
./bitcoinrpc.cpp- PrintException(&e, "ThreadRPCServer()");
./bitcoinrpc.cpp- } catch (...) {
./bitcoinrpc.cpp: vnThreadsRunning[4]--;
./bitcoinrpc.cpp- PrintException(NULL, "ThreadRPCServer()");
--
./bitcoinrpc.cpp- {
./bitcoinrpc.cpp: unsigned char rand_pwd[32];
./bitcoinrpc.cpp: RAND_bytes(rand_pwd, 32);
./bitcoinrpc.cpp- string strWhatAmI = "To use bitcoind";
--
./bitcoinrpc.cpp- GetConfigFile().c_str(),
./bitcoinrpc.cpp: EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str());
./bitcoinrpc.cpp- CreateThread(Shutdown, NULL);
--
./bitcoinrpc.cpp-
./bitcoinrpc.cpp: asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
./bitcoinrpc.cpp-
./bitcoinrpc.cpp- asio::io_service io_service;
./bitcoinrpc.cpp: ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
./bitcoinrpc.cpp- ip::tcp::acceptor acceptor(io_service, endpoint);
--
./bitcoinrpc.cpp- ip::tcp::endpoint peer;
./bitcoinrpc.cpp: vnThreadsRunning[4]--;
./bitcoinrpc.cpp- acceptor.accept(*stream.rdbuf(), peer);
./bitcoinrpc.cpp: vnThreadsRunning[4]++;
./bitcoinrpc.cpp- if (fShutdown)
--
./bitcoinrpc.cpp- // snipsnipsnip
./bitcoinrpc.cpp: // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
./bitcoinrpc.cpp- //if (!fUseSSL)
./bitcoinrpc.cpp: stream
Thursday, 21 January, Year 8 d.Tr.