tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

xpctest_params.cpp (15586B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "xpctest_private.h"
      6 #include "xpctest_interfaces.h"
      7 #include "mozilla/Casting.h"
      8 #include "js/Value.h"
      9 
     10 #include "nsCOMPtr.h"
     11 #include "nsComponentManagerUtils.h"
     12 #include "nsIURI.h"
     13 
     14 using namespace mozilla;
     15 
     16 NS_IMPL_ISUPPORTS(nsXPCTestParams, nsIXPCTestParams)
     17 
     18 #define GENERIC_METHOD_IMPL \
     19  {                         \
     20    *_retval = *b;          \
     21    *b = a;                 \
     22    return NS_OK;           \
     23  }
     24 
     25 #define STRING_METHOD_IMPL \
     26  {                        \
     27    _retval.Assign(b);     \
     28    b.Assign(a);           \
     29    return NS_OK;          \
     30  }
     31 
     32 #define SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP)                        \
     33  {                                                                 \
     34    _retval = std::move(b);                                         \
     35    b = a.Clone();                                                  \
     36    for (uint32_t i = 0; i < b.Length(); ++i) TAKE_OWNERSHIP(b[i]); \
     37    return NS_OK;                                                   \
     38  }
     39 
     40 #define TAKE_OWNERSHIP_NOOP(val) \
     41  {                              \
     42  }
     43 #define TAKE_OWNERSHIP_INTERFACE(val)         \
     44  {                                           \
     45    static_cast<nsISupports*>(val)->AddRef(); \
     46  }
     47 #define TAKE_OWNERSHIP_STRING(val)  \
     48  {                                 \
     49    nsDependentCString vprime(val); \
     50    val = ToNewCString(vprime);     \
     51  }
     52 #define TAKE_OWNERSHIP_WSTRING(val) \
     53  {                                 \
     54    nsDependentString vprime(val);  \
     55    val = ToNewUnicode(vprime);     \
     56  }
     57 
     58 // Macro for our buffer-oriented types:
     59 //   'type' is the type of element that the buffer contains.
     60 //   'padding' is an offset added to length, allowing us to handle
     61 //             null-terminated strings.
     62 //   'TAKE_OWNERSHIP' is one of the macros above.
     63 #define BUFFER_METHOD_IMPL(type, padding, TAKE_OWNERSHIP)                      \
     64  {                                                                            \
     65    uint32_t elemSize = sizeof(type);                                          \
     66                                                                               \
     67    /* Copy b into rv. */                                                      \
     68    *rvLength = *bLength;                                                      \
     69    *rv = static_cast<type*>(moz_xmalloc(elemSize * (*bLength + padding)));    \
     70    memcpy(*rv, *b, elemSize*(*bLength + padding));                            \
     71                                                                               \
     72    /* Copy a into b. */                                                       \
     73    *bLength = aLength;                                                        \
     74    free(*b);                                                                  \
     75    *b = static_cast<type*>(moz_xmalloc(elemSize * (aLength + padding)));      \
     76    memcpy(*b, a, elemSize*(aLength + padding));                               \
     77                                                                               \
     78    /* We need to take ownership of the data we got from a,                    \
     79       since the caller owns it. */                                            \
     80    for (unsigned i = 0; i < *bLength + padding; ++i) TAKE_OWNERSHIP((*b)[i]); \
     81                                                                               \
     82    return NS_OK;                                                              \
     83  }
     84 
     85 NS_IMETHODIMP nsXPCTestParams::TestBoolean(bool a, bool* b, bool* _retval) {
     86  GENERIC_METHOD_IMPL;
     87 }
     88 
     89 NS_IMETHODIMP nsXPCTestParams::TestOctet(uint8_t a, uint8_t* b,
     90                                         uint8_t* _retval) {
     91  GENERIC_METHOD_IMPL;
     92 }
     93 
     94 NS_IMETHODIMP nsXPCTestParams::TestShort(int16_t a, int16_t* b,
     95                                         int16_t* _retval) {
     96  GENERIC_METHOD_IMPL;
     97 }
     98 
     99 NS_IMETHODIMP nsXPCTestParams::TestLong(int32_t a, int32_t* b,
    100                                        int32_t* _retval) {
    101  GENERIC_METHOD_IMPL;
    102 }
    103 
    104 NS_IMETHODIMP nsXPCTestParams::TestLongLong(int64_t a, int64_t* b,
    105                                            int64_t* _retval) {
    106  GENERIC_METHOD_IMPL;
    107 }
    108 
    109 NS_IMETHODIMP nsXPCTestParams::TestUnsignedShort(uint16_t a, uint16_t* b,
    110                                                 uint16_t* _retval) {
    111  GENERIC_METHOD_IMPL;
    112 }
    113 
    114 NS_IMETHODIMP nsXPCTestParams::TestUnsignedLong(uint32_t a, uint32_t* b,
    115                                                uint32_t* _retval) {
    116  GENERIC_METHOD_IMPL;
    117 }
    118 
    119 NS_IMETHODIMP nsXPCTestParams::TestUnsignedLongLong(uint64_t a, uint64_t* b,
    120                                                    uint64_t* _retval) {
    121  GENERIC_METHOD_IMPL;
    122 }
    123 
    124 NS_IMETHODIMP nsXPCTestParams::TestFloat(float a, float* b, float* _retval) {
    125  GENERIC_METHOD_IMPL;
    126 }
    127 
    128 NS_IMETHODIMP nsXPCTestParams::TestDouble(double a, float* b, double* _retval) {
    129  GENERIC_METHOD_IMPL;
    130 }
    131 
    132 NS_IMETHODIMP nsXPCTestParams::TestChar(char a, char* b, char* _retval) {
    133  GENERIC_METHOD_IMPL;
    134 }
    135 
    136 NS_IMETHODIMP nsXPCTestParams::TestString(const char* a, char** b,
    137                                          char** _retval) {
    138  nsDependentCString aprime(a);
    139  nsDependentCString bprime(*b);
    140  *_retval = ToNewCString(bprime);
    141  *b = ToNewCString(aprime);
    142 
    143  // XPCOM ownership rules dictate that overwritten inout params must be
    144  // callee-freed. See https://developer.mozilla.org/en/XPIDL
    145  free(const_cast<char*>(bprime.get()));
    146 
    147  return NS_OK;
    148 }
    149 
    150 NS_IMETHODIMP nsXPCTestParams::TestWchar(char16_t a, char16_t* b,
    151                                         char16_t* _retval) {
    152  GENERIC_METHOD_IMPL;
    153 }
    154 
    155 NS_IMETHODIMP nsXPCTestParams::TestWstring(const char16_t* a, char16_t** b,
    156                                           char16_t** _retval) {
    157  nsDependentString aprime(a);
    158  nsDependentString bprime(*b);
    159  *_retval = ToNewUnicode(bprime);
    160  *b = ToNewUnicode(aprime);
    161 
    162  // XPCOM ownership rules dictate that overwritten inout params must be
    163  // callee-freed. See https://developer.mozilla.org/en/XPIDL
    164  free((void*)bprime.get());
    165 
    166  return NS_OK;
    167 }
    168 
    169 NS_IMETHODIMP nsXPCTestParams::TestAString(const nsAString& a, nsAString& b,
    170                                           nsAString& _retval) {
    171  STRING_METHOD_IMPL;
    172 }
    173 
    174 NS_IMETHODIMP nsXPCTestParams::TestAUTF8String(const nsACString& a,
    175                                               nsACString& b,
    176                                               nsACString& _retval) {
    177  STRING_METHOD_IMPL;
    178 }
    179 
    180 NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString& a, nsACString& b,
    181                                            nsACString& _retval) {
    182  STRING_METHOD_IMPL;
    183 }
    184 
    185 NS_IMETHODIMP nsXPCTestParams::TestJsval(JS::Handle<JS::Value> a,
    186                                         JS::MutableHandle<JS::Value> b,
    187                                         JS::MutableHandle<JS::Value> _retval) {
    188  _retval.set(b);
    189  b.set(a);
    190  return NS_OK;
    191 }
    192 
    193 NS_IMETHODIMP nsXPCTestParams::TestShortArray(uint32_t aLength, int16_t* a,
    194                                              uint32_t* bLength, int16_t** b,
    195                                              uint32_t* rvLength,
    196                                              int16_t** rv) {
    197  BUFFER_METHOD_IMPL(int16_t, 0, TAKE_OWNERSHIP_NOOP);
    198 }
    199 
    200 NS_IMETHODIMP nsXPCTestParams::TestDoubleArray(uint32_t aLength, double* a,
    201                                               uint32_t* bLength, double** b,
    202                                               uint32_t* rvLength,
    203                                               double** rv) {
    204  BUFFER_METHOD_IMPL(double, 0, TAKE_OWNERSHIP_NOOP);
    205 }
    206 
    207 NS_IMETHODIMP nsXPCTestParams::TestByteArrayOptionalLength(uint8_t* a,
    208                                                           uint32_t aLength,
    209                                                           uint32_t* rv) {
    210  *rv = aLength;
    211  return NS_OK;
    212 }
    213 
    214 NS_IMETHODIMP nsXPCTestParams::TestStringArray(uint32_t aLength, const char** a,
    215                                               uint32_t* bLength, char*** b,
    216                                               uint32_t* rvLength, char*** rv) {
    217  BUFFER_METHOD_IMPL(char*, 0, TAKE_OWNERSHIP_STRING);
    218 }
    219 
    220 NS_IMETHODIMP nsXPCTestParams::TestWstringArray(
    221    uint32_t aLength, const char16_t** a, uint32_t* bLength, char16_t*** b,
    222    uint32_t* rvLength, char16_t*** rv) {
    223  BUFFER_METHOD_IMPL(char16_t*, 0, TAKE_OWNERSHIP_WSTRING);
    224 }
    225 
    226 NS_IMETHODIMP nsXPCTestParams::TestInterfaceArray(
    227    uint32_t aLength, nsIXPCTestInterfaceA** a, uint32_t* bLength,
    228    nsIXPCTestInterfaceA*** b, uint32_t* rvLength, nsIXPCTestInterfaceA*** rv) {
    229  BUFFER_METHOD_IMPL(nsIXPCTestInterfaceA*, 0, TAKE_OWNERSHIP_INTERFACE);
    230 }
    231 
    232 NS_IMETHODIMP nsXPCTestParams::TestJsvalArray(uint32_t aLength, JS::Value* a,
    233                                              uint32_t* bLength, JS::Value** b,
    234                                              uint32_t* rvLength,
    235                                              JS::Value** rv) {
    236  BUFFER_METHOD_IMPL(JS::Value, 0, TAKE_OWNERSHIP_NOOP);
    237 }
    238 
    239 NS_IMETHODIMP nsXPCTestParams::TestSizedString(uint32_t aLength, const char* a,
    240                                               uint32_t* bLength, char** b,
    241                                               uint32_t* rvLength, char** rv) {
    242  BUFFER_METHOD_IMPL(char, 1, TAKE_OWNERSHIP_NOOP);
    243 }
    244 
    245 NS_IMETHODIMP nsXPCTestParams::TestSizedWstring(uint32_t aLength,
    246                                                const char16_t* a,
    247                                                uint32_t* bLength, char16_t** b,
    248                                                uint32_t* rvLength,
    249                                                char16_t** rv) {
    250  BUFFER_METHOD_IMPL(char16_t, 1, TAKE_OWNERSHIP_NOOP);
    251 }
    252 
    253 NS_IMETHODIMP nsXPCTestParams::TestInterfaceIs(const nsIID* aIID, void* a,
    254                                               nsIID** bIID, void** b,
    255                                               nsIID** rvIID, void** rv) {
    256  //
    257  // Getting the buffers and ownership right here can be a little tricky.
    258  //
    259 
    260  // The interface pointers are heap-allocated, and b has been AddRef'd
    261  // by XPConnect for the duration of the call. If we snatch it away from b
    262  // and leave no trace, XPConnect won't Release it. Since we also need to
    263  // return an already-AddRef'd pointer in rv, we don't need to do anything
    264  // special here.
    265  *rv = *b;
    266 
    267  // rvIID is out-only, so nobody allocated an IID buffer for us. Do that now,
    268  // and store b's IID in the new buffer.
    269  *rvIID = static_cast<nsIID*>(moz_xmalloc(sizeof(nsID)));
    270  **rvIID = **bIID;
    271 
    272  // Copy the interface pointer from a to b. Since a is in-only, XPConnect will
    273  // release it upon completion of the call. AddRef it for b.
    274  *b = a;
    275  static_cast<nsISupports*>(*b)->AddRef();
    276 
    277  // We already had a buffer allocated for b's IID, so we can re-use it.
    278  **bIID = *aIID;
    279 
    280  return NS_OK;
    281 }
    282 
    283 NS_IMETHODIMP nsXPCTestParams::TestInterfaceIsArray(
    284    uint32_t aLength, const nsIID* aIID, void** a, uint32_t* bLength,
    285    nsIID** bIID, void*** b, uint32_t* rvLength, nsIID** rvIID, void*** rv) {
    286  // Transfer the IIDs. See the comments in TestInterfaceIs (above) for an
    287  // explanation of what we're doing.
    288  *rvIID = static_cast<nsIID*>(moz_xmalloc(sizeof(nsID)));
    289  **rvIID = **bIID;
    290  **bIID = *aIID;
    291 
    292  // The macro is agnostic to the actual interface types, so we can re-use code
    293  // here.
    294  //
    295  // Do this second, since the macro returns.
    296  BUFFER_METHOD_IMPL(void*, 0, TAKE_OWNERSHIP_INTERFACE);
    297 }
    298 
    299 NS_IMETHODIMP nsXPCTestParams::TestOutAString(nsAString& o) {
    300  o.AssignLiteral("out");
    301  return NS_OK;
    302 }
    303 
    304 NS_IMETHODIMP nsXPCTestParams::TestStringArrayOptionalSize(const char** a,
    305                                                           uint32_t length,
    306                                                           nsACString& out) {
    307  out.Truncate();
    308  for (uint32_t i = 0; i < length; ++i) {
    309    out.Append(a[i]);
    310  }
    311 
    312  return NS_OK;
    313 }
    314 
    315 NS_IMETHODIMP
    316 nsXPCTestParams::TestShortSequence(const nsTArray<short>& a, nsTArray<short>& b,
    317                                   nsTArray<short>& _retval) {
    318  SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
    319 }
    320 
    321 NS_IMETHODIMP
    322 nsXPCTestParams::TestDoubleSequence(const nsTArray<double>& a,
    323                                    nsTArray<double>& b,
    324                                    nsTArray<double>& _retval) {
    325  SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
    326 }
    327 
    328 NS_IMETHODIMP
    329 nsXPCTestParams::TestInterfaceSequence(
    330    const nsTArray<RefPtr<nsIXPCTestInterfaceA>>& a,
    331    nsTArray<RefPtr<nsIXPCTestInterfaceA>>& b,
    332    nsTArray<RefPtr<nsIXPCTestInterfaceA>>& _retval) {
    333  SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
    334 }
    335 
    336 NS_IMETHODIMP
    337 nsXPCTestParams::TestAStringSequence(const nsTArray<nsString>& a,
    338                                     nsTArray<nsString>& b,
    339                                     nsTArray<nsString>& _retval) {
    340  SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
    341 }
    342 
    343 NS_IMETHODIMP
    344 nsXPCTestParams::TestACStringSequence(const nsTArray<nsCString>& a,
    345                                      nsTArray<nsCString>& b,
    346                                      nsTArray<nsCString>& _retval) {
    347  SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
    348 }
    349 
    350 NS_IMETHODIMP
    351 nsXPCTestParams::TestJsvalSequence(const nsTArray<JS::Value>& a,
    352                                   nsTArray<JS::Value>& b,
    353                                   nsTArray<JS::Value>& _retval) {
    354  SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
    355 }
    356 
    357 NS_IMETHODIMP
    358 nsXPCTestParams::TestSequenceSequence(const nsTArray<nsTArray<short>>& a,
    359                                      nsTArray<nsTArray<short>>& b,
    360                                      nsTArray<nsTArray<short>>& _retval) {
    361  _retval = std::move(b);
    362  for (const auto& element : a) {
    363    b.AppendElement(element.Clone());
    364  }
    365  return NS_OK;
    366 }
    367 
    368 NS_IMETHODIMP
    369 nsXPCTestParams::TestInterfaceIsSequence(const nsIID* aIID,
    370                                         const nsTArray<void*>& a, nsIID** bIID,
    371                                         nsTArray<void*>& b, nsIID** rvIID,
    372                                         nsTArray<void*>& _retval) {
    373  // Shuffle around our nsIIDs
    374  *rvIID = (*bIID)->Clone();
    375  *bIID = aIID->Clone();
    376 
    377  // Perform the generic sequence shuffle.
    378  SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_INTERFACE);
    379 }
    380 
    381 NS_IMETHODIMP
    382 nsXPCTestParams::TestOptionalSequence(const nsTArray<uint8_t>& aInArr,
    383                                      nsTArray<uint8_t>& aReturnArr) {
    384  aReturnArr = aInArr.Clone();
    385  return NS_OK;
    386 }
    387 
    388 NS_IMETHODIMP
    389 nsXPCTestParams::TestOmittedOptionalOut(nsIXPCTestParams* aJSObj,
    390                                        nsIURI** aOut) {
    391  MOZ_ASSERT(!(*aOut), "Unexpected value received");
    392  // Call the js component, to check XPConnect won't crash when passing nullptr
    393  // as the optional out parameter, and that the out object is built regardless.
    394  nsresult rv;
    395  // Invoke it directly passing nullptr.
    396  rv = aJSObj->TestOmittedOptionalOut(nullptr, nullptr);
    397  NS_ENSURE_SUCCESS(rv, rv);
    398  // Also invoke it with a ref pointer.
    399  nsCOMPtr<nsIURI> someURI;
    400  rv = aJSObj->TestOmittedOptionalOut(nullptr, getter_AddRefs(someURI));
    401  NS_ENSURE_SUCCESS(rv, rv);
    402  nsAutoCString spec;
    403  rv = someURI->GetSpec(spec);
    404  if (!spec.EqualsLiteral("http://example.com/")) {
    405    return NS_ERROR_UNEXPECTED;
    406  }
    407  someURI.forget(aOut);
    408  return NS_OK;
    409 }
    410 
    411 NS_IMETHODIMP
    412 nsXPCTestParams::GetTestNaN(double* aResult) {
    413  *aResult =
    414      BitwiseCast<double>((uint64_t(JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) + 1);
    415  return NS_OK;
    416 }