diff options
Diffstat (limited to 'indra/llcommon')
27 files changed, 561 insertions, 437 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d767503c7e..85ab874980 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -121,6 +121,7 @@ set(llcommon_HEADER_FILES      commoncontrol.h      ctype_workaround.h      fix_macros.h +    fsyspath.h      function_types.h      indra_constants.h      lazyeventapi.h @@ -244,7 +245,6 @@ set(llcommon_HEADER_FILES      lluriparser.h      lluuid.h      llwin32headers.h -    llwin32headerslean.h      llworkerthread.h      hbxxh.h      is_approx_equal_fraction.h diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h new file mode 100644 index 0000000000..1b4aec09b4 --- /dev/null +++ b/indra/llcommon/fsyspath.h @@ -0,0 +1,79 @@ +/** + * @file   fsyspath.h + * @author Nat Goodspeed + * @date   2024-04-03 + * @brief  Adapt our UTF-8 std::strings for std::filesystem::path + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Copyright (c) 2024, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_FSYSPATH_H) +#define LL_FSYSPATH_H + +#include <filesystem> + +// While std::filesystem::path can be directly constructed from std::string on +// both Posix and Windows, that's not what we want on Windows. Per +// https://en.cppreference.com/w/cpp/filesystem/path/path: + +// ... the method of conversion to the native character set depends on the +// character type used by source. +// +// * If the source character type is char, the encoding of the source is +//   assumed to be the native narrow encoding (so no conversion takes place on +//   POSIX systems). +// * If the source character type is char8_t, conversion from UTF-8 to native +//   filesystem encoding is used. (since C++20) +// * If the source character type is wchar_t, the input is assumed to be the +//   native wide encoding (so no conversion takes places on Windows). + +// The trouble is that on Windows, from std::string ("source character type is +// char"), the "native narrow encoding" isn't UTF-8, so file paths containing +// non-ASCII characters get mangled. +// +// Once we're building with C++20, we could pass a UTF-8 std::string through a +// vector<char8_t> to engage std::filesystem::path's own UTF-8 conversion. But +// sigh, as of 2024-04-03 we're not yet there. +// +// Anyway, encapsulating the important UTF-8 conversions in our own subclass +// allows us to migrate forward to C++20 conventions without changing +// referencing code. + +class fsyspath: public std::filesystem::path +{ +    using super = std::filesystem::path; + +public: +    // default +    fsyspath() {} +    // construct from UTF-8 encoded std::string +    fsyspath(const std::string& path): super(std::filesystem::u8path(path)) {} +    // construct from UTF-8 encoded const char* +    fsyspath(const char* path): super(std::filesystem::u8path(path)) {} +    // construct from existing path +    fsyspath(const super& path): super(path) {} + +    fsyspath& operator=(const super& p) { super::operator=(p); return *this; } +    fsyspath& operator=(const std::string& p) +    { +        super::operator=(std::filesystem::u8path(p)); +        return *this; +    } +    fsyspath& operator=(const char* p) +    { +        super::operator=(std::filesystem::u8path(p)); +        return *this; +    } + +    // shadow base-class string() method with UTF-8 aware method +    std::string string() const { return super::u8string(); } +    // On Posix systems, where value_type is already char, this operator +    // std::string() method shadows the base class operator string_type() +    // method. But on Windows, where value_type is wchar_t, the base class +    // doesn't have operator std::string(). Provide it. +    operator std::string() const { return string(); } +}; + +#endif /* ! defined(LL_FSYSPATH_H) */ diff --git a/indra/llcommon/hexdump.h b/indra/llcommon/hexdump.h new file mode 100755 index 0000000000..ab5ba2b16d --- /dev/null +++ b/indra/llcommon/hexdump.h @@ -0,0 +1,106 @@ +/** + * @file   hexdump.h + * @author Nat Goodspeed + * @date   2023-10-03 + * @brief  iostream manipulators to stream hex, or string with nonprinting chars + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Copyright (c) 2023, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_HEXDUMP_H) +#define LL_HEXDUMP_H + +#include <cctype> +#include <iomanip> +#include <iostream> +#include <string_view> + +namespace LL +{ + +// Format a given byte string as 2-digit hex values, no separators +// Usage: std::cout << hexdump(somestring) << ... +class hexdump +{ +public: +    hexdump(const std::string_view& data): +        hexdump(data.data(), data.length()) +    {} + +    hexdump(const char* data, size_t len): +        hexdump(reinterpret_cast<const unsigned char*>(data), len) +    {} + +    hexdump(const std::vector<unsigned char>& data): +        hexdump(data.data(), data.size()) +    {} + +    hexdump(const unsigned char* data, size_t len): +        mData(data, data + len) +    {} + +    friend std::ostream& operator<<(std::ostream& out, const hexdump& self) +    { +        auto oldfmt{ out.flags() }; +        auto oldfill{ out.fill() }; +        out.setf(std::ios_base::hex, std::ios_base::basefield); +        out.fill('0'); +        for (auto c : self.mData) +        { +            out << std::setw(2) << unsigned(c); +        } +        out.setf(oldfmt, std::ios_base::basefield); +        out.fill(oldfill); +        return out; +    } + +private: +    std::vector<unsigned char> mData; +}; + +// Format a given byte string as a mix of printable characters and, for each +// non-printable character, "\xnn" +// Usage: std::cout << hexmix(somestring) << ... +class hexmix +{ +public: +    hexmix(const std::string_view& data): +        mData(data) +    {} + +    hexmix(const char* data, size_t len): +        mData(data, len) +    {} + +    friend std::ostream& operator<<(std::ostream& out, const hexmix& self) +    { +        auto oldfmt{ out.flags() }; +        auto oldfill{ out.fill() }; +        out.setf(std::ios_base::hex, std::ios_base::basefield); +        out.fill('0'); +        for (auto c : self.mData) +        { +            // std::isprint() must be passed an unsigned char! +            if (std::isprint(static_cast<unsigned char>(c))) +            { +                out << c; +            } +            else +            { +                out << "\\x" << std::setw(2) << unsigned(c); +            } +        } +        out.setf(oldfmt, std::ios_base::basefield); +        out.fill(oldfill); +        return out; +    } + +private: +    std::string mData; +}; + +} // namespace LL + +#endif /* ! defined(LL_HEXDUMP_H) */ diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 6da764f94c..08a43983d3 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -88,10 +88,6 @@ LLApp* LLApp::sApplication = NULL;  // and disables crashlogger  bool LLApp::sDisableCrashlogger = false; -// Local flag for whether or not to do logging in signal handlers. -//static -bool LLApp::sLogInSignal = true; -  // static  // Keeps track of application status  LLScalarCond<LLApp::EAppStatus> LLApp::sStatus{LLApp::APP_STATUS_STOPPED}; @@ -226,7 +222,7 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv)          if(wargv[ii][0] != '-')          {              LL_INFOS() << "Did not find option identifier while parsing token: " -                << wargv[ii] << LL_ENDL; +                << (intptr_t)wargv[ii] << LL_ENDL;              return false;          }          int offset = 1; @@ -596,6 +592,10 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)      // We do the somewhat sketchy operation of blocking in here until the error handler      // has gracefully stopped the app. +    // FIXME(brad) - we are using this handler for asynchronous signals as well, so sLogInSignal is currently +    // disabled for safety.  we need to find a way to selectively reenable it when it is safe. +    // see issue secondlife/viewer#2566 +      if (LLApp::sLogInSignal)      {          LL_INFOS() << "Signal handler - Got signal " << signum << " - " << apr_signal_description_get(signum) << LL_ENDL; diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index d90ecdf661..3d18864b80 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -339,8 +339,12 @@ private:      friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);  #endif -public: -    static bool sLogInSignal; +private: +#ifdef LL_RELEASE_FOR_DOWNLOAD +    static constexpr bool sLogInSignal = false; +#else +    static constexpr bool sLogInSignal = true; +#endif  };  #endif // LL_LLAPP_H diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 10b0a55986..13597d56a4 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -34,7 +34,7 @@  #endif  #include <boost/noncopyable.hpp> -#include "llwin32headerslean.h" +#include "llwin32headers.h"  #include "apr_thread_proc.h"  #include "apr_getopt.h"  #include "apr_signal.h" diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index ad35bc84f2..90c6ba309b 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -110,7 +110,7 @@ namespace {          virtual void recordMessage(LLError::ELevel level,                                      const std::string& message) override          { -            LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING +            LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;              int syslogPriority = LOG_CRIT;              switch (level) {                  case LLError::LEVEL_DEBUG:  syslogPriority = LOG_DEBUG; break; diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index ed94ef21ef..d0bc8f7652 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -34,7 +34,7 @@  #include "stringize.h"  #if LL_WINDOWS -#include "llwin32headerslean.h" +#include "llwin32headers.h"  #include <stdlib.h>                 // Windows errno  #include <vector>  #else diff --git a/indra/llcommon/llmainthreadtask.h b/indra/llcommon/llmainthreadtask.h index cec95b2356..c3ed7fef52 100644 --- a/indra/llcommon/llmainthreadtask.h +++ b/indra/llcommon/llmainthreadtask.h @@ -89,10 +89,10 @@ private:          }          // Given arbitrary CALLABLE, which might be a lambda, how are we          // supposed to obtain its signature for std::packaged_task? It seems -        // redundant to have to add an argument list to engage result_of, then +        // redundant to have to add an argument list to engage invoke_result_t, then          // add the argument list again to complete the signature. At least we          // only support a nullary CALLABLE. -        std::packaged_task<typename std::result_of<CALLABLE()>::type()> mTask; +        std::packaged_task<std::invoke_result_t<CALLABLE>()> mTask;      };  }; diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index f64f54c262..e999b8f597 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -68,10 +68,6 @@ documentation and/or software.   */ - - - -  #include "linden_common.h"  #include "llmd5.h" @@ -81,232 +77,203 @@ documentation and/or software.  // how many bytes to grab at a time when checking files  const int LLMD5::BLOCK_LEN = 4096; -  // LLMD5 simple initialization method -  LLMD5::LLMD5()  { -  init(); +    init();  } - - -  // MD5 block update operation. Continues an MD5 message-digest  // operation, processing another message block, and updating the  // context. +void LLMD5::update(const uint8_t* input, const size_t input_length) +{ +    size_t input_index, buffer_index; +    size_t buffer_space; // how much space is left in buffer -void LLMD5::update (const uint8_t *input, const size_t input_length) { - -  size_t input_index, buffer_index; -  size_t buffer_space;                // how much space is left in buffer - -  if (finalized){  // so we can't update! -      std::cerr << "LLMD5::update:  Can't update a finalized digest!" << std::endl; -    return; -  } - -  // Compute number of bytes mod 64 -  buffer_index = size_t((count >> 3) & 0x3F); +    if (finalized) +    { // so we can't update! +        std::cerr << "LLMD5::update:  Can't update a finalized digest!" << std::endl; +        return; +    } -  // Update number of bits -  count += input_length << 3; +    // Compute number of bytes mod 64 +    buffer_index = size_t((count >> 3) & 0x3F); -  buffer_space = 64 - buffer_index;  // how much space is left in buffer +    // Update number of bits +    count += input_length << 3; -  // now, transform each 64-byte piece of the input, bypassing the buffer -  if (input == NULL || input_length == 0){ -      std::cerr << "LLMD5::update:  Invalid input!" << std::endl; -      return; -  } +    buffer_space = 64 - buffer_index; // how much space is left in buffer -  // Transform as many times as possible. -  if (input_length >= buffer_space) { // ie. we have enough to fill the buffer -    // fill the rest of the buffer and transform -    memcpy( /* Flawfinder: ignore */ -        buffer + buffer_index, -        input, -        buffer_space); -    transform (buffer); +    // now, transform each 64-byte piece of the input, bypassing the buffer +    if (input == NULL || input_length == 0) +    { +        std::cerr << "LLMD5::update:  Invalid input!" << std::endl; +        return; +    } -    for (input_index = buffer_space; input_index + 63 < input_length; -     input_index += 64) -      transform (input+input_index); +    // Transform as many times as possible. +    if (input_length >= buffer_space) // ie. we have enough to fill the buffer +    { +        // fill the rest of the buffer and transform +        memcpy(/* Flawfinder: ignore */ +               buffer + buffer_index, +               input, +               buffer_space); +        transform(buffer); -    buffer_index = 0;  // so we can buffer remaining -  } -  else -    input_index=0;     // so we can buffer the whole input +        for (input_index = buffer_space; input_index + 63 < input_length; input_index += 64) +            transform(input + input_index); +        buffer_index = 0; // so we can buffer remaining +    } +    else +        input_index = 0; // so we can buffer the whole input -  // and here we do the buffering: -  memcpy(buffer+buffer_index, input+input_index, input_length-input_index);     /* Flawfinder: ignore */ +    // and here we do the buffering: +    memcpy(buffer + buffer_index, input + input_index, input_length - input_index); /* Flawfinder: ignore */  } - -  // MD5 update for files.  // Like above, except that it works on files (and uses above as a primitive.) +void LLMD5::update(FILE* file) +{ +    unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */ +    int len; -void LLMD5::update(FILE* file){ - -  unsigned char buffer[BLOCK_LEN];      /* Flawfinder: ignore */ -  int len; - -  while ( (len=(int)fread(buffer, 1, BLOCK_LEN, file)) ) -    update(buffer, len); - -  fclose (file); +    while ((len = (int)fread(buffer, 1, BLOCK_LEN, file))) +        update(buffer, len); +    fclose(file);  }  // MD5 update for istreams.  // Like update for files; see above. +void LLMD5::update(std::istream& stream) +{ +    unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */ +    int len; -void LLMD5::update(std::istream& stream){ - -  unsigned char buffer[BLOCK_LEN];      /* Flawfinder: ignore */ -  int len; - -  while (stream.good()){ -    stream.read( (char*)buffer, BLOCK_LEN);     /* Flawfinder: ignore */        // note that return value of read is unusable. -    len=(int)stream.gcount(); -    update(buffer, len); -  } - +    while (stream.good()) +    { +        stream.read((char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable. +        len = (int)stream.gcount(); +        update(buffer, len); +    }  } -void  LLMD5::update(const std::string& s) +void LLMD5::update(const std::string& s)  { -    update((unsigned char *)s.c_str(),s.length()); +    update((unsigned char*)s.c_str(), s.length());  }  // MD5 finalization. Ends an MD5 message-digest operation, writing the  // the message digest and zeroizing the context. - - -void LLMD5::finalize (){ - -  unsigned char bits[8];        /* Flawfinder: ignore */ -  size_t index, padLen; -  static uint8_t PADDING[64]={ -    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +void LLMD5::finalize() +{ +    unsigned char bits[8]; /* Flawfinder: ignore */ +    size_t index, padLen; +    static uint8_t PADDING[64] = +    { +        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0      }; -  if (finalized){ -    std::cerr << "LLMD5::finalize:  Already finalized this digest!" << std::endl; -    return; -  } - -  // Save number of bits. -  // Treat count, a uint64_t, as uint32_t[2]. -  encode (bits, reinterpret_cast<uint32_t*>(&count), 8); +    if (finalized) +    { +        std::cerr << "LLMD5::finalize:  Already finalized this digest!" << std::endl; +        return; +    } -  // Pad out to 56 mod 64. -  index = size_t((count >> 3) & 0x3f); -  padLen = (index < 56) ? (56 - index) : (120 - index); -  update (PADDING, padLen); +    // Save number of bits. +    // Treat count, a uint64_t, as uint32_t[2]. +    encode(bits, reinterpret_cast<uint32_t*>(&count), 8); -  // Append length (before padding) -  update (bits, 8); +    // Pad out to 56 mod 64. +    index  = size_t((count >> 3) & 0x3f); +    padLen = (index < 56) ? (56 - index) : (120 - index); +    update(PADDING, padLen); -  // Store state in digest -  encode (digest, state, 16); +    // Append length (before padding) +    update(bits, 8); -  // Zeroize sensitive information -  memset (buffer, 0, sizeof(*buffer)); +    // Store state in digest +    encode(digest, state, 16); -  finalized=1; +    // Zeroize sensitive information +    memset(buffer, 0, sizeof(buffer)); +    finalized = true;  } - - - -LLMD5::LLMD5(FILE *file){ - -  init();  // must be called be all constructors -  update(file); -  finalize (); +LLMD5::LLMD5(FILE* file) +{ +    init(); // must be called be all constructors +    update(file); +    finalize();  } - - - -LLMD5::LLMD5(std::istream& stream){ - -  init();  // must called by all constructors -  update (stream); -  finalize(); +LLMD5::LLMD5(std::istream& stream) +{ +    init(); // must called by all constructors +    update(stream); +    finalize();  }  // Digest a string of the format ("%s:%i" % (s, number)) -LLMD5::LLMD5(const unsigned char *string, const unsigned int number) +LLMD5::LLMD5(const unsigned char* string, const unsigned int number)  { -    const char *colon = ":"; -    char tbuf[16];      /* Flawfinder: ignore */ +    const char* colon = ":"; +    char tbuf[16]; /* Flawfinder: ignore */      init(); -    update(string, (U32)strlen((const char *) string));     /* Flawfinder: ignore */ -    update((const unsigned char *) colon, (U32)strlen(colon));      /* Flawfinder: ignore */ -    snprintf(tbuf, sizeof(tbuf), "%i", number); /* Flawfinder: ignore */ -    update((const unsigned char *) tbuf, (U32)strlen(tbuf));    /* Flawfinder: ignore */ +    update(string, (U32)strlen((const char*)string));        /* Flawfinder: ignore */ +    update((const unsigned char*)colon, (U32)strlen(colon)); /* Flawfinder: ignore */ +    snprintf(tbuf, sizeof(tbuf), "%i", number);              /* Flawfinder: ignore */ +    update((const unsigned char*)tbuf, (U32)strlen(tbuf));   /* Flawfinder: ignore */      finalize();  }  // Digest a string -LLMD5::LLMD5(const unsigned char *s) +LLMD5::LLMD5(const unsigned char* s)  {      init(); -    update(s, (U32)strlen((const char *) s));       /* Flawfinder: ignore */ +    update(s, (U32)strlen((const char*)s)); /* Flawfinder: ignore */      finalize();  } -void LLMD5::raw_digest(unsigned char *s) const +void LLMD5::raw_digest(unsigned char* s) const  {      if (!finalized)      { -        std::cerr << "LLMD5::raw_digest:  Can't get digest if you haven't "<< -            "finalized the digest!" << std::endl; +        std::cerr << "LLMD5::raw_digest:  Can't get digest if you haven't " +                  << "finalized the digest!" << std::endl;          s[0] = '\0';          return;      } -    memcpy(s, digest, 16);      /* Flawfinder: ignore */ -    return; +    memcpy(s, digest, 16); /* Flawfinder: ignore */  } - - -void LLMD5::hex_digest(char *s) const +void LLMD5::hex_digest(char* s) const  { -    int i; -      if (!finalized)      { -        std::cerr << "LLMD5::hex_digest:  Can't get digest if you haven't "<< -          "finalized the digest!" <<std::endl; +        std::cerr << "LLMD5::hex_digest:  Can't get digest if you haven't " +                  << "finalized the digest!" << std::endl;          s[0] = '\0';          return;      } -    for (i=0; i<16; i++) +    for (int i = 0; i < 16; i++)      { -        sprintf(s+i*2, "%02x", digest[i]);      /* Flawfinder: ignore */ +        sprintf(s + i * 2, "%02x", digest[i]); /* Flawfinder: ignore */      } -    s[32]='\0'; - -    return; +    s[32] = '\0';  } - - - - - -std::ostream& operator<<(std::ostream &stream, LLMD5 context) +std::ostream& operator<<(std::ostream& stream, const LLMD5& context)  {      char s[33];     /* Flawfinder: ignore */      context.hex_digest(s); @@ -320,7 +287,7 @@ bool operator==(const LLMD5& a, const LLMD5& b)      unsigned char b_guts[16];      a.raw_digest(a_guts);      b.raw_digest(b_guts); -    if (memcmp(a_guts,b_guts,16)==0) +    if (memcmp(a_guts, b_guts, 16) == 0)          return true;      else          return false; @@ -328,30 +295,27 @@ bool operator==(const LLMD5& a, const LLMD5& b)  bool operator!=(const LLMD5& a, const LLMD5& b)  { -    return !(a==b); +    return !(a == b);  }  // PRIVATE METHODS: +void LLMD5::init() +{ +    finalized = false; // we just started! -void LLMD5::init(){ -  finalized=0;  // we just started! - -  // Nothing counted, so count=0 -  count = 0; +    // Nothing counted, so count=0 +    count = 0; -  // Load magic initialization constants. -  state[0] = 0x67452301; -  state[1] = 0xefcdab89; -  state[2] = 0x98badcfe; -  state[3] = 0x10325476; +    // Load magic initialization constants. +    state[0] = 0x67452301; +    state[1] = 0xefcdab89; +    state[2] = 0x98badcfe; +    state[3] = 0x10325476;  } - -  // Constants for MD5Transform routine.  // Although we could use C++ style constants, defines are actually better,  // since they let us easily evade scope clashes. -  #define S11 7  #define S12 12  #define S13 17 @@ -381,153 +345,144 @@ void LLMD5::init(){  /* ROTATE_LEFT rotates x left n bits.   */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))  /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.  Rotation is separate from addition to prevent recomputation.   */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (U32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ -  } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (U32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ -  } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (U32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ -  } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (U32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ -  } - - +#define FF(a, b, c, d, x, s, ac)                   \ +    {                                              \ +        (a) += F((b), (c), (d)) + (x) + (U32)(ac); \ +        (a) = ROTATE_LEFT((a), (s));               \ +        (a) += (b);                                \ +    } +#define GG(a, b, c, d, x, s, ac)                   \ +    {                                              \ +        (a) += G((b), (c), (d)) + (x) + (U32)(ac); \ +        (a) = ROTATE_LEFT((a), (s));               \ +        (a) += (b);                                \ +    } +#define HH(a, b, c, d, x, s, ac)                   \ +    {                                              \ +        (a) += H((b), (c), (d)) + (x) + (U32)(ac); \ +        (a) = ROTATE_LEFT((a), (s));               \ +        (a) += (b);                                \ +    } +#define II(a, b, c, d, x, s, ac)                   \ +    {                                              \ +        (a) += I((b), (c), (d)) + (x) + (U32)(ac); \ +        (a) = ROTATE_LEFT((a), (s));               \ +        (a) += (b);                                \ +    }  // LLMD5 basic transformation. Transforms state based on block. -void LLMD5::transform (const U8 block[64]){ - -  uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - -  decode (x, block, 64); - -  assert(!finalized);  // not just a user error, since the method is private - -  /* Round 1 */ -  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ -  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ -  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ -  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ -  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ -  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ -  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ -  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ -  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ -  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ -  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ -  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ -  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ -  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ -  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ -  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ -  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ -  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ -  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ -  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ -  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ -  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */ -  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ -  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ -  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ -  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ -  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ -  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ -  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ -  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ -  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ -  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - -  /* Round 3 */ -  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ -  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ -  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ -  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ -  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ -  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ -  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ -  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ -  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ -  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ -  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ -  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */ -  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ -  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ -  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ -  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - -  /* Round 4 */ -  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ -  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ -  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ -  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ -  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ -  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ -  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ -  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ -  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ -  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ -  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ -  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ -  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ -  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ -  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ -  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - -  state[0] += a; -  state[1] += b; -  state[2] += c; -  state[3] += d; - -  // Zeroize sensitive information. -  memset ( (uint8_t *) x, 0, sizeof(x)); - +void LLMD5::transform(const U8 block[64]) +{ +    uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + +    decode(x, block, 64); + +    assert(!finalized); // not just a user error, since the method is private + +    /* Round 1 */ +    FF(a, b, c, d, x[0], S11, 0xd76aa478);  /* 1 */ +    FF(d, a, b, c, x[1], S12, 0xe8c7b756);  /* 2 */ +    FF(c, d, a, b, x[2], S13, 0x242070db);  /* 3 */ +    FF(b, c, d, a, x[3], S14, 0xc1bdceee);  /* 4 */ +    FF(a, b, c, d, x[4], S11, 0xf57c0faf);  /* 5 */ +    FF(d, a, b, c, x[5], S12, 0x4787c62a);  /* 6 */ +    FF(c, d, a, b, x[6], S13, 0xa8304613);  /* 7 */ +    FF(b, c, d, a, x[7], S14, 0xfd469501);  /* 8 */ +    FF(a, b, c, d, x[8], S11, 0x698098d8);  /* 9 */ +    FF(d, a, b, c, x[9], S12, 0x8b44f7af);  /* 10 */ +    FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ +    FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ +    FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ +    FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ +    FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ +    FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + +    /* Round 2 */ +    GG(a, b, c, d, x[1], S21, 0xf61e2562);  /* 17 */ +    GG(d, a, b, c, x[6], S22, 0xc040b340);  /* 18 */ +    GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ +    GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);  /* 20 */ +    GG(a, b, c, d, x[5], S21, 0xd62f105d);  /* 21 */ +    GG(d, a, b, c, x[10], S22, 0x2441453);  /* 22 */ +    GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ +    GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);  /* 24 */ +    GG(a, b, c, d, x[9], S21, 0x21e1cde6);  /* 25 */ +    GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ +    GG(c, d, a, b, x[3], S23, 0xf4d50d87);  /* 27 */ +    GG(b, c, d, a, x[8], S24, 0x455a14ed);  /* 28 */ +    GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ +    GG(d, a, b, c, x[2], S22, 0xfcefa3f8);  /* 30 */ +    GG(c, d, a, b, x[7], S23, 0x676f02d9);  /* 31 */ +    GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + +    /* Round 3 */ +    HH(a, b, c, d, x[5], S31, 0xfffa3942);  /* 33 */ +    HH(d, a, b, c, x[8], S32, 0x8771f681);  /* 34 */ +    HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ +    HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ +    HH(a, b, c, d, x[1], S31, 0xa4beea44);  /* 37 */ +    HH(d, a, b, c, x[4], S32, 0x4bdecfa9);  /* 38 */ +    HH(c, d, a, b, x[7], S33, 0xf6bb4b60);  /* 39 */ +    HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ +    HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ +    HH(d, a, b, c, x[0], S32, 0xeaa127fa);  /* 42 */ +    HH(c, d, a, b, x[3], S33, 0xd4ef3085);  /* 43 */ +    HH(b, c, d, a, x[6], S34, 0x4881d05);   /* 44 */ +    HH(a, b, c, d, x[9], S31, 0xd9d4d039);  /* 45 */ +    HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ +    HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ +    HH(b, c, d, a, x[2], S34, 0xc4ac5665);  /* 48 */ + +    /* Round 4 */ +    II(a, b, c, d, x[0], S41, 0xf4292244);  /* 49 */ +    II(d, a, b, c, x[7], S42, 0x432aff97);  /* 50 */ +    II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ +    II(b, c, d, a, x[5], S44, 0xfc93a039);  /* 52 */ +    II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ +    II(d, a, b, c, x[3], S42, 0x8f0ccc92);  /* 54 */ +    II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ +    II(b, c, d, a, x[1], S44, 0x85845dd1);  /* 56 */ +    II(a, b, c, d, x[8], S41, 0x6fa87e4f);  /* 57 */ +    II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ +    II(c, d, a, b, x[6], S43, 0xa3014314);  /* 59 */ +    II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ +    II(a, b, c, d, x[4], S41, 0xf7537e82);  /* 61 */ +    II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ +    II(c, d, a, b, x[2], S43, 0x2ad7d2bb);  /* 63 */ +    II(b, c, d, a, x[9], S44, 0xeb86d391);  /* 64 */ + +    state[0] += a; +    state[1] += b; +    state[2] += c; +    state[3] += d; + +    // Zeroize sensitive information. +    memset(x, 0, sizeof(x));  } - -  // Encodes input (uint32_t) into output (unsigned char). Assumes len is  // a multiple of 4. -void LLMD5::encode (uint8_t *output, const uint32_t *input, const size_t len) { - -  size_t i, j; - -  for (i = 0, j = 0; j < len; i++, j += 4) { -    output[j]   = (uint8_t)  (input[i] & 0xff); -    output[j+1] = (uint8_t) ((input[i] >> 8) & 0xff); -    output[j+2] = (uint8_t) ((input[i] >> 16) & 0xff); -    output[j+3] = (uint8_t) ((input[i] >> 24) & 0xff); -  } +void LLMD5::encode(uint8_t* output, const uint32_t* input, const size_t len) +{ +    for (size_t i = 0, j = 0; j < len; i++, j += 4) +    { +        output[j] = (uint8_t)(input[i] & 0xff); +        output[j + 1] = (uint8_t)((input[i] >> 8) & 0xff); +        output[j + 2] = (uint8_t)((input[i] >> 16) & 0xff); +        output[j + 3] = (uint8_t)((input[i] >> 24) & 0xff); +    }  } - - -  // Decodes input (unsigned char) into output (uint32_t). Assumes len is  // a multiple of 4. -void LLMD5::decode (uint32_t *output, const uint8_t *input, const size_t len){ - -  size_t i, j; - -  for (i = 0, j = 0; j < len; i++, j += 4) -    output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | -      (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24); +void LLMD5::decode(uint32_t* output, const uint8_t* input, const size_t len) +{ +    for (size_t i = 0, j = 0; j < len; i++, j += 4) +        output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | +        (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);  } - - diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index 46c79cf5a2..ad063fda46 100644 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h @@ -67,59 +67,57 @@ documentation and/or software.  */ -#include <cstdint>                  // uint32_t et al. +#include <cstdint> // uint32_t et al.  // use for the raw digest output  const int MD5RAW_BYTES = 16;  // use for outputting hex digests -const int MD5HEX_STR_SIZE = 33;  // char hex[MD5HEX_STR_SIZE]; with null +const int MD5HEX_STR_SIZE  = 33; // char hex[MD5HEX_STR_SIZE]; with null  const int MD5HEX_STR_BYTES = 32; // message system fixed size -class LL_COMMON_API LLMD5 { -// how many bytes to grab at a time when checking files -  static const int BLOCK_LEN; +class LL_COMMON_API LLMD5 +{ +    // how many bytes to grab at a time when checking files +    static const int BLOCK_LEN;  public: -// methods for controlled operation: -  LLMD5              ();  // simple initializer -  void  update     (const uint8_t *input, const size_t input_length); -  void  update     (std::istream& stream); -  void  update     (FILE *file); -  void  update     (const std::string& str); -  void  finalize   (); - -// constructors for special circumstances.  All these constructors finalize -// the MD5 context. -  LLMD5              (const unsigned char *string); // digest string, finalize -  LLMD5              (std::istream& stream);       // digest stream, finalize -  LLMD5              (FILE *file);            // digest file, close, finalize -  LLMD5              (const unsigned char *string, const unsigned int number); - -// methods to acquire finalized result -  void              raw_digest(unsigned char *array) const; // provide 16-byte array for binary data -  void              hex_digest(char *string) const;         // provide 33-byte array for ascii-hex string - -  friend LL_COMMON_API std::ostream&   operator<< (std::ostream&, LLMD5 context); +    // methods for controlled operation: +    LLMD5(); // simple initializer +    void update(const uint8_t* input, const size_t input_length); +    void update(std::istream& stream); +    void update(FILE* file); +    void update(const std::string& str); +    void finalize(); + +    // constructors for special circumstances.  All these constructors finalize +    // the MD5 context. +    LLMD5(const unsigned char* string); // digest string, finalize +    LLMD5(std::istream& stream);        // digest stream, finalize +    LLMD5(FILE* file);                  // digest file, close, finalize +    LLMD5(const unsigned char* string, const unsigned int number); + +    // methods to acquire finalized result +    void raw_digest(unsigned char* array) const; // provide 16-byte array for binary data +    void hex_digest(char* string) const;         // provide 33-byte array for ascii-hex string + +    friend LL_COMMON_API std::ostream& operator<<(std::ostream&, const LLMD5& context);  private: - - -// next, the private data: -  uint32_t state[4]; -  uint64_t count;     // number of *bits*, mod 2^64 -  uint8_t buffer[64];   // input buffer -  uint8_t digest[16]; -  uint8_t finalized; - -// last, the private methods, mostly static: -  void init             ();               // called by all constructors -  void transform        (const uint8_t *buffer);  // does the real update work.  Note -                                          // that length is implied to be 64. - -  static void encode    (uint8_t *dest, const uint32_t *src, const size_t length); -  static void decode    (uint32_t *dest, const uint8_t *src, const size_t length); - +    // next, the private data: +    uint32_t state[4]; +    uint64_t count;      // number of *bits*, mod 2^64 +    uint8_t  buffer[64]; // input buffer +    uint8_t  digest[16]; +    bool     finalized; + +    // last, the private methods, mostly static: +    void init();                           // called by all constructors +    void transform(const uint8_t* buffer); // does the real update work.  Note +                                           // that length is implied to be 64. + +    static void encode(uint8_t* dest, const uint32_t* src, const size_t length); +    static void decode(uint32_t* dest, const uint8_t* src, const size_t length);  };  LL_COMMON_API bool operator==(const LLMD5& a, const LLMD5& b); diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index 6e8cf9643b..62943845a5 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -194,6 +194,18 @@ public:              mSharedMutex->unlock<SHARED>();      } +    void lock() +    { +        if (mSharedMutex) +            mSharedMutex->lock<SHARED>(); +    } + +    void unlock() +    { +        if (mSharedMutex) +            mSharedMutex->unlock<SHARED>(); +    } +  private:      LLSharedMutex* mSharedMutex;  }; diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h index 6edff9fa5e..048547e4cc 100644 --- a/indra/llcommon/llpointer.h +++ b/indra/llcommon/llpointer.h @@ -418,6 +418,17 @@ private:      bool mStayUnique;  }; +template<typename Type> +bool operator!=(Type* lhs, const LLPointer<Type>& rhs) +{ +    return (lhs != rhs.get()); +} + +template<typename Type> +bool operator==(Type* lhs, const LLPointer<Type>& rhs) +{ +    return (lhs == rhs.get()); +}  // boost hash adapter  template <class Type> diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h index 7c6874d279..91c623eae1 100644 --- a/indra/llcommon/llpredicate.h +++ b/indra/llcommon/llpredicate.h @@ -139,7 +139,7 @@ namespace LLPredicate          Rule()          {} -        void require(ENUM e, bool match) +        void mandate(ENUM e, bool match)          {              mRule.set(e, match);          } @@ -154,7 +154,7 @@ namespace LLPredicate              return (mRule && value).someSet();          } -        bool requires(const Value<ENUM> value) const +        bool mandates(const Value<ENUM> value) const          {              return (mRule && value).someSet() && (!mRule && value).noneSet();          } diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index b2378875c3..e9f07f6fdf 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -100,15 +100,6 @@  # define LL_THREAD_LOCAL __thread  #endif -// Static linking with apr on windows needs to be declared. -#if LL_WINDOWS && !LL_COMMON_LINK_SHARED -#ifndef APR_DECLARE_STATIC -#define APR_DECLARE_STATIC // For APR on Windows -#endif -#ifndef APU_DECLARE_STATIC -#define APU_DECLARE_STATIC // For APR util on Windows -#endif -#endif  #if defined(LL_WINDOWS)  #define BOOST_REGEX_NO_LIB 1 @@ -121,13 +112,6 @@  // Deal with VC++ problems  #if LL_MSVC -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS // disable warnings for methods considered unsafe -#endif -#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS -#define _WINSOCK_DEPRECATED_NO_WARNINGS // disable deprecated WinSock API warnings -#endif -  // level 4 warnings that we need to disable:  #pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class  #pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index e7caf1175c..52b5e0f562 100644 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h @@ -29,7 +29,6 @@  #include "llinitparam.h"  #include "llsdparam.h" -#include "llwin32headerslean.h"  #include "llexception.h"  #include "apr_thread_proc.h"  #include <boost/ptr_container/ptr_vector.hpp> @@ -38,7 +37,7 @@  #include <iosfwd>                   // std::ostream  #if LL_WINDOWS -#include "llwin32headerslean.h" // for HANDLE +#include "llwin32headers.h" // for HANDLE  #elif LL_LINUX || __FreeBSD__  #if defined(Status)  #undef Status diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 0e180d9915..1696a165a2 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -34,7 +34,7 @@  //#include <memory>  #if LL_WINDOWS -#   include "llwin32headerslean.h" +#   include "llwin32headers.h"  #   define _interlockedbittestandset _renamed_interlockedbittestandset  #   define _interlockedbittestandreset _renamed_interlockedbittestandreset  #   include <intrin.h> @@ -699,7 +699,8 @@ private:          memset(cpu_vendor, 0, len);          sysctlbyname("machdep.cpu.vendor", (void*)cpu_vendor, &len, NULL, 0);          cpu_vendor[0x1f] = 0; -        setInfo(eVendor, cpu_vendor); +        // M series CPUs don't provide this field so if empty, just fall back to Apple. +        setInfo(eVendor, (cpu_vendor[0] != '\0') ? cpu_vendor : "Apple");          setInfo(eStepping, getSysctlInt("machdep.cpu.stepping"));          setInfo(eModel, getSysctlInt("machdep.cpu.model")); diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp index 5d38e55686..655869a704 100644 --- a/indra/llcommon/llsdjson.cpp +++ b/indra/llcommon/llsdjson.cpp @@ -61,12 +61,21 @@ LLSD LlsdFromJson(const boost::json::value& val)          result = LLSD(val.as_bool());          break;      case boost::json::kind::array: +    {          result = LLSD::emptyArray(); -        for (const auto &element : val.as_array()) +        const boost::json::array& array = val.as_array(); +        size_t size = array.size(); +        // allocate elements 0 .. (size() - 1) to avoid incremental allocation +        if (! array.empty()) +        { +            result[size - 1] = LLSD(); +        } +        for (size_t i = 0; i < size; i++)          { -            result.append(LlsdFromJson(element)); +            result[i] = (LlsdFromJson(array[i]));          }          break; +    }      case boost::json::kind::object:          result = LLSD::emptyMap();          for (const auto& element : val.as_object()) @@ -106,6 +115,7 @@ boost::json::value LlsdToJson(const LLSD &val)      case LLSD::TypeMap:      {          boost::json::object& obj = result.emplace_object(); +        obj.reserve(val.size());          for (const auto& llsd_dat : llsd::inMap(val))          {              obj[llsd_dat.first] = LlsdToJson(llsd_dat.second); @@ -115,6 +125,7 @@ boost::json::value LlsdToJson(const LLSD &val)      case LLSD::TypeArray:      {          boost::json::array& json_array = result.emplace_array(); +        json_array.reserve(val.size());          for (const auto& llsd_dat : llsd::inArray(val))          {              json_array.push_back(LlsdToJson(llsd_dat)); @@ -123,7 +134,8 @@ boost::json::value LlsdToJson(const LLSD &val)      }      case LLSD::TypeBinary:      default: -        LL_ERRS("LlsdToJson") << "Unsupported conversion to JSON from LLSD type (" << val.type() << ")." << LL_ENDL; +        LL_ERRS("LlsdToJson") << "Unsupported conversion to JSON from LLSD type (" +                              << val.type() << ")." << LL_ENDL;          break;      } diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 23ac52956d..9fa27cee78 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -32,8 +32,7 @@  #include <sstream>  #if LL_WINDOWS -#   define WIN32_LEAN_AND_MEAN -#   include <winsock2.h>    // for htonl +#   include "llwin32headers.h" // for htonl  #elif LL_LINUX  #   include <netinet/in.h>  #elif LL_DARWIN || __FreeBSD__ diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp index ca8f4299d9..c223c26bb0 100644 --- a/indra/llcommon/llstacktrace.cpp +++ b/indra/llcommon/llstacktrace.cpp @@ -32,7 +32,7 @@  #include <iostream>  #include <sstream> -#include "llwin32headerslean.h" +#include "llwin32headers.h"  #include <dbghelp.h>  typedef USHORT NTAPI RtlCaptureStackBackTrace_Function( diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index 06cf8d3480..d756aca62b 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -41,6 +41,13 @@ public:      LLStrider(Object* first) { mObjectp = first; mSkip = sizeof(Object); }      ~LLStrider() { } +    const LLStrider<Object>& operator=(const LLStrider<Object>& rhs) +    { +        mBytep = rhs.mBytep; +        mSkip = rhs.mSkip; +        return *this; +    } +      const LLStrider<Object>& operator =  (Object *first)    { mObjectp = first; return *this;}      void setStride (S32 skipBytes)  { mSkip = (skipBytes ? skipBytes : sizeof(Object));} diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 505789f9ea..07adf71d18 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -33,8 +33,7 @@  #include <vector>  #if LL_WINDOWS -#include "llwin32headerslean.h" -#include <winnls.h> // for WideCharToMultiByte +#include "llwin32headers.h"  #endif  std::string ll_safe_string(const char* in) @@ -1410,6 +1409,14 @@ bool LLStringUtil::simpleReplacement(std::string &replacement, std::string token  template<>  void LLStringUtil::setLocale(std::string inLocale)  { +    if(startsWith(inLocale, "MissingString")) +    { +        // it seems this hasn't been working for some time, and I'm not sure how it is intentded to +        // properly discover the correct locale.  early out now to avoid failures later in +        // formatNumber() +        LL_WARNS() << "Failed attempting to set invalid locale: " << inLocale << LL_ENDL; +        return; +    }      sLocale = inLocale;  }; diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 4e85618b2d..94d59adf29 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -59,7 +59,7 @@  using namespace llsd;  #if LL_WINDOWS -#   include "llwin32headerslean.h" +#   include "llwin32headers.h"  #   include <psapi.h>               // GetPerformanceInfo() et al.  #   include <VersionHelpers.h>  #elif LL_DARWIN diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index d85b1bbfee..4e15ae29a9 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -34,7 +34,7 @@  #include <thread>  #if LL_WINDOWS -#   include "llwin32headerslean.h" +#   include "llwin32headers.h"  #elif LL_LINUX || LL_DARWIN || __FreeBSD__  #   include <errno.h>  #   include <sys/time.h> diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index eb7233a21a..6d7cf473f5 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -25,11 +25,8 @@  #include "linden_common.h" - // We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes.  #if LL_WINDOWS  #include "llwin32headers.h" -// ugh, this is ugly.  We need to straighten out our linking for this library -#pragma comment(lib, "IPHLPAPI.lib")  #include <iphlpapi.h>  #include <nb30.h>  #endif diff --git a/indra/llcommon/llwin32headers.h b/indra/llcommon/llwin32headers.h index f679adc200..df433deb7a 100644 --- a/indra/llcommon/llwin32headers.h +++ b/indra/llcommon/llwin32headers.h @@ -28,15 +28,8 @@  #define LL_LLWINDOWS_H  #ifdef LL_WINDOWS -#ifndef NOMINMAX -#define NOMINMAX -#endif -#undef WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> -// reset to default, which is lean -#define WIN32_LEAN_AND_MEAN -#undef NOMINMAX +#include <windows.h> // Does not include winsock.h because WIN32_LEAN_AND_MEAN is defined +#include <winsock2.h> // Requires windows.h  #endif  #endif diff --git a/indra/llcommon/llwin32headerslean.h b/indra/llcommon/llwin32headerslean.h deleted file mode 100644 index 97c8edb8cf..0000000000 --- a/indra/llcommon/llwin32headerslean.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file llwin32headerslean.h - * @brief sanitized include of windows header files - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLWINDOWS_H -#define LL_LLWINDOWS_H - -#ifdef LL_WINDOWS -#ifndef NOMINMAX -#define NOMINMAX -#endif -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> -#undef NOMINMAX -#endif - -#endif | 
