diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index 420c6c4bacf17b..861537ce212e11 100644 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -55,15 +55,16 @@ void checkBudgetInputs(const UniValue& params, std::string &strProposalName, std CBlockIndex* pindexPrev = chainActive.Tip(); if (strProposalName.size() > 20) - throw std::runtime_error("Invalid proposal name, limit of 20 characters."); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid proposal name, limit of 20 characters."); strURL = SanitizeString(params[1].get_str()); - if (strURL.size() > 64) - throw std::runtime_error("Invalid url, limit of 64 characters."); + std::string strErr; + if (!validateURL(strURL, strErr)) + throw JSONRPCError(RPC_INVALID_PARAMETER, strErr); nPaymentCount = params[2].get_int(); if (nPaymentCount < 1) - throw std::runtime_error("Invalid payment count, must be more than zero."); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid payment count, must be more than zero."); // Start must be in the next budget cycle if (pindexPrev != NULL) nBlockMin = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetBudgetCycleBlocks() + Params().GetBudgetCycleBlocks(); @@ -71,16 +72,16 @@ void checkBudgetInputs(const UniValue& params, std::string &strProposalName, std nBlockStart = params[3].get_int(); if (nBlockStart % Params().GetBudgetCycleBlocks() != 0) { int nNext = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetBudgetCycleBlocks() + Params().GetBudgetCycleBlocks(); - throw std::runtime_error(strprintf("Invalid block start - must be a budget cycle block. Next valid block: %d", nNext)); + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid block start - must be a budget cycle block. Next valid block: %d", nNext)); } int nBlockEnd = nBlockStart + (Params().GetBudgetCycleBlocks() * nPaymentCount); // End must be AFTER current cycle if (nBlockStart < nBlockMin) - throw std::runtime_error("Invalid block start, must be more than current height."); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block start, must be more than current height."); if (nBlockEnd < pindexPrev->nHeight) - throw std::runtime_error("Invalid ending block, starting block + (payment_cycle*payments) must be more than current height."); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid ending block, starting block + (payment_cycle*payments) must be more than current height."); address = params[4].get_str(); if (!address.IsValid()) diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 16fd87aa4f3d5b..41ee86c954a668 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -39,6 +39,46 @@ std::string SanitizeString(const std::string& str, int rule) return strResult; } +/* +** bool validateURL(std::string, int [optional, defaulted to 64]) +** +** Input: +** strURL: A std::string URL to be be processed for validity. +** strErr: A std::string to be filled with any error messages. +** maxSize: An int to define the maximum size the URL can be; +** Optional, defaulting to 64. +** +** Return: +** boolean true|false result if the validation passes. +** strRrror: Filled with any error messages. +*/ +bool validateURL(std::string strURL, std::string& strErr, unsigned int maxSize) { + + // Check URL size + if (strURL.size() > maxSize) { + strErr = strprintf("Invalid URL: %d exceeds limit of %d characters.", strURL.size(), maxSize); + return false; + } + + std::vector reqPre; + + // Required initial strings; URL must contain one + reqPre.push_back("http://"); + reqPre.push_back("https://"); + + // check fronts + bool found = false; + for (int i=0; i < reqPre.size() && !found; i++) { + if (strURL.find(reqPre[i]) == 0) found = true; + } + if ((!found) && (reqPre.size() > 0)) { + strErr = "Invalid URL, check scheme (e.g. https://)"; + return false; + } + + return true; +} + const signed char p_util_hexdigit[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 97c3bfd91fbc93..5f7dfbc120ee80 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -40,6 +40,7 @@ enum SafeChars * @return A new string without unsafe chars */ std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT); +bool validateURL(std::string strURL, std::string& strErr, unsigned int maxSize = 64); std::vector ParseHex(const char* psz); std::vector ParseHex(const std::string& str); signed char HexDigit(char c);