Legacy steps to update the library: - Update the "strtools_public.h" and "strtools_public.cpp" files, commenting out the "Uint64ToString", "wcsncpy_s", and "strncpy_s" functions. The "Uint64ToString" function name conflicts with another used in Gecko and the "errno_t" return type returned by the other functions is not defined in Mozilla's macOS continuous integration build environments. Fortunately, the OpenVR SDK does not use these functions. - Replace the #define VR_INTERFACE in openvr.h to avoid extern'ing the functions. Unlike the usual OpenVR API builds, we are not building a separate dll. - Add explicit in CVRSettingHelper constructor. - In strtools_public.cpp/.h, ensure that UTF16to8 and UTF8to16 are only compiled under #if defined( _WIN32 ) and redefine those functions to use ::WideCharToMultiByte and MultiByteToWideChar, respectively. These are modified because the original implementations contain unsupported try-catch. - In strtools_public.cpp, remove the definition of convert_type. - In strtools_public.cpp, remove the include of , as this causes problems in compiling on Linux. - In pathtools_public.cpp/.h, comment out Path_UrlToFilePath and Path_FilePathToUrl to avoid a compile error because 'alloca' isn't defined. - In vrpathregistry_public.cpp, CVRPathRegistry_Public::BLoadFromFile contains a try-catch, which is not permitted. This code is simply commented out, but Bug 1640068 - OpenVR code can fail JSON parsing and raise exceptions is filed to address a safe fallback in the error condition. diff --git a/headers/openvr.h b/headers/openvr.h index ec26ef41564b9..b95fb1db7e0fe 100644 --- a/headers/openvr.h +++ b/headers/openvr.h @@ -1932,30 +1932,33 @@ struct ImuSample_t #pragma pack( pop ) +#define VR_INTERFACE + +// Mozilla: see mozilla.patch for more details // figure out how to import from the VR API dll -#if defined(_WIN32) - - #if !defined(OPENVR_BUILD_STATIC) - #ifdef VR_API_EXPORT - #define VR_INTERFACE extern "C" __declspec( dllexport ) - #else - #define VR_INTERFACE extern "C" __declspec( dllimport ) - #endif - #else - #define VR_INTERFACE extern "C" - #endif - -#elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) - -#ifdef VR_API_EXPORT - #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) -#else - #define VR_INTERFACE extern "C" -#endif +// #if defined(_WIN32) -#else - #error "Unsupported Platform." -#endif +// #if !defined(OPENVR_BUILD_STATIC) +// #ifdef VR_API_EXPORT +// #define VR_INTERFACE extern "C" __declspec( dllexport ) +// #else +// #define VR_INTERFACE extern "C" __declspec( dllimport ) +// #endif +// #else +// #define VR_INTERFACE extern "C" +// #endif + +// #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) + +// #ifdef VR_API_EXPORT +// #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) +// #else +// #define VR_INTERFACE extern "C" +// #endif + +// #else +// #error "Unsupported Platform." +// #endif #if defined( _WIN32 ) @@ -2557,7 +2560,8 @@ namespace vr { IVRSettings *m_pSettings; public: - CVRSettingHelper( IVRSettings *pSettings ) + // Mozilla: see mozilla.patch for more details + explicit CVRSettingHelper( IVRSettings *pSettings ) { m_pSettings = pSettings; } diff --git a/src/pathtools_public.cpp b/src/pathtools_public.cpp index eb1373a57b1a5..e7f6d6ca1bf45 100644 --- a/src/pathtools_public.cpp +++ b/src/pathtools_public.cpp @@ -798,52 +798,54 @@ bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const cha #define FILE_URL_PREFIX "file://" #endif +// Mozilla: see mozilla.patch for more details // ---------------------------------------------------------------------------------------------------------------------------- // Purpose: Turns a path to a file on disk into a URL (or just returns the value if it's already a URL) // ---------------------------------------------------------------------------------------------------------------------------- -std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath ) -{ - if ( StringHasPrefix( sRelativePath, "http://" ) - || StringHasPrefix( sRelativePath, "https://" ) - || StringHasPrefix( sRelativePath, "vr-input-workshop://" ) - || StringHasPrefix( sRelativePath, "file://" ) - ) - { - return sRelativePath; - } - else - { - std::string sAbsolute = Path_MakeAbsolute( sRelativePath, sBasePath ); - if ( sAbsolute.empty() ) - return sAbsolute; - sAbsolute = Path_FixSlashes( sAbsolute, '/' ); - - size_t unBufferSize = sAbsolute.length() * 3; - char *pchBuffer = (char *)alloca( unBufferSize ); - V_URLEncodeFullPath( pchBuffer, (int)unBufferSize, sAbsolute.c_str(), (int)sAbsolute.length() ); - - return std::string( FILE_URL_PREFIX ) + pchBuffer; - } -} - +// std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath ) +// { +// if ( StringHasPrefix( sRelativePath, "http://" ) +// || StringHasPrefix( sRelativePath, "https://" ) +// || StringHasPrefix( sRelativePath, "vr-input-workshop://" ) +// || StringHasPrefix( sRelativePath, "file://" ) +// ) +// { +// return sRelativePath; +// } +// else +// { +// std::string sAbsolute = Path_MakeAbsolute( sRelativePath, sBasePath ); +// if ( sAbsolute.empty() ) +// return sAbsolute; +// sAbsolute = Path_FixSlashes( sAbsolute, '/' ); + +// size_t unBufferSize = sAbsolute.length() * 3; +// char *pchBuffer = (char *)alloca( unBufferSize ); +// V_URLEncodeFullPath( pchBuffer, (int)unBufferSize, sAbsolute.c_str(), (int)sAbsolute.length() ); + +// return std::string( FILE_URL_PREFIX ) + pchBuffer; +// } +// } + +// Mozilla: see mozilla.patch for more details // ----------------------------------------------------------------------------------------------------- // Purpose: Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned // ----------------------------------------------------------------------------------------------------- -std::string Path_UrlToFilePath( const std::string & sFileUrl ) -{ - if ( !strnicmp( sFileUrl.c_str(), FILE_URL_PREFIX, strlen( FILE_URL_PREFIX ) ) ) - { - char *pchBuffer = (char *)alloca( sFileUrl.length() ); - V_URLDecodeNoPlusForSpace( pchBuffer, (int)sFileUrl.length(), - sFileUrl.c_str() + strlen( FILE_URL_PREFIX ), (int)( sFileUrl.length() - strlen( FILE_URL_PREFIX ) ) ); - - return Path_FixSlashes( pchBuffer ); - } - else - { - return ""; - } -} +// std::string Path_UrlToFilePath( const std::string & sFileUrl ) +// { +// if ( !strnicmp( sFileUrl.c_str(), FILE_URL_PREFIX, strlen( FILE_URL_PREFIX ) ) ) +// { +// char *pchBuffer = (char *)alloca( sFileUrl.length() ); +// V_URLDecodeNoPlusForSpace( pchBuffer, (int)sFileUrl.length(), +// sFileUrl.c_str() + strlen( FILE_URL_PREFIX ), (int)( sFileUrl.length() - strlen( FILE_URL_PREFIX ) ) ); + +// return Path_FixSlashes( pchBuffer ); +// } +// else +// { +// return ""; +// } +// } // ----------------------------------------------------------------------------------------------------- diff --git a/src/pathtools_public.h b/src/pathtools_public.h index 9a120f43d6a57..33688fba2f4ad 100644 --- a/src/pathtools_public.h +++ b/src/pathtools_public.h @@ -98,8 +98,9 @@ std::string Path_ReadTextFile( const std::string &strFilename ); bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData ); bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData ); +// Mozilla: see mozilla.patch for more details /** Returns a file:// url for paths, or an http or https url if that's what was provided */ -std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath ); +// std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath ); /** Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned */ std::string Path_UrlToFilePath( const std::string & sFileUrl ); diff --git a/src/strtools_public.cpp b/src/strtools_public.cpp index f9ce0fd5ea799..f52f8e9004982 100644 --- a/src/strtools_public.cpp +++ b/src/strtools_public.cpp @@ -4,11 +4,12 @@ #include #include #include -#include +// Mozilla: see mozilla.patch for more details +// #include #include #include #include -#include +// #include #if defined( _WIN32 ) #include @@ -57,40 +58,74 @@ bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -typedef std::codecvt_utf8< wchar_t > convert_type; +// Mozilla: see mozilla.patch for more details +//typedef std::codecvt_utf8< wchar_t > convert_type; +// Mozilla: see mozilla.patch for more details +#if defined( _WIN32 ) std::string UTF16to8(const wchar_t * in) { - static std::wstring_convert< convert_type, wchar_t > s_converter; // construction of this can be expensive (or even serialized) depending on locale - - try - { - return s_converter.to_bytes( in ); - } - catch ( ... ) + int retLength = ::WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr); + if (retLength == 0) { return std::string(); } + + char* retString = new char[retLength]; + ::WideCharToMultiByte(CP_UTF8, 0, in, -1, retString, retLength, nullptr, nullptr); + + std::string retStringValue(retString); + + delete[] retString; + + return retStringValue; + + // static std::wstring_convert< convert_type, wchar_t > s_converter; // construction of this can be expensive (or even serialized) depending on locale + + // try + // { + // return s_converter.to_bytes( in ); + // } + // catch ( ... ) + // { + // return std::string(); + // } } std::string UTF16to8( const std::wstring & in ) { return UTF16to8( in.c_str() ); } - +// Mozilla: see mozilla.patch for more details std::wstring UTF8to16(const char * in) { - static std::wstring_convert< convert_type, wchar_t > s_converter; // construction of this can be expensive (or even serialized) depending on locale - - try - { - return s_converter.from_bytes( in ); - } - catch ( ... ) + int retLength = ::MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0); + if (retLength == 0) { return std::wstring(); } + + wchar_t* retString = new wchar_t[retLength]; + ::MultiByteToWideChar(CP_UTF8, 0, in, -1, retString, retLength); + + std::wstring retStringValue(retString); + + delete[] retString; + + return retStringValue; + + //static std::wstring_convert< convert_type, wchar_t > s_converter; // construction of this can be expensive (or even serialized) depending on locale + + //try + //{ + // return s_converter.from_bytes( in ); + //} + //catch ( ... ) + //{ + // return std::wstring(); + //} } std::wstring UTF8to16( const std::string & in ) { return UTF8to16( in.c_str() ); } +#endif #if defined( _WIN32 ) @@ -173,16 +208,17 @@ uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t /** Returns a std::string from a uint64_t */ -std::string Uint64ToString( uint64_t ulValue ) -{ - char buf[ 22 ]; -#if defined( _WIN32 ) - sprintf_s( buf, "%llu", ulValue ); -#else - snprintf( buf, sizeof( buf ), "%llu", (long long unsigned int ) ulValue ); -#endif - return buf; -} +// Mozilla: see mozilla.patch for more details +// std::string Uint64ToString( uint64_t ulValue ) +// { +// char buf[ 22 ]; +// #if defined( _WIN32 ) +// sprintf_s( buf, "%llu", ulValue ); +// #else +// snprintf( buf, sizeof( buf ), "%llu", (long long unsigned int ) ulValue ); +// #endif +// return buf; +// } /** returns a uint64_t from a string */ @@ -451,84 +487,85 @@ std::vector TokenizeString( const std::string & sString, char cToke return vecStrings; } +// Mozilla: see mozilla.patch for more details //----------------------------------------------------------------------------- // Purpose: Repairs a should-be-UTF-8 string to a for-sure-is-UTF-8 string, plus return boolean if we subbed in '?' somewhere //----------------------------------------------------------------------------- -bool RepairUTF8( const char *pbegin, const char *pend, std::string & sOutputUtf8 ) -{ - typedef std::codecvt_utf8 facet_type; - facet_type myfacet; - - std::mbstate_t mystate = std::mbstate_t(); - - sOutputUtf8.clear(); - sOutputUtf8.reserve( pend - pbegin ); - bool bSqueakyClean = true; - - const char *pmid = pbegin; - while ( pmid != pend ) - { - bool bHasError = false; - bool bHasValidData = false; - - char32_t out = 0xdeadbeef, *pout; - pbegin = pmid; - switch ( myfacet.in( mystate, pbegin, pend, pmid, &out, &out + 1, pout ) ) - { - case facet_type::ok: - bHasValidData = true; - break; - - case facet_type::noconv: - // unexpected! always converting type - bSqueakyClean = false; - break; - - case facet_type::partial: - bHasError = pbegin == pmid; - if ( bHasError ) - { - bSqueakyClean = false; - } - else - { - bHasValidData = true; - } - break; - - case facet_type::error: - bHasError = true; - bSqueakyClean = false; - break; - } - - if ( bHasValidData ) - { - // could convert back, but no need - for ( const char *p = pbegin; p != pmid; ++p ) - { - sOutputUtf8 += *p; - } - } - - if ( bHasError ) - { - sOutputUtf8 += '?'; - } - - if ( pmid == pbegin ) - { - pmid++; - } - } - - return bSqueakyClean; -} - -//----------------------------------------------------------------------------- -// Purpose: Repairs a should-be-UTF-8 string to a for-sure-is-UTF-8 string, plus return boolean if we subbed in '?' somewhere -//----------------------------------------------------------------------------- -bool RepairUTF8( const std::string & sInputUtf8, std::string & sOutputUtf8 ) -{ - return RepairUTF8( sInputUtf8.data(), sInputUtf8.data() + sInputUtf8.size(), sOutputUtf8 ); -} +// bool RepairUTF8( const char *pbegin, const char *pend, std::string & sOutputUtf8 ) +// { +// typedef std::codecvt_utf8 facet_type; +// facet_type myfacet; + +// std::mbstate_t mystate = std::mbstate_t(); + +// sOutputUtf8.clear(); +// sOutputUtf8.reserve( pend - pbegin ); +// bool bSqueakyClean = true; + +// const char *pmid = pbegin; +// while ( pmid != pend ) +// { +// bool bHasError = false; +// bool bHasValidData = false; + +// char32_t out = 0xdeadbeef, *pout; +// pbegin = pmid; +// switch ( myfacet.in( mystate, pbegin, pend, pmid, &out, &out + 1, pout ) ) +// { +// case facet_type::ok: +// bHasValidData = true; +// break; + +// case facet_type::noconv: +// // unexpected! always converting type +// bSqueakyClean = false; +// break; + +// case facet_type::partial: +// bHasError = pbegin == pmid; +// if ( bHasError ) +// { +// bSqueakyClean = false; +// } +// else +// { +// bHasValidData = true; +// } +// break; + +// case facet_type::error: +// bHasError = true; +// bSqueakyClean = false; +// break; +// } + +// if ( bHasValidData ) +// { +// // could convert back, but no need +// for ( const char *p = pbegin; p != pmid; ++p ) +// { +// sOutputUtf8 += *p; +// } +// } + +// if ( bHasError ) +// { +// sOutputUtf8 += '?'; +// } + +// if ( pmid == pbegin ) +// { +// pmid++; +// } +// } + +// return bSqueakyClean; +// } + +// //----------------------------------------------------------------------------- +// // Purpose: Repairs a should-be-UTF-8 string to a for-sure-is-UTF-8 string, plus return boolean if we subbed in '?' somewhere +// //----------------------------------------------------------------------------- +// bool RepairUTF8( const std::string & sInputUtf8, std::string & sOutputUtf8 ) +// { +// return RepairUTF8( sInputUtf8.data(), sInputUtf8.data() + sInputUtf8.size(), sOutputUtf8 ); +// } diff --git a/src/strtools_public.h b/src/strtools_public.h index 349b5b38fd387..067bbe1b1b074 100644 --- a/src/strtools_public.h +++ b/src/strtools_public.h @@ -14,6 +14,8 @@ bool StringHasPrefixCaseSensitive( const std::string & sString, const std::strin bool StringHasSuffix( const std::string &sString, const std::string &sSuffix ); bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix ); +// Mozilla: see mozilla.patch for more details +#if defined( _WIN32 ) /** converts a UTF-16 string to a UTF-8 string */ std::string UTF16to8( const wchar_t * in ); std::string UTF16to8( const std::wstring & in ); @@ -22,6 +24,7 @@ std::string UTF16to8( const std::wstring & in ); std::wstring UTF8to16(const char * in); std::wstring UTF8to16( const std::string & in ); #define Utf16FromUtf8 UTF8to16 +#endif #if defined( _WIN32 ) std::string DefaultACPtoUTF8( const char *pszStr ); @@ -69,15 +72,15 @@ inline int strnicmp( const char *pStr1, const char *pStr2, size_t unBufferLen ) #if defined( OSX ) // behaviors ensure NULL-termination at least as well as _TRUNCATE does, but // wcsncpy_s/strncpy_s can non-NULL-terminate, wcslcpy/strlcpy can not. -inline errno_t wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count) -{ - return wcslcpy(strDest, strSource, numberOfElements); -} +// inline errno_t wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count) +// { +// return wcslcpy(strDest, strSource, numberOfElements); +// } -inline errno_t strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count) -{ - return strlcpy(strDest, strSource, numberOfElements); -} +// inline errno_t strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count) +// { +// return strlcpy(strDest, strSource, numberOfElements); +// } #endif @@ -108,7 +111,8 @@ inline uint64_t strtoull(const char *str, char **endptr, int base) { return _str uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen ); /** Returns a std::string from a uint64_t */ -std::string Uint64ToString( uint64_t ulValue ); +// Mozilla: see mozilla.patch for more details +//std::string Uint64ToString( uint64_t ulValue ); /** returns a uint64_t from a string */ uint64_t StringToUint64( const std::string & sValue ); diff --git a/src/vrpathregistry_public.cpp b/src/vrpathregistry_public.cpp index 6a7f457bbacf3..f40fc1cda1acd 100644 --- a/src/vrpathregistry_public.cpp +++ b/src/vrpathregistry_public.cpp @@ -208,7 +208,7 @@ bool CVRPathRegistry_Public::ToJsonString( std::string &sJsonString ) return true; } - +// Mozilla: see mozilla.patch for more details // --------------------------------------------------------------------------- // Purpose: Loads the config file from its well known location // --------------------------------------------------------------------------- @@ -239,7 +239,8 @@ bool CVRPathRegistry_Public::BLoadFromFile( std::string *psLoadError ) std::istringstream istream( sRegistryContents ); std::string sErrors; - try { +// try + { if ( !parseFromStream( builder, istream, &root, &sErrors ) ) { if ( psLoadError ) @@ -257,14 +258,14 @@ bool CVRPathRegistry_Public::BLoadFromFile( std::string *psLoadError ) ParseStringListFromJson( &m_vecExternalDrivers, root, "external_drivers" ); } } - catch ( ... ) - { - if ( psLoadError ) - { - *psLoadError = "Unable to parse " + sRegPath + ": exception thrown in JSON library"; - } - return false; - } +// catch ( ... ) +// { +// if ( psLoadError ) +// { +// *psLoadError = "Unable to parse " + sRegPath + ": exception thrown in JSON library"; +// } +// return false; +// } return true; }