SL-18837: Avoid stuffing build number into 32-bit int.

Even though LLVersionInfo::getBuild() already returns a 64-bit int, various
consumers assumed it could fit into 32 bits. It was especially bad to pass it
to a classic C style varargs function. Only on a little-endian CPU, and only
because it was the last argument, the damage was limited to truncation --
instead of arbitrary undefined behavior.

Where the consumer doesn't support 64-bit ints, pass as string instead.
master
Nat Goodspeed 2023-10-17 06:33:05 -04:00
parent 19f453fc20
commit 117f07e5a4
7 changed files with 42 additions and 34 deletions

View File

@ -3209,8 +3209,10 @@ LLSD LLAppViewer::getViewerInfo() const
// LLFloaterAbout.
LLSD info;
auto& versionInfo(LLVersionInfo::instance());
// With GitHub builds, the build number is too big to fit in a 32-bit int,
// and LLSD doesn't deal with integers wider than int. Use string.
info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(),
versionInfo.getPatch(), versionInfo.getBuild());
versionInfo.getPatch(), stringize(versionInfo.getBuild()));
info["VIEWER_VERSION_STR"] = versionInfo.getVersion();
info["CHANNEL"] = versionInfo.getChannel();
info["ADDRESS_SIZE"] = ADDRESS_SIZE;

View File

@ -45,6 +45,7 @@
#include "llxmlrpctransaction.h"
#include "llviewernetwork.h"
#include "llpanel.h"
#include "stringize.h"
const F64 CURRENCY_ESTIMATE_FREQUENCY = 2.0;
@ -158,7 +159,7 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
mLocalCurrencyEstimated = true;
return;
}
LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct();
keywordArgs.appendString("agentId", gAgent.getID().asString());
keywordArgs.appendString(
@ -170,8 +171,10 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor());
keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor());
keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch());
keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::instance().getBuild());
// With GitHub builds, the build number is too big to fit in a 32-bit int,
// and XMLRPC_VALUE doesn't deal with integers wider than int. Use string.
keywordArgs.appendString("viewerBuildVersion", stringize(LLVersionInfo::instance().getBuild()));
LLXMLRPCValue params = LLXMLRPCValue::createArray();
params.append(keywordArgs);
@ -245,7 +248,9 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)
keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor());
keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor());
keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch());
keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::instance().getBuild());
// With GitHub builds, the build number is too big to fit in a 32-bit int,
// and XMLRPC_VALUE doesn't deal with integers wider than int. Use string.
keywordArgs.appendString("viewerBuildVersion", stringize(LLVersionInfo::instance().getBuild()));
LLXMLRPCValue params = LLXMLRPCValue::createArray();
params.append(keywordArgs);

View File

@ -65,6 +65,7 @@
#include "lltrans.h"
#include "llglheaders.h"
#include "llpanelloginlistener.h"
#include "stringize.h"
#if LL_WINDOWS
#pragma warning(disable: 4355) // 'this' used in initializer list
@ -300,10 +301,9 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
setDefaultBtn(def_btn);
std::string channel = LLVersionInfo::instance().getChannel();
std::string version = llformat("%s (%ld)",
LLVersionInfo::instance().getShortVersion().c_str(),
LLVersionInfo::instance().getBuild());
std::string version = stringize(LLVersionInfo::instance().getShortVersion(), " (",
LLVersionInfo::instance().getBuild(), ')');
LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
@ -894,9 +894,8 @@ void LLPanelLogin::loadLoginPage()
}
// Channel and Version
params["version"] = llformat("%s (%ld)",
LLVersionInfo::instance().getShortVersion().c_str(),
LLVersionInfo::instance().getBuild());
params["version"] = stringize(LLVersionInfo::instance().getShortVersion(), " (",
LLVersionInfo::instance().getBuild(), ')');
params["channel"] = LLVersionInfo::instance().getChannel();
// Grid

View File

@ -39,6 +39,7 @@
#include "json/reader.h"
#include "llcorehttputil.h"
#include "llurlregistry.h"
#include "stringize.h"
static const std::string AZURE_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">");
@ -160,12 +161,12 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, LLSD
LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
std::string user_agent = llformat("%s %d.%d.%d (%ld)",
LLVersionInfo::instance().getChannel().c_str(),
LLVersionInfo::instance().getMajor(),
LLVersionInfo::instance().getMinor(),
LLVersionInfo::instance().getPatch(),
LLVersionInfo::instance().getBuild());
std::string user_agent = stringize(
LLVersionInfo::instance().getChannel(), ' ',
LLVersionInfo::instance().getMajor(), '.',
LLVersionInfo::instance().getMinor(), '.',
LLVersionInfo::instance().getPatch(), " (",
LLVersionInfo::instance().getBuild(), ')');
initHttpHeader(httpHeaders, user_agent, key);
@ -215,12 +216,12 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
std::string user_agent = llformat("%s %d.%d.%d (%ld)",
LLVersionInfo::instance().getChannel().c_str(),
LLVersionInfo::instance().getMajor(),
LLVersionInfo::instance().getMinor(),
LLVersionInfo::instance().getPatch(),
LLVersionInfo::instance().getBuild());
std::string user_agent = stringize(
LLVersionInfo::instance().getChannel(), ' ',
LLVersionInfo::instance().getMajor(), '.',
LLVersionInfo::instance().getMinor(), '.',
LLVersionInfo::instance().getPatch(), " (",
LLVersionInfo::instance().getBuild(), ')');
initHttpHeader(httpHeaders, user_agent);
httpOpts->setSSLVerifyPeer(false);

View File

@ -69,7 +69,7 @@ void LLVersionInfo::initSingleton()
// fully constructed; such calls don't really belong in the constructor.
// cache the version string
version = STRINGIZE(getShortVersion() << "." << getBuild());
version = stringize(getShortVersion(), ".", getBuild());
}
LLVersionInfo::~LLVersionInfo()
@ -91,7 +91,7 @@ S32 LLVersionInfo::getPatch()
return LL_VIEWER_VERSION_PATCH;
}
S64 LLVersionInfo::getBuild()
U64 LLVersionInfo::getBuild()
{
return LL_VIEWER_VERSION_BUILD;
}

View File

@ -61,7 +61,7 @@ public:
S32 getPatch();
/// return the build number as an integer
S64 getBuild();
U64 getBuild();
/// return the full viewer version as a string like "2.0.0.200030"
std::string getVersion();

View File

@ -42,6 +42,7 @@
#include "bufferarray.h"
#include "llversioninfo.h"
#include "llviewercontrol.h"
#include "stringize.h"
// Have to include these last to avoid queue redefinition!
@ -384,14 +385,14 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
std::string user_agent = llformat("%s %d.%d.%d (%ld)",
LLVersionInfo::instance().getChannel().c_str(),
LLVersionInfo::instance().getMajor(),
LLVersionInfo::instance().getMinor(),
LLVersionInfo::instance().getPatch(),
LLVersionInfo::instance().getBuild());
std::string user_agent = stringize(
LLVersionInfo::instance().getChannel(), ' ',
LLVersionInfo::instance().getMajor(), '.',
LLVersionInfo::instance().getMinor(), '.',
LLVersionInfo::instance().getPatch(), " (",
LLVersionInfo::instance().getBuild(), ')');
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
///* Setting the DNS cache timeout to -1 disables it completely.
//This might help with bug #503 */