void
EventListenerManager::AddEventListenerInternal(
                        const EventListenerHolder& aListenerHolder,
                        uint32_t aType,
                        nsIAtom* aTypeAtom,
                        const nsAString& aTypeString,
                        const EventListenerFlags& aFlags,
                        bool aHandler,
                        bool aAllEvents)
{
  MOZ_ASSERT((NS_IsMainThread() && aType && aTypeAtom) || // Main thread
             (!NS_IsMainThread() && aType && !aTypeString.IsEmpty()) || // non-main-thread
             aAllEvents, "Missing type"); // all-events listener

  if (!aListenerHolder || mClearingListeners) {
    return;
  }

  // Since there is no public API to call us with an EventListenerHolder, we
  // know that there's an EventListenerHolder on the stack holding a strong ref
  // to the listener.

  Listener* listener;
  uint32_t count = mListeners.Length();
  for (uint32_t i = 0; i < count; i++) {
    listener = &mListeners.ElementAt(i);
    // mListener == aListenerHolder is the last one, since it can be a bit slow.
    if (listener->mListenerIsHandler == aHandler &&
        listener->mFlags == aFlags &&
        EVENT_TYPE_EQUALS(listener, aType, aTypeAtom, aTypeString,
                          aAllEvents) &&
        listener->mListener == aListenerHolder) {
      return;
    }
  }

  mNoListenerForEvent = NS_EVENT_NULL;
  mNoListenerForEventAtom = nullptr;

  listener = aAllEvents ? mListeners.InsertElementAt(0) :
                          mListeners.AppendElement();
  listener->mListener = aListenerHolder;
  MOZ_ASSERT(aType < PR_UINT16_MAX);
  listener->mEventType = aType;
  listener->mTypeString = aTypeString;
  listener->mTypeAtom = aTypeAtom;
  listener->mFlags = aFlags;
  listener->mListenerIsHandler = aHandler;
  listener->mHandlerIsString = false;
  listener->mAllEvents = aAllEvents;

  // Detect the type of event listener.
  nsCOMPtr<nsIXPConnectWrappedJS> wjs;
  if (aFlags.mListenerIsJSListener) {
    MOZ_ASSERT(!aListenerHolder.HasWebIDLCallback());
    listener->mListenerType = Listener::eJSEventListener;
  } else if (aListenerHolder.HasWebIDLCallback()) {
    listener->mListenerType = Listener::eWebIDLListener;
  } else if ((wjs = do_QueryInterface(aListenerHolder.GetXPCOMCallback()))) {
    listener->mListenerType = Listener::eWrappedJSListener;
  } else {
    listener->mListenerType = Listener::eNativeListener;
  }


  if (aFlags.mInSystemGroup) {
    mMayHaveSystemGroupListeners = true;
  }
  if (aFlags.mCapture) {
    mMayHaveCapturingListeners = true;
  }

  if (aType == NS_AFTERPAINT) {
    mMayHavePaintEventListener = true;
    nsPIDOMWindow* window = GetInnerWindowForTarget();
    if (window) {
      window->SetHasPaintEventListeners();
    }
  } else if (aType >= NS_MUTATION_START && aType <= NS_MUTATION_END) {
    // For mutation listeners, we need to update the global bit on the DOM window.
    // Otherwise we won't actually fire the mutation event.
    mMayHaveMutationListeners = true;
    // Go from our target to the nearest enclosing DOM window.
    nsPIDOMWindow* window = GetInnerWindowForTarget();
    if (window) {
      nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
      if (doc) {
        doc->WarnOnceAbout(nsIDocument::eMutationEvent);
      }
      // If aType is NS_MUTATION_SUBTREEMODIFIED, we need to listen all
      // mutations. nsContentUtils::HasMutationListeners relies on this.
      window->SetMutationListeners((aType == NS_MUTATION_SUBTREEMODIFIED) ?
                                   kAllMutationBits :
                                   MutationBitForEventType(aType));
    }
  } else if (aTypeAtom == nsGkAtoms::ondeviceorientation) {
    EnableDevice(NS_DEVICE_ORIENTATION);
  } else if (aTypeAtom == nsGkAtoms::ondeviceproximity || aTypeAtom == nsGkAtoms::onuserproximity) {
    EnableDevice(NS_DEVICE_PROXIMITY);
  } else if (aTypeAtom == nsGkAtoms::ondevicelight) {
    EnableDevice(NS_DEVICE_LIGHT);
  } else if (aTypeAtom == nsGkAtoms::ondevicemotion) {
    EnableDevice(NS_DEVICE_MOTION);
#ifdef MOZ_B2G
  } else if (aTypeAtom == nsGkAtoms::onmoztimechange) {
    nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
    if (window) {
      window->EnableTimeChangeNotifications();
    }
  } else if (aTypeAtom == nsGkAtoms::onmoznetworkupload) {
    nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
    if (window) {
      window->EnableNetworkEvent(NS_NETWORK_UPLOAD_EVENT);
    }
  } else if (aTypeAtom == nsGkAtoms::onmoznetworkdownload) {
    nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
    if (window) {
      window->EnableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT);
    }
#endif // MOZ_B2G
  } else if (aTypeAtom == nsGkAtoms::ontouchstart ||
             aTypeAtom == nsGkAtoms::ontouchend ||
             aTypeAtom == nsGkAtoms::ontouchmove ||
             aTypeAtom == nsGkAtoms::ontouchcancel) {
    mMayHaveTouchEventListener = true;
    nsPIDOMWindow* window = GetInnerWindowForTarget();
    // we don't want touchevent listeners added by scrollbars to flip this flag
    // so we ignore listeners created with system event flag
    if (window && !aFlags.mInSystemGroup) {
      window->SetHasTouchEventListeners();
    }
  } else if (aTypeAtom == nsGkAtoms::onwheel ||
             aTypeAtom == nsGkAtoms::onDOMMouseScroll ||
             aTypeAtom == nsHtml5Atoms::onmousewheel) {
    mMayHaveScrollWheelEventListener = true;
    nsPIDOMWindow* window = GetInnerWindowForTarget();
    // we don't want touchevent listeners added by scrollbars to flip this flag
    // so we ignore listeners created with system event flag
    if (window && !aFlags.mInSystemGroup) {
      window->SetHasScrollWheelEventListeners();
    }
  } else if (aType >= NS_POINTER_EVENT_START && aType <= NS_POINTER_LOST_CAPTURE) {
    nsPIDOMWindow* window = GetInnerWindowForTarget();
    if (aTypeAtom == nsGkAtoms::onpointerenter ||
        aTypeAtom == nsGkAtoms::onpointerleave) {
      mMayHavePointerEnterLeaveEventListener = true;
      if (window) {
#ifdef DEBUG
        nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
        NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d),
                         "Please do not use pointerenter/leave events in chrome. "
                         "They are slower than pointerover/out!");
#endif
        window->SetHasPointerEnterLeaveEventListeners();
      }
    }
  } else if (aTypeAtom == nsGkAtoms::onmouseenter ||
             aTypeAtom == nsGkAtoms::onmouseleave) {
    mMayHaveMouseEnterLeaveEventListener = true;
    nsPIDOMWindow* window = GetInnerWindowForTarget();
    if (window) {
#ifdef DEBUG
      nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
      NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d),
                       "Please do not use mouseenter/leave events in chrome. "
                       "They are slower than mouseover/out!");
#endif
      window->SetHasMouseEnterLeaveEventListeners();
    }
#ifdef MOZ_GAMEPAD
  } else if (aType >= NS_GAMEPAD_START &&
             aType <= NS_GAMEPAD_END) {
    nsPIDOMWindow* window = GetInnerWindowForTarget();
    if (window) {
      window->SetHasGamepadEventListener();
    }
#endif
  }
  if (aTypeAtom && mTarget) {
    mTarget->EventListenerAdded(aTypeAtom);
  }
}
Ejemplo n.º 2
0
already_AddRefed<nsITransferable>
DataTransfer::GetTransferable(uint32_t aIndex, nsILoadContext* aLoadContext)
{
  if (aIndex >= MozItemCount()) {
    return nullptr;
  }

  const nsTArray<RefPtr<DataTransferItem>>& item = *mItems->MozItemsAt(aIndex);
  uint32_t count = item.Length();
  if (!count) {
    return nullptr;
  }

  nsCOMPtr<nsITransferable> transferable =
    do_CreateInstance("@mozilla.org/widget/transferable;1");
  if (!transferable) {
    return nullptr;
  }
  transferable->Init(aLoadContext);

  nsCOMPtr<nsIStorageStream> storageStream;
  nsCOMPtr<nsIObjectOutputStream> stream;

  bool added = false;
  bool handlingCustomFormats = true;

  // When writing the custom data, we need to ensure that there is sufficient
  // space for a (uint32_t) data ending type, and the null byte character at
  // the end of the nsCString. We claim that space upfront and store it in
  // baseLength. This value will be set to zero if a write error occurs
  // indicating that the data and length are no longer valid.
  const uint32_t baseLength = sizeof(uint32_t) + 1;
  uint32_t totalCustomLength = baseLength;

  const char* knownFormats[] = {
    kTextMime, kHTMLMime, kNativeHTMLMime, kRTFMime,
    kURLMime, kURLDataMime, kURLDescriptionMime, kURLPrivateMime,
    kPNGImageMime, kJPEGImageMime, kGIFImageMime, kNativeImageMime,
    kFileMime, kFilePromiseMime, kFilePromiseURLMime,
    kFilePromiseDestFilename, kFilePromiseDirectoryMime,
    kMozTextInternal, kHTMLContext, kHTMLInfo, kImageRequestMime };

  /*
   * Two passes are made here to iterate over all of the types. First, look for
   * any types that are not in the list of known types. For this pass,
   * handlingCustomFormats will be true. Data that corresponds to unknown types
   * will be pulled out and inserted into a single type (kCustomTypesMime) by
   * writing the data into a stream.
   *
   * The second pass will iterate over the formats looking for known types.
   * These are added as is. The unknown types are all then inserted as a single
   * type (kCustomTypesMime) in the same position of the first custom type. This
   * model is used to maintain the format order as best as possible.
   *
   * The format of the kCustomTypesMime type is one or more of the following
   * stored sequentially:
   *   <32-bit> type (only none or string is supported)
   *   <32-bit> length of format
   *   <wide string> format
   *   <32-bit> length of data
   *   <wide string> data
   * A type of eCustomClipboardTypeId_None ends the list, without any following
   * data.
   */
  do {
    for (uint32_t f = 0; f < count; f++) {
      RefPtr<DataTransferItem> formatitem = item[f];
      nsCOMPtr<nsIVariant> variant = formatitem->DataNoSecurityCheck();
      if (!variant) { // skip empty items
        continue;
      }

      nsAutoString type;
      formatitem->GetInternalType(type);

      // If the data is of one of the well-known formats, use it directly.
      bool isCustomFormat = true;
      for (uint32_t f = 0; f < ArrayLength(knownFormats); f++) {
        if (type.EqualsASCII(knownFormats[f])) {
          isCustomFormat = false;
          break;
        }
      }

      uint32_t lengthInBytes;
      nsCOMPtr<nsISupports> convertedData;

      if (handlingCustomFormats) {
        if (!ConvertFromVariant(variant, getter_AddRefs(convertedData),
                                &lengthInBytes)) {
          continue;
        }

        // When handling custom types, add the data to the stream if this is a
        // custom type. If totalCustomLength is 0, then a write error occurred
        // on a previous item, so ignore any others.
        if (isCustomFormat && totalCustomLength > 0) {
          // If it isn't a string, just ignore it. The dataTransfer is cached in
          // the drag sesion during drag-and-drop, so non-strings will be
          // available when dragging locally.
          nsCOMPtr<nsISupportsString> str(do_QueryInterface(convertedData));
          if (str) {
            nsAutoString data;
            str->GetData(data);

            if (!stream) {
              // Create a storage stream to write to.
              NS_NewStorageStream(1024, UINT32_MAX, getter_AddRefs(storageStream));

              nsCOMPtr<nsIOutputStream> outputStream;
              storageStream->GetOutputStream(0, getter_AddRefs(outputStream));

              stream = NS_NewObjectOutputStream(outputStream);
            }

            CheckedInt<uint32_t> formatLength =
              CheckedInt<uint32_t>(type.Length()) * sizeof(nsString::char_type);

            // The total size of the stream is the format length, the data
            // length, two integers to hold the lengths and one integer for
            // the string flag. Guard against large data by ignoring any that
            // don't fit.
            CheckedInt<uint32_t> newSize = formatLength + totalCustomLength +
                                           lengthInBytes + (sizeof(uint32_t) * 3);
            if (newSize.isValid()) {
              // If a write error occurs, set totalCustomLength to 0 so that
              // further processing gets ignored.
              nsresult rv = stream->Write32(eCustomClipboardTypeId_String);
              if (NS_WARN_IF(NS_FAILED(rv))) {
                totalCustomLength = 0;
                continue;
              }
              rv = stream->Write32(formatLength.value());
              if (NS_WARN_IF(NS_FAILED(rv))) {
                totalCustomLength = 0;
                continue;
              }
              rv = stream->WriteBytes((const char *)type.get(), formatLength.value());
              if (NS_WARN_IF(NS_FAILED(rv))) {
                totalCustomLength = 0;
                continue;
              }
              rv = stream->Write32(lengthInBytes);
              if (NS_WARN_IF(NS_FAILED(rv))) {
                totalCustomLength = 0;
                continue;
              }
              rv = stream->WriteBytes((const char *)data.get(), lengthInBytes);
              if (NS_WARN_IF(NS_FAILED(rv))) {
                totalCustomLength = 0;
                continue;
              }

              totalCustomLength = newSize.value();
            }
          }
        }
      } else if (isCustomFormat && stream) {
        // This is the second pass of the loop (handlingCustomFormats is false).
        // When encountering the first custom format, append all of the stream
        // at this position. If totalCustomLength is 0 indicating a write error
        // occurred, or no data has been added to it, don't output anything,
        if (totalCustomLength > baseLength) {
          // Write out an end of data terminator.
          nsresult rv = stream->Write32(eCustomClipboardTypeId_None);
          if (NS_SUCCEEDED(rv)) {
            nsCOMPtr<nsIInputStream> inputStream;
            storageStream->NewInputStream(0, getter_AddRefs(inputStream));

            RefPtr<nsStringBuffer> stringBuffer =
              nsStringBuffer::Alloc(totalCustomLength);

            // Subtract off the null terminator when reading.
            totalCustomLength--;

            // Read the data from the stream and add a null-terminator as
            // ToString needs it.
            uint32_t amountRead;
            rv = inputStream->Read(static_cast<char*>(stringBuffer->Data()),
                              totalCustomLength, &amountRead);
            if (NS_SUCCEEDED(rv)) {
              static_cast<char*>(stringBuffer->Data())[amountRead] = 0;

              nsCString str;
              stringBuffer->ToString(totalCustomLength, str);
              nsCOMPtr<nsISupportsCString>
                strSupports(do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
              strSupports->SetData(str);

              nsresult rv = transferable->SetTransferData(kCustomTypesMime,
                                                          strSupports,
                                                          totalCustomLength);
              if (NS_FAILED(rv)) {
                return nullptr;
              }

              added = true;
            }
          }
        }

        // Clear the stream so it doesn't get used again.
        stream = nullptr;
      } else {
        // This is the second pass of the loop and a known type is encountered.
        // Add it as is.
        if (!ConvertFromVariant(variant, getter_AddRefs(convertedData),
                                &lengthInBytes)) {
          continue;
        }

        // The underlying drag code uses text/unicode, so use that instead of
        // text/plain
        const char* format;
        NS_ConvertUTF16toUTF8 utf8format(type);
        if (utf8format.EqualsLiteral(kTextMime)) {
          format = kUnicodeMime;
        } else {
          format = utf8format.get();
        }

        // If a converter is set for a format, set the converter for the
        // transferable and don't add the item
        nsCOMPtr<nsIFormatConverter> converter =
          do_QueryInterface(convertedData);
        if (converter) {
          transferable->AddDataFlavor(format);
          transferable->SetConverter(converter);
          continue;
        }

        nsresult rv = transferable->SetTransferData(format, convertedData,
                                                    lengthInBytes);
        if (NS_FAILED(rv)) {
          return nullptr;
        }

        added = true;
      }
    }

    handlingCustomFormats = !handlingCustomFormats;
  } while (!handlingCustomFormats);

  // only return the transferable if data was successfully added to it
  if (added) {
    return transferable.forget();
  }

  return nullptr;
}
Ejemplo n.º 3
0
/* redo cannot simply resplit the right node, because subsequent transactions
 * on the redo stack may depend on the left node existing in its previous state.
 */
NS_IMETHODIMP SplitElementTxn::RedoTransaction(void)
{
  NS_ASSERTION(mEditor && mExistingRightNode && mNewLeftNode && mParent, "bad state");
  if (!mEditor || !mExistingRightNode || !mNewLeftNode || !mParent) {
    return NS_ERROR_NOT_INITIALIZED;
  }

#ifdef NS_DEBUG
  if (gNoisy) { 
    printf("%p Redo Split of existing node %p and new node %p offset %d\n",
           static_cast<void*>(this),
           static_cast<void*>(mExistingRightNode.get()),
           static_cast<void*>(mNewLeftNode.get()),
           mOffset);
    if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
  }
#endif

  nsresult result;
  nsCOMPtr<nsIDOMNode>resultNode;
  // first, massage the existing node so it is in its post-split state
  nsCOMPtr<nsIDOMCharacterData>rightNodeAsText = do_QueryInterface(mExistingRightNode);
  if (rightNodeAsText)
  {
    result = rightNodeAsText->DeleteData(0, mOffset);
#ifdef NS_DEBUG
    if (gNoisy) 
    { 
      printf("** after delete of text in right text node %p offset %d\n",
             static_cast<void*>(rightNodeAsText.get()),
             mOffset);
      mEditor->DebugDumpContent();  // DEBUG
    }
#endif
  }
  else
  {
    nsCOMPtr<nsIDOMNode>child;
    nsCOMPtr<nsIDOMNode>nextSibling;
    result = mExistingRightNode->GetFirstChild(getter_AddRefs(child));
    PRInt32 i;
    for (i=0; i<mOffset; i++)
    {
      if (NS_FAILED(result)) {return result;}
      if (!child) {return NS_ERROR_NULL_POINTER;}
      child->GetNextSibling(getter_AddRefs(nextSibling));
      result = mExistingRightNode->RemoveChild(child, getter_AddRefs(resultNode));
      if (NS_SUCCEEDED(result)) 
      {
        result = mNewLeftNode->AppendChild(child, getter_AddRefs(resultNode));
#ifdef NS_DEBUG
        if (gNoisy) 
        { 
          printf("** move child node %p from right node %p to left node %p\n",
                 static_cast<void*>(child.get()),
                 static_cast<void*>(mExistingRightNode.get()),
                 static_cast<void*>(mNewLeftNode.get()));
          if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
        }
#endif
      }
      child = do_QueryInterface(nextSibling);
    }
  }
  // second, re-insert the left node into the tree 
  result = mParent->InsertBefore(mNewLeftNode, mExistingRightNode, getter_AddRefs(resultNode));
#ifdef NS_DEBUG
  if (gNoisy) 
  { 
    printf("** reinsert left child node %p before right node %p\n",
           static_cast<void*>(mNewLeftNode.get()),
           static_cast<void*>(mExistingRightNode.get()));
    if (gNoisy) {mEditor->DebugDumpContent(); } // DEBUG
  }
#endif
  return result;
}
nsresult
nsMsgSendLater::InternalSendMessages(bool aUserInitiated,
                                     nsIMsgIdentity *aIdentity)
{
    if (WeAreOffline())
        return NS_MSG_ERROR_OFFLINE;

    // Protect against being called whilst we're already sending.
    if (mSendingMessages)
    {
        NS_ERROR("nsMsgSendLater is already sending messages\n");
        return NS_ERROR_FAILURE;
    }

    nsresult rv;

    // XXX This code should be set up for multiple unsent folders, however we
    // don't support that at the moment, so for now just assume one folder.
    if (!mMessageFolder)
    {
        rv = GetUnsentMessagesFolder(nullptr,
                                     getter_AddRefs(mMessageFolder));
        NS_ENSURE_SUCCESS(rv, rv);
    }
    nsCOMPtr<nsIMsgDatabase> unsentDB;
    // Remember these in case we need to reparse the db.
    mUserInitiated = aUserInitiated;
    mIdentity = aIdentity;
    rv = ReparseDBIfNeeded(this);
    NS_ENSURE_SUCCESS(rv, rv);
    mIdentity = nullptr; // don't hold onto the identity since we're a service.

    nsCOMPtr<nsISimpleEnumerator> enumerator;
    rv = mMessageFolder->GetMessages(getter_AddRefs(enumerator));
    NS_ENSURE_SUCCESS(rv, rv);

    // copy all the elements in the enumerator into our isupports array....

    nsCOMPtr<nsISupports> currentItem;
    nsCOMPtr<nsIMsgDBHdr> messageHeader;
    bool hasMoreElements = false;
    while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) && hasMoreElements)
    {
        rv = enumerator->GetNext(getter_AddRefs(currentItem));
        if (NS_SUCCEEDED(rv))
        {
            messageHeader = do_QueryInterface(currentItem, &rv);
            if (NS_SUCCEEDED(rv))
            {
                if (aUserInitiated)
                    // If the user initiated the send, add all messages
                    mMessagesToSend.AppendObject(messageHeader);
                else
                {
                    // Else just send those that are NOT marked as Queued.
                    uint32_t flags;
                    rv = messageHeader->GetFlags(&flags);
                    if (NS_SUCCEEDED(rv) && !(flags & nsMsgMessageFlags::Queued))
                        mMessagesToSend.AppendObject(messageHeader);
                }
            }
        }
    }

    // Now get an enumerator for our array.
    rv = NS_NewArrayEnumerator(getter_AddRefs(mEnumerator), mMessagesToSend);
    NS_ENSURE_SUCCESS(rv, rv);

    // We're now sending messages so its time to signal that and reset our counts.
    mSendingMessages = true;
    mTotalSentSuccessfully = 0;
    mTotalSendCount = 0;

    // Notify the listeners that we are starting a send.
    NotifyListenersOnStartSending(mMessagesToSend.Count());

    return StartNextMailFileSend(NS_OK);
}
//-----------------------------------------------------------------------------
LRESULT CWindowMinMaxSubclass::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  if (!IsWindow(hWnd)) 
    return 0;
  switch (uMsg)
  {
    case WM_SETCURSOR:
    {
      // a WM_SETCURSOR message with WM_LBUTTONDOWN is issued each time the mouse is clicked on a resizer.
      // it's also done plenty of other times, but it doesn't matter, this is merely used to reset the compensation
      // variables between two resizing sessions (see comments below)
      if (HIWORD(lParam) == WM_LBUTTONDOWN)
      { 
        m_dx = m_ix = m_dy = m_iy = 0;
      }
      break;
    }

    // XXXlone> this is a temporary fix, until mozilla handles maximizing (and restoring to a maximized state) on secondary screens
    case WM_GETMINMAXINFO:
    {
      MINMAXINFO* mi = (MINMAXINFO *) lParam;
      RECT workArea;
      RECT monitorArea;
       
      // Need both the area with and without taskbar, because ptMaxPosition uses local coordinates
      CMultiMonitor::GetMonitorFromWindow(&workArea, hWnd, TRUE);
      CMultiMonitor::GetMonitorFromWindow(&monitorArea, hWnd, FALSE);

      mi->ptMaxSize.x = workArea.right - workArea.left;
      mi->ptMaxSize.y = workArea.bottom - workArea.top;
      mi->ptMaxPosition.x = workArea.left - monitorArea.left;
      mi->ptMaxPosition.y = workArea.top - monitorArea.top;
    }
    break;
      
    case WM_WINDOWPOSCHANGING:
    {
      WINDOWPOS *wp = (WINDOWPOS*)lParam;
      if (m_callback && wp && !(wp->flags & SWP_NOSIZE))
      {
        // previous window position on screen
        RECT r;
        GetWindowRect(hWnd, &r);
        
        // determine which way the window is being dragged, because mozilla does not honor WM_SIZING/WM_EXITSIZEMOVE
        int _r, _t, _l, _b;
        _r = r.right != wp->x + wp->cx;
        _b = r.bottom != wp->y + wp->cy;
        _l = r.left != wp->x;
        _t = r.top != wp->y;
        
        // if all sides are moving, this is not a user-initiated resize, let moz handle it
        if (_r && _b && _l && _t) break;
        
        // ask the script callback for current min/max values         
        // since technically, any of the callbacks could have caused our window to be destroyed,
        // check that the window is still valid after any callback returns
        int _minwidth = -1, _minheight = -1, _maxwidth = -1, _maxheight = -1;
        m_callback->GetMaxWidth(&_maxwidth);
        if (!IsWindow(hWnd)) return 0;
        m_callback->GetMaxHeight(&_maxheight);
        if (!IsWindow(hWnd)) return 0;
        m_callback->GetMinWidth(&_minwidth);
        if (!IsWindow(hWnd)) return 0;
        m_callback->GetMinHeight(&_minheight);
        if (!IsWindow(hWnd)) return 0;

        // fill default resize values from mozilla's resizer object
        LRESULT ret = CallWindowProc(m_prevWndProc, hWnd, uMsg, wParam, lParam);

        // original size to which mozilla would like to resize the window
        int ocx = wp->cx;
        int ocy = wp->cy;
        
        // because the moz resize object handles resizing using relative mouse tracking, we need to compensate for the motion of the mouse outside of the allowed values. 
        // for instance, when going past the minimum size allowed, the mouse will naturally travel further than the side of the window (the mouse will no longer be in front of 
        // the resizer anymore, but will move over the content of the window). this is normal, it's what we want, but because of the use of relative tracking, moving the mouse back will 
        // immediately start to resize the window in the other direction instead of waiting until the mouse has come back on top of the resizer. that's what you get for using relative
        // tracking... well, that and bugs, too.
        //
        // anyway, to fix this (definitely unwanted) behavior, we keep track of four values, which respectively describe how much the mouse has traveled past the horizontal minimum, 
        // horizontal maximum, vertical minimum and vertical maximum on the left and bottom sides (fotunately, the resizer object does not provoke the same problem with top/left tracking 
        // or we would need 8 of these).
        //
        // using the size of the window mozilla would like to set, and the previous size of the window, we determine which way the mouse has been tracked, and use this to update
        // the four compensation variables. we use their values when the mouse moves the other direction and decrease or increase the size of the window so that it looks like
        // it is never resized at all when the mouse is past the min/max values (ie, it looks like an absolute mouse tracking).
        //
        // this of course has to work in conjunction with the normal tailoring of the window position and size that we're here to implement in the first place.
        //
        // fun.
        
        if (_r && _minwidth != -1) 
        {
          // compensate -- increment left motion past minimum width
          int v = _minwidth-ocx;
          if (v > 0) m_dx += v;
        }

        if (_r && _maxwidth != -1) 
        {
          // compensate -- increment right motion past maximum width
          int v = ocx-_maxwidth;
          if (v > 0) m_ix += v;
        }

        if (_b && _minheight != -1) 
        {
          // compensate -- increment top motion past minimum height
          int v = _minheight-ocy;
          if (v > 0) m_dy += v;
        }

        if (_b && _maxheight != -1) 
        {
          // compensate -- increment bottom motion past maximum height
          int v = ocy-_maxheight;
          if (v > 0) m_iy += v;
        }

        if (_r) // the user is dragging the window by the right side (or one of the corners on the right), we only need to modify the width of the window to constrain it
        {
          if (_minwidth != -1 && wp->cx < _minwidth) wp->cx = _minwidth; 
          else 
          { 
            // compensate -- decrement left motion past minimum width, decrease resulting width so it looks like nothing happened
            int v = ocx-(r.right-r.left);
            if (v > 0)
            {
              if (m_dx >= v) { wp->cx -= v; m_dx -= v; } else { wp->cx -= m_dx; m_dx = 0; }
            }
          }
          if (_maxwidth != -1 && wp->cx > _maxwidth) wp->cx = _maxwidth;
          else
          {
            // compensate -- decrement right motion past maximum width, increase resulting width so it looks like nothing happened
            int v = (r.right-r.left)-ocx;
            if (v > 0)
            {
              if (m_ix >= v) { wp->cx += v; m_ix -= v; } else { wp->cx += m_ix; m_ix = 0; }
            }
          }
        }
        if (_l) // the user is dragging the window by the left side (or one of the corners on the left), we need to modify both the width and the right anchor of the window to constrain it
        {
          if (_maxwidth != -1 && wp->cx > _maxwidth)
          { 
            wp->cx = _maxwidth; 
            wp->x = r.right - _maxwidth; 
          }
          if (_minwidth != -1 && wp->cx < _minwidth) 
          { 
            wp->cx = _minwidth; 
            wp->x = r.right - _minwidth; 
          }
        }
        if (_b) // the user is dragging the window by the bottom side (or one of the corners on the bottom), we only need to modify the height of the window to constrain it
        {
          if (_minheight != -1 && wp->cy < _minheight) wp->cy = _minheight;
          else 
          { 
            // compensate -- decrement upward motion past minimum height, decrease resulting height so it looks like nothing happened
            int v = ocy-(r.bottom-r.top);
            if (v > 0)
            {
              if (m_dy >= v) { wp->cy -= v; m_dy -= v; } else { wp->cy -= m_dy; m_dy = 0; }
            }
          }
          if (_maxheight != -1 && wp->cy > _maxheight) wp->cy = _maxheight;
          else
          {
            // compensate -- decrement downward motion past maximum height, increase resulting height so it looks like nothing happened
            int v = (r.bottom-r.top)-ocy;
            if (v > 0)
            {
              if (m_iy >= v) { wp->cy += v; m_iy -= v; } else { wp->cy += m_iy; m_iy = 0; }
            }
          }
        }
        if (_t) // the user is dragging the window by the top side (or one of the corners on the top), we need to modify both the height and the top anchor of the window to constrain it
        {
          if (_maxheight != -1 && wp->cy > _maxheight)
          { 
            wp->cy = _maxheight; 
            wp->y = r.bottom - _maxheight; 
          }
          if (_minheight != -1 && wp->cy < _minheight) 
          { 
            wp->cy = _minheight; 
            wp->y = r.bottom - _minheight; 
          }
        }

        // all done, return value we got from moz
        return ret;
      }
    }
    break;

    // Added WM_DEVICECHANGE handler for CDDevice object, as a Windows specific
    // implementation, for receiving media insert and removal notifications.
    case WM_DEVICECHANGE:
    {
      nsresult rv;
      nsCOMPtr<sbIDeviceManager> deviceManager =
        do_GetService("@songbirdnest.com/Songbird/DeviceManager;1", &rv);
      if (NS_FAILED(rv))
      {
        NS_WARNING("Failed to get the DeviceManager!");
        break;
      }

      // Send an event to the CDDevice, if present.
      PRBool hasCDDevice;
      NS_NAMED_LITERAL_STRING(cdCategory, "Songbird CD Device");

      rv = deviceManager->HasDeviceForCategory(cdCategory, &hasCDDevice);
      if (NS_SUCCEEDED(rv) && hasCDDevice)
      {
        nsCOMPtr<sbIDeviceBase> baseDevice;
        rv = deviceManager->GetDeviceByCategory(cdCategory,
                                                getter_AddRefs(baseDevice));
        if (NS_SUCCEEDED(rv))
        {

#if defined(SB_ENABLE_CD_DEVICE)
          nsCOMPtr<sbICDDevice> cdDevice = do_QueryInterface(baseDevice, &rv);
          if (NS_SUCCEEDED(rv))
          {
            PRBool retVal;
            PRBool mediaInserted = DBT_DEVICEARRIVAL == wParam;
            rv = cdDevice->OnCDDriveEvent(mediaInserted, &retVal);
          }
#endif

        }
      }
      break;
    }
    // Added WM_SYSCOMMAND handler for taskbar buttons' close command
    case WM_SYSCOMMAND:
    {
      if (wParam == SC_CLOSE && m_callback)
      {
        m_callback->OnWindowClose();
        return 0;
      }
    }
    break;
 }
  if (!IsWindow(hWnd)) 
    return 0;
  return CallWindowProc(m_prevWndProc, hWnd, uMsg, wParam, lParam);
} // WndProc
bool
nsXHTMLContentSerializer::SerializeLIValueAttribute(nsIContent* aElement,
        nsAString& aStr)
{
    // We are copying and we are at the "first" LI node of OL in selected range.
    // It may not be the first LI child of OL but it's first in the selected range.
    // Note that we get into this condition only once per a OL.
    bool found = false;
    nsCOMPtr<nsIDOMNode> currNode = do_QueryInterface(aElement);
    nsAutoString valueStr;

    olState state (0, false);

    if (!mOLStateStack.IsEmpty()) {
        state = mOLStateStack[mOLStateStack.Length()-1];
        // isFirstListItem should be true only before the serialization of the
        // first item in the list.
        state.isFirstListItem = false;
        mOLStateStack[mOLStateStack.Length()-1] = state;
    }

    int32_t startVal = state.startVal;
    int32_t offset = 0;

    // Traverse previous siblings until we find one with "value" attribute.
    // offset keeps track of how many previous siblings we had tocurrNode traverse.
    while (currNode && !found) {
        nsCOMPtr<nsIDOMElement> currElement = do_QueryInterface(currNode);
        // currElement may be null if it were a text node.
        if (currElement) {
            nsAutoString tagName;
            currElement->GetTagName(tagName);
            if (tagName.LowerCaseEqualsLiteral("li")) {
                currElement->GetAttribute(NS_LITERAL_STRING("value"), valueStr);
                if (valueStr.IsEmpty())
                    offset++;
                else {
                    found = true;
                    nsresult rv = NS_OK;
                    startVal = valueStr.ToInteger(&rv);
                }
            }
        }
        nsCOMPtr<nsIDOMNode> tmp;
        currNode->GetPreviousSibling(getter_AddRefs(tmp));
        currNode.swap(tmp);
    }
    // If LI was not having "value", Set the "value" attribute for it.
    // Note that We are at the first LI in the selected range of OL.
    if (offset == 0 && found) {
        // offset = 0 => LI itself has the value attribute and we did not need to traverse back.
        // Just serialize value attribute like other tags.
        NS_ENSURE_TRUE(SerializeAttr(EmptyString(), NS_LITERAL_STRING("value"),
                                     valueStr, aStr, false), false);
    }
    else if (offset == 1 && !found) {
        /*(offset = 1 && !found) means either LI is the first child node of OL
        and LI is not having "value" attribute.
        In that case we would not like to set "value" attribute to reduce the changes.
        */
        //do nothing...
    }
    else if (offset > 0) {
        // Set value attribute.
        nsAutoString valueStr;

        //As serializer needs to use this valueAttr we are creating here,
        valueStr.AppendInt(startVal + offset);
        NS_ENSURE_TRUE(SerializeAttr(EmptyString(), NS_LITERAL_STRING("value"),
                                     valueStr, aStr, false), false);
    }

    return true;
}
NS_IMETHODIMP nsMsgGroupView::OpenWithHdrs(nsISimpleEnumerator *aHeaders, nsMsgViewSortTypeValue aSortType,
                                        nsMsgViewSortOrderValue aSortOrder, nsMsgViewFlagsTypeValue aViewFlags,
                                        int32_t *aCount)
{
  nsresult rv = NS_OK;

  m_groupsTable.Clear();
  if (aSortType == nsMsgViewSortType::byThread || aSortType == nsMsgViewSortType::byId
    || aSortType == nsMsgViewSortType::byNone || aSortType == nsMsgViewSortType::bySize)
    return NS_ERROR_INVALID_ARG;

  m_sortType = aSortType;
  m_sortOrder = aSortOrder;
  m_viewFlags = aViewFlags | nsMsgViewFlagsType::kThreadedDisplay | nsMsgViewFlagsType::kGroupBySort;
  SaveSortInfo(m_sortType, m_sortOrder);

  if (m_sortType == nsMsgViewSortType::byCustom)
  {
    // If the desired sort is a custom column and there is no handler found,
    // it hasn't been registered yet; after the custom column observer is
    // notified with MsgCreateDBView and registers the handler, it will come
    // back and build the view.
    nsIMsgCustomColumnHandler* colHandler = GetCurColumnHandler();
    if (!colHandler)
      return rv;
  }

  bool hasMore;
  nsCOMPtr <nsISupports> supports;
  nsCOMPtr <nsIMsgDBHdr> msgHdr;
  while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv = aHeaders->HasMoreElements(&hasMore)) && hasMore)
  {
    rv = aHeaders->GetNext(getter_AddRefs(supports));
    if (NS_SUCCEEDED(rv) && supports)
    {
      bool notUsed;
      msgHdr = do_QueryInterface(supports);
      AddHdrToThread(msgHdr, &notUsed);
    }
  }
  uint32_t expandFlags = 0;
  bool expandAll = m_viewFlags & nsMsgViewFlagsType::kExpandAll;
  uint32_t viewFlag = (m_sortType == nsMsgViewSortType::byDate) ? MSG_VIEW_FLAG_DUMMY : 0;
  if (viewFlag && m_db)
  {
    nsCOMPtr <nsIDBFolderInfo> dbFolderInfo;
    nsresult rv = m_db->GetDBFolderInfo(getter_AddRefs(dbFolderInfo));
    NS_ENSURE_SUCCESS(rv, rv);
    if (dbFolderInfo)
      dbFolderInfo->GetUint32Property("dateGroupFlags",  0, &expandFlags);
  }
  // go through the view updating the flags for threads with more than one message...
  // and if grouped by date, expanding threads that were expanded before.
  for (uint32_t viewIndex = 0; viewIndex < m_keys.Length(); viewIndex++)
  {
    nsCOMPtr <nsIMsgThread> thread;
    GetThreadContainingIndex(viewIndex, getter_AddRefs(thread));
    if (thread)
    {
      uint32_t numChildren;
      thread->GetNumChildren(&numChildren);
      if (numChildren > 1 || viewFlag)
        OrExtraFlag(viewIndex, viewFlag | MSG_VIEW_FLAG_HASCHILDREN);
      if (expandAll || expandFlags)
      {
        nsMsgGroupThread *groupThread = static_cast<nsMsgGroupThread *>((nsIMsgThread *) thread);
        if (expandAll || expandFlags & (1 << groupThread->m_threadKey))
        {
          uint32_t numExpanded;
          ExpandByIndex(viewIndex, &numExpanded);
          viewIndex += numExpanded;
        }
      }
    }
  }
  *aCount = m_keys.Length();
  return rv;
}
Ejemplo n.º 8
0
bool
nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
                      bool aReportOnly, bool aUpgradeInsecure) const
{
  if (CSPUTILSLOGENABLED()) {
    nsAutoCString spec;
    aUri->GetSpec(spec);
    CSPUTILSLOG(("nsCSPHostSrc::permits, aUri: %s", spec.get()));
  }

  // we are following the enforcement rules from the spec, see:
  // http://www.w3.org/TR/CSP11/#match-source-expression

  // 4.3) scheme matching: Check if the scheme matches.
  if (!permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure)) {
    return false;
  }

  // The host in nsCSpHostSrc should never be empty. In case we are enforcing
  // just a specific scheme, the parser should generate a nsCSPSchemeSource.
  NS_ASSERTION((!mHost.IsEmpty()), "host can not be the empty string");

  // 2) host matching: Enforce a single *
  if (mHost.EqualsASCII("*")) {
    // The single ASTERISK character (*) does not match a URI's scheme of a type
    // designating a globally unique identifier (such as blob:, data:, or filesystem:)
    // At the moment firefox does not support filesystem; but for future compatibility
    // we support it in CSP according to the spec, see: 4.2.2 Matching Source Expressions
    // Note, that whitelisting any of these schemes would call nsCSPSchemeSrc::permits().
    bool isBlobScheme =
      (NS_SUCCEEDED(aUri->SchemeIs("blob", &isBlobScheme)) && isBlobScheme);
    bool isDataScheme =
      (NS_SUCCEEDED(aUri->SchemeIs("data", &isDataScheme)) && isDataScheme);
    bool isFileScheme =
      (NS_SUCCEEDED(aUri->SchemeIs("filesystem", &isFileScheme)) && isFileScheme);

    if (isBlobScheme || isDataScheme || isFileScheme) {
      return false;
    }
    return true;
  }

  // Before we can check if the host matches, we have to
  // extract the host part from aUri.
  nsAutoCString uriHost;
  nsresult rv = aUri->GetHost(uriHost);
  NS_ENSURE_SUCCESS(rv, false);

  // 4.5) host matching: Check if the allowed host starts with a wilcard.
  if (mHost.First() == '*') {
    NS_ASSERTION(mHost[1] == '.', "Second character needs to be '.' whenever host starts with '*'");

    // Eliminate leading "*", but keeping the FULL STOP (.) thereafter before checking
    // if the remaining characters match
    nsString wildCardHost = mHost;
    wildCardHost = Substring(wildCardHost, 1, wildCardHost.Length() - 1);
    if (!StringEndsWith(NS_ConvertUTF8toUTF16(uriHost), wildCardHost)) {
      return false;
    }
  }
  // 4.6) host matching: Check if hosts match.
  else if (!mHost.Equals(NS_ConvertUTF8toUTF16(uriHost))) {
    return false;
  }

  // 4.9) Path matching: If there is a path, we have to enforce
  // path-level matching, unless the channel got redirected, see:
  // http://www.w3.org/TR/CSP11/#source-list-paths-and-redirects
  if (!aWasRedirected && !mPath.IsEmpty()) {
    // converting aUri into nsIURL so we can strip query and ref
    // example.com/test#foo     -> example.com/test
    // example.com/test?val=foo -> example.com/test
    nsCOMPtr<nsIURL> url = do_QueryInterface(aUri);
    if (!url) {
      NS_ASSERTION(false, "can't QI into nsIURI");
      return false;
    }
    nsAutoCString uriPath;
    rv = url->GetFilePath(uriPath);
    NS_ENSURE_SUCCESS(rv, false);
    // check if the last character of mPath is '/'; if so
    // we just have to check loading resource is within
    // the allowed path.
    if (mPath.Last() == '/') {
      if (!StringBeginsWith(NS_ConvertUTF8toUTF16(uriPath), mPath)) {
        return false;
      }
    }
    // otherwise mPath whitelists a specific file, and we have to
    // check if the loading resource matches that whitelisted file.
    else {
      if (!mPath.Equals(NS_ConvertUTF8toUTF16(uriPath))) {
        return false;
      }
    }
  }

  // 4.8) Port matching: If port uses wildcard, allow the load.
  if (mPort.EqualsASCII("*")) {
    return true;
  }

  // Before we can check if the port matches, we have to
  // query the port from aUri.
  int32_t uriPort;
  rv = aUri->GetPort(&uriPort);
  NS_ENSURE_SUCCESS(rv, false);

  nsAutoCString scheme;
  rv = aUri->GetScheme(scheme);
  NS_ENSURE_SUCCESS(rv, false);

  uriPort = (uriPort > 0) ? uriPort : NS_GetDefaultPort(scheme.get());

  // 4.7) Default port matching: If mPort is empty, we have to compare default ports.
  if (mPort.IsEmpty()) {
    int32_t port = NS_GetDefaultPort(NS_ConvertUTF16toUTF8(mScheme).get());
    if (port != uriPort) {
      // We should not return false for scheme-less sources where the protected resource
      // is http and the load is https, see: http://www.w3.org/TR/CSP2/#match-source-expression
      // BUT, we only allow scheme-less sources to be upgraded from http to https if CSP
      // does not explicitly define a port.
      if (!(uriPort == NS_GetDefaultPort("https"))) {
        return false;
      }
    }
  }
  // 4.7) Port matching: Compare the ports.
  else {
    nsString portStr;
    portStr.AppendInt(uriPort);
    if (!mPort.Equals(portStr)) {
      return false;
    }
  }

  // At the end: scheme, host, path, and port match -> allow the load.
  return true;
}
//
// Native method Install
//
static JSBool
InstallTriggerGlobalInstall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj);
  if (!nativeThis)
    return JS_FALSE;

  *rval = JSVAL_FALSE;

  // make sure XPInstall is enabled, return false if not
  nsIScriptGlobalObject *globalObject = nsnull;
  nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx);
  if (scriptContext)
    globalObject = scriptContext->GetGlobalObject();

  if (!globalObject)
      return JS_TRUE;

  nsCOMPtr<nsIScriptSecurityManager> secman(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
  if (!secman)
  {
    JS_ReportError(cx, "Could not the script security manager service.");
    return JS_FALSE;
  }
  // get the principal.  if it doesn't exist, die.
  nsCOMPtr<nsIPrincipal> principal;
  secman->GetSubjectPrincipal(getter_AddRefs(principal));
  if (!principal)
  {
    JS_ReportError(cx, "Could not get the Subject Principal during InstallTrigger.Install()");
    return JS_FALSE;
  }

  // get window.location to construct relative URLs
  nsCOMPtr<nsIURI> baseURL;
  JSObject* global = JS_GetGlobalObject(cx);
  if (global)
  {
    jsval v;
    if (JS_GetProperty(cx,global,"location",&v))
    {
      nsAutoString location;
      ConvertJSValToStr( location, cx, v );
      NS_NewURI(getter_AddRefs(baseURL), location);
    }
  }

  PRBool abortLoad = PR_FALSE;

  // parse associative array of installs
  if ( argc >= 1 && JSVAL_IS_OBJECT(argv[0]) && JSVAL_TO_OBJECT(argv[0]) )
  {
    nsXPITriggerInfo *trigger = new nsXPITriggerInfo();
    if (!trigger)
      return JS_FALSE;

    trigger->SetPrincipal(principal);

    JSIdArray *ida = JS_Enumerate( cx, JSVAL_TO_OBJECT(argv[0]) );
    if ( ida )
    {
      jsval v;
      const PRUnichar *name, *URL;
      const PRUnichar *iconURL = nsnull;

      for (int i = 0; i < ida->length && !abortLoad; i++ )
      {
        JS_IdToValue( cx, ida->vector[i], &v );
        JSString * str = JS_ValueToString( cx, v );
        if (!str)
        {
          abortLoad = PR_TRUE;
          break;
        }

        name = reinterpret_cast<const PRUnichar*>(JS_GetStringChars( str ));

        URL = iconURL = nsnull;
        JSAutoByteString hash;
        JS_GetUCProperty( cx, JSVAL_TO_OBJECT(argv[0]), reinterpret_cast<const jschar*>(name), nsCRT::strlen(name), &v );
        if ( JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) )
        {
          jsval v2;
          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "URL", &v2 ) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str) {
              abortLoad = PR_TRUE;
              break;
            }
            URL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
          }

          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "IconURL", &v2 ) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str) {
              abortLoad = PR_TRUE;
              break;
            }
            iconURL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
          }

          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "Hash", &v2) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str || !hash.encode(cx, str)) {
              abortLoad = PR_TRUE;
              break;
            }
          }
        }
        else
        {
          JSString *str = JS_ValueToString(cx, v);
          if (!str) {
            abortLoad = PR_TRUE;
            break;
          }
          URL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
        }

        if ( URL )
        {
            // Get relative URL to load
            nsAutoString xpiURL(URL);
            if (baseURL)
            {
                nsCAutoString resolvedURL;
                baseURL->Resolve(NS_ConvertUTF16toUTF8(xpiURL), resolvedURL);
                xpiURL = NS_ConvertUTF8toUTF16(resolvedURL);
            }

            nsAutoString icon(iconURL);
            if (iconURL && baseURL)
            {
                nsCAutoString resolvedIcon;
                baseURL->Resolve(NS_ConvertUTF16toUTF8(icon), resolvedIcon);
                icon = NS_ConvertUTF8toUTF16(resolvedIcon);
            }

            // Make sure we're allowed to load this URL and the icon URL
            nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, xpiURL);
            if (NS_FAILED(rv))
                abortLoad = PR_TRUE;

            if (!abortLoad && iconURL)
            {
                rv = InstallTriggerCheckLoadURIFromScript(cx, icon);
                if (NS_FAILED(rv))
                    abortLoad = PR_TRUE;
            }

            if (!abortLoad)
            {
                // Add the install item to the trigger collection
                nsXPITriggerItem *item =
                    new nsXPITriggerItem( name, xpiURL.get(), icon.get(), hash );
                if ( item )
                {
                    trigger->Add( item );
                }
                else
                    abortLoad = PR_TRUE;
            }
        }
        else
            abortLoad = PR_TRUE;
      }
      JS_DestroyIdArray( cx, ida );
    }


    // pass on only if good stuff found
    if (!abortLoad && trigger->Size() > 0)
    {
        nsCOMPtr<nsIURI> checkuri;
        nsresult rv = nativeThis->GetOriginatingURI(globalObject,
                                                    getter_AddRefs(checkuri));
        if (NS_SUCCEEDED(rv))
        {
            nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject));
            nsCOMPtr<nsIXPIInstallInfo> installInfo =
                new nsXPIInstallInfo(win, checkuri, trigger, 0);
            if (installInfo)
            {
                // installInfo now owns triggers
                PRBool enabled = PR_FALSE;
                nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST, &enabled);
                if (!enabled)
                {
                    nsCOMPtr<nsIObserverService> os =
                      mozilla::services::GetObserverService();
                    if (os)
                        os->NotifyObservers(installInfo,
                                            "xpinstall-install-blocked",
                                            nsnull);
                }
                else
                {
                    // save callback function if any (ignore bad args for now)
                    if ( argc >= 2 && JS_TypeOfValue(cx,argv[1]) == JSTYPE_FUNCTION )
                    {
                        trigger->SaveCallback( cx, argv[1] );
                    }

                    PRBool result;
                    nativeThis->StartInstall(installInfo, &result);
                    *rval = BOOLEAN_TO_JSVAL(result);
                }
                return JS_TRUE;
            }
        }
    }
    // didn't pass it on so we must delete trigger
    delete trigger;
  }

  JS_ReportError(cx, "Incorrect arguments to InstallTrigger.Install()");
  return JS_FALSE;
}
nsresult
sbLocalDatabaseLibraryFactory::CreateLibraryFromDatabase(nsIFile* aDatabase,
                                                         sbILibrary** _retval,
                                                         nsIPropertyBag2* aCreationParameters,
                                                         nsString aResourceGUID /* = EmptyString() */)
{
  NS_ENSURE_ARG_POINTER(aDatabase);
  NS_ENSURE_ARG_POINTER(_retval);

  nsresult rv;

  // Get a unique value for this database file.
  nsCOMPtr<nsIHashable> hashable = do_QueryInterface(aDatabase, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  // We have to copy the file name escaping logic from when we actually create
  // the database, otherwise we end up re-initizliaing the database over and over.
  nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIURI> databaseURI;
  rv = NS_NewFileURI(getter_AddRefs(databaseURI), aDatabase, ioService);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIURL> databaseURL = do_QueryInterface(databaseURI, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCAutoString utf8GUID;
  rv = databaseURL->GetFileBaseName(utf8GUID);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIFile> databaseParent;
  rv = aDatabase->GetParent(getter_AddRefs(databaseParent));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCAutoString fileName;
  rv = databaseURL->GetFileName(fileName);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIFile> escapedFile;
  rv = databaseParent->Clone(getter_AddRefs(escapedFile));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = escapedFile->Append(NS_ConvertUTF8toUTF16(fileName));
  NS_ENSURE_SUCCESS(rv, rv);

  // On Windows, if the file does not exist, its hashcode is different from when it does.
  // If we ever attempt to get the hash code while it doesn't exist, the
  // nsLocalFile caches the hash code and stays incorrect.
  bool exists;
  rv = escapedFile->Exists(&exists);
  NS_ENSURE_SUCCESS(rv, rv);

  // See if we've already created this library. If we have (and it is still
  // alive) just return it.
  nsCOMPtr<nsIWeakReference> weakRef;
  if (exists && mCreatedLibraries.Get(hashable, getter_AddRefs(weakRef))) {
    nsCOMPtr<sbILibrary> existingLibrary = do_QueryReferent(weakRef, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    if (existingLibrary) {
      existingLibrary.swap(*_retval);
      return NS_OK;
    }

    mCreatedLibraries.Remove(hashable);
  }

  // If the database file does not exist, create and initalize it.  Otherwise,
  // update it.
  if (!exists) {
    rv = InitalizeLibrary(aDatabase, aResourceGUID);
    NS_ENSURE_SUCCESS(rv, rv);
  }
  else {
    rv = UpdateLibrary(aDatabase);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  nsCOMPtr<nsIURI> databaseLocation;
  rv = NS_NewFileURI(getter_AddRefs(databaseLocation), databaseParent,
                     ioService);
  NS_ENSURE_SUCCESS(rv, rv);

  nsRefPtr<sbLocalDatabaseLibrary> library(new sbLocalDatabaseLibrary());
  NS_ENSURE_TRUE(library, NS_ERROR_OUT_OF_MEMORY);

  nsCOMPtr<nsIPropertyBag2> creationParams = aCreationParameters;
  if (!creationParams) {
    nsCOMPtr<nsIWritablePropertyBag2> bag =
      do_CreateInstance(SB_PROPERTYBAG_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = bag->SetPropertyAsInterface(NS_LITERAL_STRING(PROPERTY_KEY_DATABASEFILE),
                                     aDatabase);
    NS_ENSURE_SUCCESS(rv, rv);

    creationParams = do_QueryInterface(bag, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  rv = library->Init(NS_ConvertUTF8toUTF16(utf8GUID), creationParams, this,
                     databaseLocation);
  NS_ENSURE_SUCCESS(rv, rv);

  // Add this library to our table of created libraries.
  weakRef = do_GetWeakReference(NS_ISUPPORTS_CAST(sbILibrary*, library),
                                &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  bool success = mCreatedLibraries.Put(hashable, weakRef);
  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);

  NS_ADDREF(*_retval = library);
  return NS_OK;
}
nsresult
sbLocalDatabaseLibraryFactory::InitalizeLibrary(nsIFile* aDatabaseFile,
                                                const nsAString &aResourceGUID)
{
  nsresult rv;
  PRInt32 dbOk;

  nsCOMPtr<nsIFile> parentDirectory;
  rv = aDatabaseFile->GetParent(getter_AddRefs(parentDirectory));
  NS_ENSURE_SUCCESS(rv, rv);

  bool parentExists;
  rv = parentDirectory->Exists(&parentExists);
  NS_ENSURE_SUCCESS(rv, rv);

  if (!parentExists) {
    rv = CreateDirectory(parentDirectory);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  bool parentIsWritable = IsDirectoryWritable(parentDirectory);
  NS_ENSURE_TRUE(parentIsWritable, NS_ERROR_FILE_ACCESS_DENIED);

  // Now that we know we have appropriate permissions make a new query.
  nsCOMPtr<sbIDatabaseQuery> query =
    do_CreateInstance(SONGBIRD_DATABASEQUERY_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = query->SetAsyncQuery(PR_FALSE);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = SetQueryDatabaseFile(query, aDatabaseFile);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIURI> schemaURI;
  rv = NS_NewURI(getter_AddRefs(schemaURI), NS_LITERAL_CSTRING(SCHEMA_URL));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIInputStream> input;
  rv = NS_OpenURI(getter_AddRefs(input), schemaURI);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIConverterInputStream> converterStream =
    do_CreateInstance("@mozilla.org/intl/converter-input-stream;1", &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = converterStream->Init(input,
                             "UTF-8",
                             CONVERTER_BUFFER_SIZE,
                             nsIConverterInputStream::
                               DEFAULT_REPLACEMENT_CHARACTER);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIUnicharInputStream> unichar =
    do_QueryInterface(converterStream, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  PRUint32 read;
  nsString response, result;
  rv = unichar->ReadString(PR_UINT32_MAX, result, &read);
  NS_ENSURE_SUCCESS(rv, rv);
  NS_ASSERTION(read, "Schema file zero bytes?");
  while (read > 0) {
    response.Append(result);
    rv = unichar->ReadString(PR_UINT32_MAX, result, &read);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  rv = unichar->Close();
  NS_ENSURE_SUCCESS(rv, rv);

  NS_NAMED_LITERAL_STRING(colonNewline, ";\n");
  PRInt32 posStart = 0;
  PRInt32 posEnd = response.Find(colonNewline, posStart);
  while (posEnd >= 0) {
    rv = query->AddQuery(Substring(response, posStart, posEnd - posStart));
    NS_ENSURE_SUCCESS(rv, rv);
    posStart = posEnd + 2;
    posEnd = response.Find(colonNewline, posStart);
  }

  rv = query->Execute(&dbOk);
  NS_ENSURE_SUCCESS(rv, rv);
  NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);

  nsString guid(aResourceGUID);
  if(guid.IsEmpty()) {
    // Create a resource guid for this database.
    nsCOMPtr<nsIUUIDGenerator> uuidGen =
      do_GetService("@mozilla.org/uuid-generator;1", &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsID id;
    rv = uuidGen->GenerateUUIDInPlace(&id);
    NS_ENSURE_SUCCESS(rv, rv);

    char guidChars[NSID_LENGTH];
    id.ToProvidedString(guidChars);

    guid = NS_ConvertASCIItoUTF16(nsDependentCString(guidChars + 1,
                                                     NSID_LENGTH - 3));
  }

  // Insert the guid into the database.
  nsCOMPtr<sbISQLInsertBuilder> insert =
    do_CreateInstance(SB_SQLBUILDER_INSERT_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->SetIntoTableName(NS_LITERAL_STRING("library_metadata"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddColumn(NS_LITERAL_STRING("name"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddColumn(NS_LITERAL_STRING("value"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddValueString(NS_LITERAL_STRING("resource-guid"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddValueString(guid);
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoString sql;
  rv = insert->ToString(sql);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = query->ResetQuery();
  NS_ENSURE_SUCCESS(rv, rv);

  rv = query->AddQuery(sql);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = query->Execute(&dbOk);
  NS_ENSURE_SUCCESS(rv, rv);
  NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);

  nsString now;
  sbLocalDatabaseLibrary::GetNowString(now);

  nsCOMPtr<nsIURI> fileURI;
  rv = NS_NewFileURI(getter_AddRefs(fileURI), aDatabaseFile);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCString uriSpec;
  rv = fileURI->GetSpec(uriSpec);
  NS_ENSURE_SUCCESS(rv, rv);

  // Add the default library media item properties
  insert = do_CreateInstance(SB_SQLBUILDER_INSERT_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->SetIntoTableName(NS_LITERAL_STRING("library_media_item"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddColumn(NS_LITERAL_STRING("guid"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddValueString(guid);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddColumn(NS_LITERAL_STRING("created"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddValueString(now);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddColumn(NS_LITERAL_STRING("updated"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddValueString(now);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddColumn(NS_LITERAL_STRING("content_url"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddValueString(NS_ConvertUTF8toUTF16(uriSpec));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddColumn(NS_LITERAL_STRING("hidden"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddValueLong(0);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddColumn(NS_LITERAL_STRING("is_list"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->AddValueLong(0);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = insert->ToString(sql);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = query->ResetQuery();
  NS_ENSURE_SUCCESS(rv, rv);

  rv = query->AddQuery(sql);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = query->Execute(&dbOk);
  NS_ENSURE_SUCCESS(rv, rv);
  NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);

  return NS_OK;
}
Ejemplo n.º 12
0
NS_IMETHODIMP
nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
                                    const char      *challenge,
                                    bool             isProxyAuth,
                                    const char16_t *domain,
                                    const char16_t *user,
                                    const char16_t *pass,
                                    nsISupports    **sessionState,
                                    nsISupports    **continuationState,
                                    uint32_t       *aFlags,
                                    char           **creds)

{
    LOG(("nsHttpNTLMAuth::GenerateCredentials\n"));

    *creds = nullptr;
    *aFlags = 0;

    // if user or password is empty, ChallengeReceived returned
    // identityInvalid = false, that means we are using default user
    // credentials; see  nsAuthSSPI::Init method for explanation of this
    // condition
    if (!user || !pass)
        *aFlags = USING_INTERNAL_IDENTITY;

    nsresult rv;
    nsCOMPtr<nsIAuthModule> module = do_QueryInterface(*continuationState, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    void *inBuf, *outBuf;
    uint32_t inBufLen, outBufLen;

    // initial challenge
    if (PL_strcasecmp(challenge, "NTLM") == 0) {
        // NTLM service name format is 'HTTP@host' for both http and https
        nsCOMPtr<nsIURI> uri;
        rv = authChannel->GetURI(getter_AddRefs(uri));
        if (NS_FAILED(rv))
            return rv;
        nsAutoCString serviceName, host;
        rv = uri->GetAsciiHost(host);
        if (NS_FAILED(rv))
            return rv;
        serviceName.AppendLiteral("HTTP@");
        serviceName.Append(host);
        // initialize auth module
        uint32_t reqFlags = nsIAuthModule::REQ_DEFAULT;
        if (isProxyAuth)
            reqFlags |= nsIAuthModule::REQ_PROXY_AUTH;

        rv = module->Init(serviceName.get(), reqFlags, domain, user, pass);
        if (NS_FAILED(rv))
            return rv;

// This update enables updated Windows machines (Win7 or patched previous
// versions) and Linux machines running Samba (updated for Channel
// Binding), to perform Channel Binding when authenticating using NTLMv2
// and an outer secure channel.
//
// Currently only implemented for Windows, linux support will be landing in
// a separate patch, update this #ifdef accordingly then.
#if defined (XP_WIN) /* || defined (LINUX) */
        // We should retrieve the server certificate and compute the CBT,
        // but only when we are using the native NTLM implementation and
        // not the internal one.
        // It is a valid case not having the security info object.  This
        // occures when we connect an https site through an ntlm proxy.
        // After the ssl tunnel has been created, we get here the second
        // time and now generate the CBT from now valid security info.
        nsCOMPtr<nsIChannel> channel = do_QueryInterface(authChannel, &rv);
        if (NS_FAILED(rv))
            return rv;

        nsCOMPtr<nsISupports> security;
        rv = channel->GetSecurityInfo(getter_AddRefs(security));
        if (NS_FAILED(rv))
            return rv;

        nsCOMPtr<nsISSLStatusProvider> statusProvider =
            do_QueryInterface(security);

        if (mUseNative && statusProvider) {
            nsCOMPtr<nsISSLStatus> status;
            rv = statusProvider->GetSSLStatus(getter_AddRefs(status));
            if (NS_FAILED(rv))
                return rv;

            nsCOMPtr<nsIX509Cert> cert;
            rv = status->GetServerCert(getter_AddRefs(cert));
            if (NS_FAILED(rv))
                return rv;

            uint32_t length;
            uint8_t* certArray;
            cert->GetRawDER(&length, &certArray);						
			
            // If there is a server certificate, we pass it along the
            // first time we call GetNextToken().
            inBufLen = length;
            inBuf = certArray;
        } else {
            // If there is no server certificate, we don't pass anything.
            inBufLen = 0;
            inBuf = nullptr;
        }
#else // Extended protection update is just for Linux and Windows machines.
        inBufLen = 0;
        inBuf = nullptr;
#endif
    }
    else {
        // decode challenge; skip past "NTLM " to the start of the base64
        // encoded data.
        int len = strlen(challenge);
        if (len < 6)
            return NS_ERROR_UNEXPECTED; // bogus challenge
        challenge += 5;
        len -= 5;

        // strip off any padding (see bug 230351)
        while (challenge[len - 1] == '=')
          len--;

        // decode into the input secbuffer
        inBufLen = (len * 3)/4;      // sufficient size (see plbase64.h)
        inBuf = nsMemory::Alloc(inBufLen);
        if (!inBuf)
            return NS_ERROR_OUT_OF_MEMORY;

        if (PL_Base64Decode(challenge, len, (char *) inBuf) == nullptr) {
            nsMemory::Free(inBuf);
            return NS_ERROR_UNEXPECTED; // improper base64 encoding
        }
    }

    rv = module->GetNextToken(inBuf, inBufLen, &outBuf, &outBufLen);
    if (NS_SUCCEEDED(rv)) {
        // base64 encode data in output buffer and prepend "NTLM "
        int credsLen = 5 + ((outBufLen + 2)/3)*4;
        *creds = (char *) nsMemory::Alloc(credsLen + 1);
        if (!*creds)
            rv = NS_ERROR_OUT_OF_MEMORY;
        else {
            memcpy(*creds, "NTLM ", 5);
            PL_Base64Encode((char *) outBuf, outBufLen, *creds + 5);
            (*creds)[credsLen] = '\0'; // null terminate
        }
        // OK, we are done with |outBuf|
        nsMemory::Free(outBuf);
    }

    if (inBuf)
        nsMemory::Free(inBuf);

    return rv;
}
nsresult
EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
                                                  const nsAString* aBody,
                                                  Element* aElement)
{
  MOZ_ASSERT(aListener->GetJSEventHandler());
  MOZ_ASSERT(aListener->mHandlerIsString, "Why are we compiling a non-string JS listener?");
  JSEventHandler* jsEventHandler = aListener->GetJSEventHandler();
  MOZ_ASSERT(!jsEventHandler->GetTypedEventHandler().HasEventHandler(),
             "What is there to compile?");

  nsresult result = NS_OK;
  nsCOMPtr<nsIDocument> doc;
  nsCOMPtr<nsIScriptGlobalObject> global =
    GetScriptGlobalAndDocument(getter_AddRefs(doc));
  NS_ENSURE_STATE(global);

  // Activate JSAPI, and make sure that exceptions are reported on the right
  // Window.
  AutoJSAPI jsapi;
  if (NS_WARN_IF(!jsapi.Init(global))) {
    return NS_ERROR_UNEXPECTED;
  }
  jsapi.TakeOwnershipOfErrorReporting();
  JSContext* cx = jsapi.cx();

  nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom;
  nsIAtom* attrName = typeAtom;

  // Flag us as not a string so we don't keep trying to compile strings which
  // can't be compiled.
  aListener->mHandlerIsString = false;

  // mTarget may not be an Element if it's a window and we're
  // getting an inline event listener forwarded from <html:body> or
  // <html:frameset> or <xul:window> or the like.
  // XXX I don't like that we have to reference content from
  // here. The alternative is to store the event handler string on
  // the JSEventHandler itself, and that still doesn't address
  // the arg names issue.
  nsCOMPtr<Element> element = do_QueryInterface(mTarget);
  MOZ_ASSERT(element || aBody, "Where will we get our body?");
  nsAutoString handlerBody;
  const nsAString* body = aBody;
  if (!aBody) {
    if (aListener->mTypeAtom == nsGkAtoms::onSVGLoad) {
      attrName = nsGkAtoms::onload;
    } else if (aListener->mTypeAtom == nsGkAtoms::onSVGUnload) {
      attrName = nsGkAtoms::onunload;
    } else if (aListener->mTypeAtom == nsGkAtoms::onSVGResize) {
      attrName = nsGkAtoms::onresize;
    } else if (aListener->mTypeAtom == nsGkAtoms::onSVGScroll) {
      attrName = nsGkAtoms::onscroll;
    } else if (aListener->mTypeAtom == nsGkAtoms::onSVGZoom) {
      attrName = nsGkAtoms::onzoom;
    } else if (aListener->mTypeAtom == nsGkAtoms::onbeginEvent) {
      attrName = nsGkAtoms::onbegin;
    } else if (aListener->mTypeAtom == nsGkAtoms::onrepeatEvent) {
      attrName = nsGkAtoms::onrepeat;
    } else if (aListener->mTypeAtom == nsGkAtoms::onendEvent) {
      attrName = nsGkAtoms::onend;
    }

    element->GetAttr(kNameSpaceID_None, attrName, handlerBody);
    body = &handlerBody;
    aElement = element;
  }
  aListener = nullptr;

  uint32_t lineNo = 0;
  nsAutoCString url (NS_LITERAL_CSTRING("-moz-evil:lying-event-listener"));
  MOZ_ASSERT(body);
  MOZ_ASSERT(aElement);
  nsIURI *uri = aElement->OwnerDoc()->GetDocumentURI();
  if (uri) {
    uri->GetSpec(url);
    lineNo = 1;
  }

  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget);
  uint32_t argCount;
  const char **argNames;
  nsContentUtils::GetEventArgNames(aElement->GetNameSpaceID(),
                                   typeAtom, win,
                                   &argCount, &argNames);

  JSAddonId *addonId = MapURIToAddonID(uri);

  // Wrap the event target, so that we can use it as the scope for the event
  // handler. Note that mTarget is different from aElement in the <body> case,
  // where mTarget is a Window.
  //
  // The wrapScope doesn't really matter here, because the target will create
  // its reflector in the proper scope, and then we'll enter that compartment.
  JS::Rooted<JSObject*> wrapScope(cx, global->GetGlobalJSObject());
  JS::Rooted<JS::Value> v(cx);
  {
    JSAutoCompartment ac(cx, wrapScope);
    nsresult rv = nsContentUtils::WrapNative(cx, mTarget, &v,
                                             /* aAllowWrapping = */ false);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }

  if (addonId) {
    JS::Rooted<JSObject*> vObj(cx, &v.toObject());
    JS::Rooted<JSObject*> addonScope(cx, xpc::GetAddonScope(cx, vObj, addonId));
    if (!addonScope) {
      return NS_ERROR_FAILURE;
    }
    JSAutoCompartment ac(cx, addonScope);

    // Wrap our event target into the addon scope, since that's where we want to
    // do all our work.
    if (!JS_WrapValue(cx, &v)) {
      return NS_ERROR_FAILURE;
    }
  }
  JS::Rooted<JSObject*> target(cx, &v.toObject());
  JSAutoCompartment ac(cx, target);

  // Now that we've entered the compartment we actually care about, create our
  // scope chain.  Note that we start with |element|, not aElement, because
  // mTarget is different from aElement in the <body> case, where mTarget is a
  // Window, and in that case we do not want the scope chain to include the body
  // or the document.
  JS::AutoObjectVector scopeChain(cx);
  if (!nsJSUtils::GetScopeChainForElement(cx, element, scopeChain)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  nsDependentAtomString str(attrName);
  // Most of our names are short enough that we don't even have to malloc
  // the JS string stuff, so don't worry about playing games with
  // refcounting XPCOM stringbuffers.
  JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx,
                                                      str.BeginReading(),
                                                      str.Length()));
  NS_ENSURE_TRUE(jsStr, NS_ERROR_OUT_OF_MEMORY);

  // Get the reflector for |aElement|, so that we can pass to setElement.
  if (NS_WARN_IF(!GetOrCreateDOMReflector(cx, target, aElement, &v))) {
    return NS_ERROR_FAILURE;
  }
  JS::CompileOptions options(cx);
  options.setIntroductionType("eventHandler")
         .setFileAndLine(url.get(), lineNo)
         .setVersion(JSVERSION_DEFAULT)
         .setElement(&v.toObject())
         .setElementAttributeName(jsStr);

  JS::Rooted<JSObject*> handler(cx);
  result = nsJSUtils::CompileFunction(jsapi, scopeChain, options,
                                      nsAtomCString(typeAtom),
                                      argCount, argNames, *body, handler.address());
  NS_ENSURE_SUCCESS(result, result);
  NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE);

  if (jsEventHandler->EventName() == nsGkAtoms::onerror && win) {
    nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
      new OnErrorEventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr);
    jsEventHandler->SetHandler(handlerCallback);
  } else if (jsEventHandler->EventName() == nsGkAtoms::onbeforeunload && win) {
    nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback =
      new OnBeforeUnloadEventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr);
    jsEventHandler->SetHandler(handlerCallback);
  } else {
    nsRefPtr<EventHandlerNonNull> handlerCallback =
      new EventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr);
    jsEventHandler->SetHandler(handlerCallback);
  }

  return result;
}
nsresult
EventListenerManager::SetEventHandler(nsIAtom* aName,
                                      const nsAString& aBody,
                                      bool aDeferCompilation,
                                      bool aPermitUntrustedEvents,
                                      Element* aElement)
{
  nsCOMPtr<nsIDocument> doc;
  nsCOMPtr<nsIScriptGlobalObject> global =
    GetScriptGlobalAndDocument(getter_AddRefs(doc));

  if (!global) {
    // This can happen; for example this document might have been
    // loaded as data.
    return NS_OK;
  }

#ifdef DEBUG
  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(global);
  if (win) {
    MOZ_ASSERT(win->IsInnerWindow(), "We should not have an outer window here!");
  }
#endif

  nsresult rv = NS_OK;
  // return early preventing the event listener from being added
  // 'doc' is fetched above
  if (doc) {
    // Don't allow adding an event listener if the document is sandboxed
    // without 'allow-scripts'.
    if (doc->GetSandboxFlags() & SANDBOXED_SCRIPTS) {
      return NS_ERROR_DOM_SECURITY_ERR;
    }

    nsCOMPtr<nsIContentSecurityPolicy> csp;
    rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
    NS_ENSURE_SUCCESS(rv, rv);

    if (csp) {
      bool inlineOK = true;
      bool reportViolations = false;
      rv = csp->GetAllowsInlineScript(&reportViolations, &inlineOK);
      NS_ENSURE_SUCCESS(rv, rv);

      if (reportViolations) {
        // gather information to log with violation report
        nsIURI* uri = doc->GetDocumentURI();
        nsAutoCString asciiSpec;
        if (uri)
          uri->GetAsciiSpec(asciiSpec);
        nsAutoString scriptSample, attr, tagName(NS_LITERAL_STRING("UNKNOWN"));
        aName->ToString(attr);
        nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mTarget));
        if (domNode)
          domNode->GetNodeName(tagName);
        // build a "script sample" based on what we know about this element
        scriptSample.Assign(attr);
        scriptSample.AppendLiteral(" attribute on ");
        scriptSample.Append(tagName);
        scriptSample.AppendLiteral(" element");
        csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT,
                                 NS_ConvertUTF8toUTF16(asciiSpec),
                                 scriptSample,
                                 0,
                                 EmptyString(),
                                 EmptyString());
      }

      // return early if CSP wants us to block inline scripts
      if (!inlineOK) {
        return NS_OK;
      }
    }
  }

  // This might be the first reference to this language in the global
  // We must init the language before we attempt to fetch its context.
  if (NS_FAILED(global->EnsureScriptEnvironment())) {
    NS_WARNING("Failed to setup script environment for this language");
    // but fall through and let the inevitable failure below handle it.
  }

  nsIScriptContext* context = global->GetScriptContext();
  NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
  NS_ENSURE_STATE(global->GetGlobalJSObject());

  Listener* listener = SetEventHandlerInternal(aName,
                                               EmptyString(),
                                               TypedEventHandler(),
                                               aPermitUntrustedEvents);

  if (!aDeferCompilation) {
    return CompileEventHandlerInternal(listener, &aBody, aElement);
  }

  return NS_OK;
}
NS_IMETHODIMP
nsXPathExpression::EvaluateWithContext(nsIDOMNode *aContextNode,
                                       PRUint32 aContextPosition,
                                       PRUint32 aContextSize,
                                       PRUint16 aType,
                                       nsISupports *aInResult,
                                       nsISupports **aResult)
{
    nsCOMPtr<nsINode> context = do_QueryInterface(aContextNode);
    NS_ENSURE_ARG(context);

    if (aContextPosition > aContextSize)
        return NS_ERROR_FAILURE;

    if (!nsContentUtils::CanCallerAccess(aContextNode))
        return NS_ERROR_DOM_SECURITY_ERR;

    if (mDocument && mDocument != aContextNode) {
        nsCOMPtr<nsIDOMDocument> contextDocument;
        aContextNode->GetOwnerDocument(getter_AddRefs(contextDocument));

        if (mDocument != contextDocument) {
            return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
        }
    }

    nsresult rv;
    PRUint16 nodeType;
    rv = aContextNode->GetNodeType(&nodeType);
    NS_ENSURE_SUCCESS(rv, rv);

    if (nodeType == nsIDOMNode::TEXT_NODE ||
        nodeType == nsIDOMNode::CDATA_SECTION_NODE) {
        nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(aContextNode);
        NS_ENSURE_TRUE(textNode, NS_ERROR_FAILURE);

        if (textNode) {
            PRUint32 textLength;
            textNode->GetLength(&textLength);
            if (textLength == 0)
                return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
        }

        // XXX Need to get logical XPath text node for CDATASection
        //     and Text nodes.
    }
    else if (nodeType != nsIDOMNode::DOCUMENT_NODE &&
             nodeType != nsIDOMNode::ELEMENT_NODE &&
             nodeType != nsIDOMNode::ATTRIBUTE_NODE &&
             nodeType != nsIDOMNode::COMMENT_NODE &&
             nodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE &&
             nodeType != nsIDOMXPathNamespace::XPATH_NAMESPACE_NODE) {
        return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    }

    NS_ENSURE_ARG(aResult);
    *aResult = nsnull;

    nsAutoPtr<txXPathNode> contextNode(txXPathNativeNode::createXPathNode(aContextNode));
    if (!contextNode) {
        return NS_ERROR_OUT_OF_MEMORY;
    }

    EvalContextImpl eContext(*contextNode, aContextPosition, aContextSize,
                             mRecycler);
    nsRefPtr<txAExprResult> exprResult;
    rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult));
    NS_ENSURE_SUCCESS(rv, rv);

    PRUint16 resultType = aType;
    if (aType == nsIDOMXPathResult::ANY_TYPE) {
        short exprResultType = exprResult->getResultType();
        switch (exprResultType) {
            case txAExprResult::NUMBER:
                resultType = nsIDOMXPathResult::NUMBER_TYPE;
                break;
            case txAExprResult::STRING:
                resultType = nsIDOMXPathResult::STRING_TYPE;
                break;
            case txAExprResult::BOOLEAN:
                resultType = nsIDOMXPathResult::BOOLEAN_TYPE;
                break;
            case txAExprResult::NODESET:
                resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE;
                break;
            case txAExprResult::RESULT_TREE_FRAGMENT:
                NS_ERROR("Can't return a tree fragment!");
                return NS_ERROR_FAILURE;
        }
    }

    // We need a result object and it must be our implementation.
    nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(aInResult);
    if (!xpathResult) {
        // Either no aInResult or not one of ours.
        xpathResult = new nsXPathResult();
        NS_ENSURE_TRUE(xpathResult, NS_ERROR_OUT_OF_MEMORY);
    }
    rv = xpathResult->SetExprResult(exprResult, resultType, context);
    NS_ENSURE_SUCCESS(rv, rv);

    return CallQueryInterface(xpathResult, aResult);
}
//
// Native method InstallChrome
//
static JSBool
InstallTriggerGlobalInstallChrome(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj);
  if (!nativeThis)
    return JS_FALSE;

  uint32       chromeType = NOT_CHROME;
  nsAutoString sourceURL;
  nsAutoString name;

  *rval = JSVAL_FALSE;

  // get chromeType first, the update enabled check for skins skips whitelisting
  if (argc >=1)
  {
      if (!JS_ValueToECMAUint32(cx, argv[0], &chromeType))
          return JS_FALSE;
  }

  // make sure XPInstall is enabled, return if not
  nsIScriptGlobalObject *globalObject = nsnull;
  nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx);
  if (scriptContext)
      globalObject = scriptContext->GetGlobalObject();

  if (!globalObject)
      return JS_TRUE;

  // get window.location to construct relative URLs
  nsCOMPtr<nsIURI> baseURL;
  JSObject* global = JS_GetGlobalObject(cx);
  if (global)
  {
    jsval v;
    if (JS_GetProperty(cx,global,"location",&v))
    {
      nsAutoString location;
      ConvertJSValToStr( location, cx, v );
      NS_NewURI(getter_AddRefs(baseURL), location);
    }
  }


  if ( argc >= 3 )
  {
    ConvertJSValToStr(sourceURL, cx, argv[1]);
    ConvertJSValToStr(name, cx, argv[2]);

    if (baseURL)
    {
        nsCAutoString resolvedURL;
        baseURL->Resolve(NS_ConvertUTF16toUTF8(sourceURL), resolvedURL);
        sourceURL = NS_ConvertUTF8toUTF16(resolvedURL);
    }

    // Make sure caller is allowed to load this url.
    nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, sourceURL);
    if (NS_FAILED(rv))
        return JS_FALSE;

    if ( chromeType & CHROME_ALL )
    {
        // there's at least one known chrome type
        nsCOMPtr<nsIURI> checkuri;
        nsresult rv = nativeThis->GetOriginatingURI(globalObject,
                                                    getter_AddRefs(checkuri));
        if (NS_SUCCEEDED(rv))
        {
            nsAutoPtr<nsXPITriggerInfo> trigger(new nsXPITriggerInfo());
            nsAutoPtr<nsXPITriggerItem> item(new nsXPITriggerItem(name.get(),
                                                                  sourceURL.get(),
                                                                  nsnull));
            if (trigger && item)
            {
                // trigger will free item when complete
                trigger->Add(item.forget());
                nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject));
                nsCOMPtr<nsIXPIInstallInfo> installInfo =
                    new nsXPIInstallInfo(win, checkuri, trigger, chromeType);
                if (installInfo)
                {
                    // installInfo owns trigger now
                    trigger.forget();
                    PRBool enabled = PR_FALSE;
                    nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST,
                                              &enabled);
                    if (!enabled)
                    {
                        nsCOMPtr<nsIObserverService> os =
                          mozilla::services::GetObserverService();
                        if (os)
                            os->NotifyObservers(installInfo,
                                                "xpinstall-install-blocked",
                                                nsnull);
                    }
                    else
                    {
                        PRBool nativeRet = PR_FALSE;
                        nativeThis->StartInstall(installInfo, &nativeRet);
                        *rval = BOOLEAN_TO_JSVAL(nativeRet);
                    }
                }
            }
        }
    }
  }
  return JS_TRUE;
}
Ejemplo n.º 17
0
NS_IMETHODIMP
nsIncrementalDownload::OnStartRequest(nsIRequest *request,
                                      nsISupports *context)
{
  nsresult rv;

  nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(request, &rv);
  if (NS_FAILED(rv))
    return rv;

  // Ensure that we are receiving a 206 response.
  PRUint32 code;
  rv = http->GetResponseStatus(&code);
  if (NS_FAILED(rv))
    return rv;
  if (code != 206) {
    // We may already have the entire file downloaded, in which case
    // our request for a range beyond the end of the file would have
    // been met with an error response code.
    if (code == 416 && mTotalSize == -1) {
      mTotalSize = mCurrentSize;
      // Return an error code here to suppress OnDataAvailable.
      return NS_ERROR_DOWNLOAD_COMPLETE;
    }
    // The server may have decided to give us all of the data in one chunk.  If
    // we requested a partial range, then we don't want to download all of the
    // data at once.  So, we'll just try again, but if this keeps happening then
    // we'll eventually give up.
    if (code == 200) {
      if (mInterval) {
        mChannel = nsnull;
        if (++mNonPartialCount > MAX_RETRY_COUNT) {
          NS_WARNING("unable to fetch a byte range; giving up");
          return NS_ERROR_FAILURE;
        }
        // Increase delay with each failure.
        StartTimer(mInterval * mNonPartialCount);
        return NS_ERROR_DOWNLOAD_NOT_PARTIAL;
      }
      // Since we have been asked to download the rest of the file, we can deal
      // with a 200 response.  This may result in downloading the beginning of
      // the file again, but that can't really be helped.
    } else {
      NS_WARNING("server response was unexpected");
      return NS_ERROR_UNEXPECTED;
    }
  } else {
    // We got a partial response, so clear this counter in case the next chunk
    // results in a 200 response.
    mNonPartialCount = 0;
  }

  // Do special processing after the first response.
  if (mTotalSize == -1) {
    // Update knowledge of mFinalURI
    rv = http->GetURI(getter_AddRefs(mFinalURI));
    if (NS_FAILED(rv))
      return rv;

    if (code == 206) {
      // OK, read the Content-Range header to determine the total size of this
      // download file.
      nsCAutoString buf;
      rv = http->GetResponseHeader(NS_LITERAL_CSTRING("Content-Range"), buf);
      if (NS_FAILED(rv))
        return rv;
      PRInt32 slash = buf.FindChar('/');
      if (slash == kNotFound) {
        NS_WARNING("server returned invalid Content-Range header!");
        return NS_ERROR_UNEXPECTED;
      }
      if (PR_sscanf(buf.get() + slash + 1, "%lld", &mTotalSize) != 1)
        return NS_ERROR_UNEXPECTED;
    } else {
      http->GetContentLength(&mTotalSize);
      // We need to know the total size of the thing we're trying to download.
      if (mTotalSize == -1) {
        NS_WARNING("server returned no content-length header!");
        return NS_ERROR_UNEXPECTED;
      }
      // Need to truncate (or create, if it doesn't exist) the file since we
      // are downloading the whole thing.
      WriteToFile(mDest, nsnull, 0, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE);
      mCurrentSize = 0;
    }

    // Notify observer that we are starting...
    rv = CallOnStartRequest();
    if (NS_FAILED(rv))
      return rv;
  }

  // Adjust mChunkSize accordingly if mCurrentSize is close to mTotalSize.
  PRInt64 diff = mTotalSize - mCurrentSize;
  if (diff <= 0) {
    NS_WARNING("about to set a bogus chunk size; giving up");
    return NS_ERROR_UNEXPECTED;
  }

  if (diff < mChunkSize)
    mChunkSize = PRUint32(diff);

  mChunk = new char[mChunkSize];
  if (!mChunk)
    rv = NS_ERROR_OUT_OF_MEMORY;

  return rv;
}
//
// Native method StartSoftwareUpdate
//
static JSBool
InstallTriggerGlobalStartSoftwareUpdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj);
  if (!nativeThis)
    return JS_FALSE;

  PRBool       nativeRet;
  PRInt32      flags = 0;

  *rval = JSVAL_FALSE;

  nsIScriptGlobalObject *globalObject = nsnull;
  nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx);
  if (scriptContext)
      globalObject = scriptContext->GetGlobalObject();

  if (!globalObject)
      return JS_TRUE;

  // get window.location to construct relative URLs
  nsCOMPtr<nsIURI> baseURL;
  JSObject* global = JS_GetGlobalObject(cx);
  if (global)
  {
    jsval v;
    if (JS_GetProperty(cx,global,"location",&v))
    {
      nsAutoString location;
      ConvertJSValToStr( location, cx, v );
      NS_NewURI(getter_AddRefs(baseURL), location);
    }
  }


  if ( argc >= 1 )
  {
    nsAutoString xpiURL;
    ConvertJSValToStr(xpiURL, cx, argv[0]);
    if (baseURL)
    {
        nsCAutoString resolvedURL;
        baseURL->Resolve(NS_ConvertUTF16toUTF8(xpiURL), resolvedURL);
        xpiURL = NS_ConvertUTF8toUTF16(resolvedURL);
    }

    // Make sure caller is allowed to load this url.
    nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, xpiURL);
    if (NS_FAILED(rv))
        return JS_FALSE;

    if (argc >= 2 && !JS_ValueToInt32(cx, argv[1], (int32 *)&flags))
    {
        JS_ReportError(cx, "StartSoftwareUpdate() 2nd parameter must be a number");
        return JS_FALSE;
    }

    nsCOMPtr<nsIURI> checkuri;
    rv = nativeThis->GetOriginatingURI(globalObject, getter_AddRefs(checkuri));
    if (NS_SUCCEEDED(rv))
    {
        nsAutoPtr<nsXPITriggerInfo> trigger(new nsXPITriggerInfo());
        nsAutoPtr<nsXPITriggerItem> item(new nsXPITriggerItem(0,
                                                              xpiURL.get(),
                                                              nsnull));
        if (trigger && item)
        {
            // trigger will free item when complete
            trigger->Add(item.forget());
            nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject));
            nsCOMPtr<nsIXPIInstallInfo> installInfo =
                                new nsXPIInstallInfo(win, checkuri, trigger, 0);
            if (installInfo)
            {
                // From here trigger is owned by installInfo until passed on to nsXPInstallManager
                trigger.forget();
                PRBool enabled = PR_FALSE;
                nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST, &enabled);
                if (!enabled)
                {
                    nsCOMPtr<nsIObserverService> os =
                      mozilla::services::GetObserverService();
                    if (os)
                        os->NotifyObservers(installInfo,
                                            "xpinstall-install-blocked",
                                            nsnull);
                }
                else
                {
                    nativeThis->StartInstall(installInfo, &nativeRet);
                    *rval = BOOLEAN_TO_JSVAL(nativeRet);
                }
            }
        }
    }
  }
  else
  {
    JS_ReportError(cx, "Function StartSoftwareUpdate requires 1 parameters");
    return JS_FALSE;
  }

  return JS_TRUE;
}
nsMsgGroupThread *nsMsgGroupView::AddHdrToThread(nsIMsgDBHdr *msgHdr, bool *pNewThread)
{
  nsMsgKey msgKey;
  uint32_t msgFlags;
  msgHdr->GetMessageKey(&msgKey);
  msgHdr->GetFlags(&msgFlags);
  nsString hashKey;
  nsresult rv = HashHdr(msgHdr, hashKey);
  if (NS_FAILED(rv))
    return nullptr;

//  if (m_sortType == nsMsgViewSortType::byDate)
//    msgKey = ((nsPRUint32Key *) hashKey)->GetValue();
  nsCOMPtr<nsIMsgThread> msgThread;
  m_groupsTable.Get(hashKey, getter_AddRefs(msgThread));
  bool newThread = !msgThread;
  *pNewThread = newThread;
  nsMsgViewIndex viewIndexOfThread; // index of first message in thread in view
  nsMsgViewIndex threadInsertIndex; // index of newly added header in thread

  nsMsgGroupThread *foundThread = static_cast<nsMsgGroupThread *>(msgThread.get());
  if (foundThread) 
  {
    // find the view index of the root node of the thread in the view
    viewIndexOfThread = GetIndexOfFirstDisplayedKeyInThread(foundThread,
                                                            true);
    if (viewIndexOfThread == nsMsgViewIndex_None)
    {
      // Something is wrong with the group table. Remove the old group and
      // insert a new one.
      m_groupsTable.Remove(hashKey);
      foundThread = nullptr;
      *pNewThread = newThread = true;
    }
  }
  // If the thread does not already exist, create one
  if (!foundThread)
  {
    foundThread = CreateGroupThread(m_db);
    msgThread = do_QueryInterface(foundThread);
    m_groupsTable.Put(hashKey, msgThread);
    if (GroupViewUsesDummyRow())
    {
      foundThread->m_dummy = true;
      msgFlags |=  MSG_VIEW_FLAG_DUMMY | MSG_VIEW_FLAG_HASCHILDREN;
    }

    viewIndexOfThread = GetInsertIndex(msgHdr);
    if (viewIndexOfThread == nsMsgViewIndex_None)
      viewIndexOfThread = m_keys.Length();

    // add the thread root node to the view
    InsertMsgHdrAt(viewIndexOfThread, msgHdr, msgKey,
                   msgFlags | MSG_VIEW_FLAG_ISTHREAD | nsMsgMessageFlags::Elided, 0);

    // For dummy rows, Have the header serve as the dummy node (it will be added
    //  again for its actual content later.)
    if (GroupViewUsesDummyRow())
      foundThread->InsertMsgHdrAt(0, msgHdr);

    // Calculate the (integer thread key); this really only needs to be done for
    //  the byDate case where the expanded state of the groups can be easily
    //  persisted and restored because of the bounded, consecutive value space
    //  occupied.  We calculate an integer value in all cases mainly because
    //  it's the sanest choice available...
    // (The thread key needs to be an integer, so parse hash keys that are
    //  stringified integers to real integers, and hash actual strings into
    //  integers.)
    if ((m_sortType == nsMsgViewSortType::byAttachments) ||
        (m_sortType == nsMsgViewSortType::byFlagged) ||
        (m_sortType == nsMsgViewSortType::byPriority) ||
        (m_sortType == nsMsgViewSortType::byStatus) ||
        (m_sortType == nsMsgViewSortType::byReceived) ||
        (m_sortType == nsMsgViewSortType::byDate))
      foundThread->m_threadKey =
        atoi(NS_LossyConvertUTF16toASCII(hashKey).get());
    else
      foundThread->m_threadKey = (nsMsgKey)
        PL_HashString(NS_LossyConvertUTF16toASCII(hashKey).get());
  }
  // Add the message to the thread as an actual content-bearing header.
  // (If we use dummy rows, it was already added to the thread during creation.)
  threadInsertIndex = foundThread->AddChildFromGroupView(msgHdr, this);
  // check if new hdr became thread root
  if (!newThread && threadInsertIndex == 0)
  {
    // update the root node's header (in the view) to be the same as the root
    //  node in the thread.
    SetMsgHdrAt(msgHdr, viewIndexOfThread, msgKey,
                (msgFlags & ~(nsMsgMessageFlags::Elided)) |
                  // maintain elided flag and dummy flag
                  (m_flags[viewIndexOfThread] & (nsMsgMessageFlags::Elided
                                                 | MSG_VIEW_FLAG_DUMMY))
                  // ensure thread and has-children flags are set
                  | MSG_VIEW_FLAG_ISTHREAD | MSG_VIEW_FLAG_HASCHILDREN, 0);
    // update the content-bearing copy in the thread to match.  (the root and
    //  first nodes in the thread should always be the same header.)
    // note: the guy who used to be the root will still exist.  If our list of
    //  nodes was [A A], a new node B is introduced which sorts to be the first
    //  node, giving us [B A A], our copy makes that [B B A], and things are
    //  right in the world (since we want the first two headers to be the same
    //  since one is our dummy and one is real.)
    if (GroupViewUsesDummyRow())
      foundThread->SetMsgHdrAt(1, msgHdr); // replace the old duplicate dummy header.
    // we do not update the content-bearing copy in the view to match; we leave
    //  that up to OnNewHeader, which is the piece of code who gets to care
    //  about whether the thread's children are shown or not (elided)
  }

  return foundThread;
}
Ejemplo n.º 20
0
NS_IMETHODIMP
IDBDatabase::Transaction(const jsval& aStoreNames,
                         PRUint16 aMode,
                         JSContext* aCx,
                         PRUint8 aOptionalArgCount,
                         nsIIDBTransaction** _retval)
{
  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");

  if (IndexedDatabaseManager::IsShuttingDown()) {
    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
  }

  if (mClosed) {
    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
  }

  if (mRunningVersionChange) {
    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
  }

  if (aOptionalArgCount) {
    if (aMode != nsIIDBTransaction::READ_WRITE &&
        aMode != nsIIDBTransaction::READ_ONLY) {
      return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
    }
  }
  else {
    aMode = nsIIDBTransaction::READ_ONLY;
  }

  nsresult rv;
  nsTArray<nsString> storesToOpen;

  if (!JSVAL_IS_PRIMITIVE(aStoreNames)) {
    JSObject* obj = JSVAL_TO_OBJECT(aStoreNames);

    // See if this is a JS array.
    if (JS_IsArrayObject(aCx, obj)) {
      jsuint length;
      if (!JS_GetArrayLength(aCx, obj, &length)) {
        return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
      }

      if (!length) {
        return NS_ERROR_DOM_INVALID_ACCESS_ERR;
      }

      storesToOpen.SetCapacity(length);

      for (jsuint index = 0; index < length; index++) {
        jsval val;
        JSString* jsstr;
        nsDependentJSString str;
        if (!JS_GetElement(aCx, obj, index, &val) ||
            !(jsstr = JS_ValueToString(aCx, val)) ||
            !str.init(aCx, jsstr)) {
          return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
        }

        storesToOpen.AppendElement(str);
      }

      NS_ASSERTION(!storesToOpen.IsEmpty(),
                   "Must have something here or else code below will "
                   "misbehave!");
    }
    else {
      // Perhaps some kind of wrapped object?
      nsIXPConnect* xpc = nsContentUtils::XPConnect();
      NS_ASSERTION(xpc, "This should never be null!");

      nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
      rv = xpc->GetWrappedNativeOfJSObject(aCx, obj, getter_AddRefs(wrapper));
      NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);

      if (wrapper) {
        nsISupports* wrappedObject = wrapper->Native();
        NS_ENSURE_TRUE(wrappedObject, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);

        // We only accept DOMStringList.
        nsCOMPtr<nsIDOMDOMStringList> list = do_QueryInterface(wrappedObject);
        if (list) {
          PRUint32 length;
          rv = list->GetLength(&length);
          NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);

          if (!length) {
            return NS_ERROR_DOM_INVALID_ACCESS_ERR;
          }

          storesToOpen.SetCapacity(length);

          for (PRUint32 index = 0; index < length; index++) {
            nsString* item = storesToOpen.AppendElement();
            NS_ASSERTION(item, "This should never fail!");

            rv = list->Item(index, *item);
            NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
          }

          NS_ASSERTION(!storesToOpen.IsEmpty(),
                       "Must have something here or else code below will "
                       "misbehave!");
        }
      }
    }
  }

  // If our list is empty here then the argument must have been an object that
  // we don't support or a primitive. Either way we convert to a string.
  if (storesToOpen.IsEmpty()) {
    JSString* jsstr;
    nsDependentJSString str;
    if (!(jsstr = JS_ValueToString(aCx, aStoreNames)) ||
        !str.init(aCx, jsstr)) {
      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
    }

    storesToOpen.AppendElement(str);
  }

  // Now check to make sure the object store names we collected actually exist.
  DatabaseInfo* info = Info();
  for (PRUint32 index = 0; index < storesToOpen.Length(); index++) {
    if (!info->ContainsStoreName(storesToOpen[index])) {
      return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
    }
  }

  nsRefPtr<IDBTransaction> transaction =
    IDBTransaction::Create(this, storesToOpen, aMode, false);
  NS_ENSURE_TRUE(transaction, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);

  transaction.forget(_retval);
  return NS_OK;
}
Ejemplo n.º 21
0
nsresult
nsMsgSendLater::StartNextMailFileSend(nsresult prevStatus)
{
    bool hasMoreElements = false;
    if ((!mEnumerator) ||
            NS_FAILED(mEnumerator->HasMoreElements(&hasMoreElements)) ||
            !hasMoreElements)
    {
        // Notify that this message has finished being sent.
        NotifyListenersOnProgress(mTotalSendCount, mMessagesToSend.Count(), 100, 100);

        // EndSendMessages resets everything for us
        EndSendMessages(prevStatus, nullptr, mTotalSendCount, mTotalSentSuccessfully);

        // XXX Should we be releasing references so that we don't hold onto items
        // unnecessarily.
        return NS_OK;
    }

    // If we've already sent a message, and are sending more, send out a progress
    // update with 100% for both send and copy as we must have finished by now.
    if (mTotalSendCount)
        NotifyListenersOnProgress(mTotalSendCount, mMessagesToSend.Count(), 100, 100);

    nsCOMPtr<nsISupports> currentItem;
    nsresult rv = mEnumerator->GetNext(getter_AddRefs(currentItem));
    NS_ENSURE_SUCCESS(rv, rv);

    mMessage = do_QueryInterface(currentItem);
    if (!mMessage)
        return NS_ERROR_NOT_AVAILABLE;

    if (!mMessageFolder)
        return NS_ERROR_UNEXPECTED;

    nsCString messageURI;
    mMessageFolder->GetUriForMsg(mMessage, messageURI);

    rv = nsMsgCreateTempFile("nsqmail.tmp", getter_AddRefs(mTempFile));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIMsgMessageService> messageService;
    rv = GetMessageServiceFromURI(messageURI, getter_AddRefs(messageService));
    if (NS_FAILED(rv) && !messageService)
        return NS_ERROR_FACTORY_NOT_LOADED;

    ++mTotalSendCount;

    nsCString identityKey;
    rv = mMessage->GetStringProperty(HEADER_X_MOZILLA_IDENTITY_KEY,
                                     getter_Copies(identityKey));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIMsgIdentity> identity;
    rv = GetIdentityFromKey(identityKey.get(), getter_AddRefs(identity));
    NS_ENSURE_SUCCESS(rv, rv);

    // Notify that we're just about to start sending this message
    NotifyListenersOnMessageStartSending(mTotalSendCount, mMessagesToSend.Count(),
                                         identity);

    // Setup what we need to parse the data stream correctly
    m_inhead = true;
    m_headersFP = 0;
    m_headersPosition = 0;
    m_bytesRead = 0;
    m_position = 0;
    m_flagsPosition = 0;
    m_headersSize = 0;
    PR_FREEIF(mLeftoverBuffer);

    // Now, get our stream listener interface and plug it into the DisplayMessage
    // operation
    AddRef();

    rv = messageService->DisplayMessage(messageURI.get(),
                                        static_cast<nsIStreamListener*>(this),
                                        nullptr, nullptr, nullptr, nullptr);

    Release();

    return rv;
}
Ejemplo n.º 22
0
/**
 * Performs initialization of the MANDATORY components of the Video Engine
 */
MediaConduitErrorCode WebrtcVideoConduit::Init(WebrtcVideoConduit *other)
{
  CSFLogDebug(logTag,  "%s this=%p other=%p", __FUNCTION__, this, other);

#ifdef MOZILLA_INTERNAL_API
  // already know we must be on MainThread barring unit test weirdness
  MOZ_ASSERT(NS_IsMainThread());

  nsresult rv;
  nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
  if (!NS_WARN_IF(NS_FAILED(rv)))
  {
    nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);

    if (branch)
    {
      int32_t temp;
      NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.video.test_latency", &mVideoLatencyTestEnable)));
      NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.min_bitrate", &temp)));
      if (temp >= 0) {
        mMinBitrate = temp;
      }
      NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.start_bitrate", &temp)));
      if (temp >= 0) {
        mStartBitrate = temp;
      }
      NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.max_bitrate", &temp)));
      if (temp >= 0) {
        mMaxBitrate = temp;
      }
      bool use_loadmanager = false;
      NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.navigator.load_adapt", &use_loadmanager)));
      if (use_loadmanager) {
        mLoadManager = LoadManagerBuild();
      }
    }
  }
#endif

  if (other) {
    MOZ_ASSERT(!other->mOtherDirection);
    other->mOtherDirection = this;
    mOtherDirection = other;

    // only one can call ::Create()/GetVideoEngine()
    MOZ_ASSERT(other->mVideoEngine);
    mVideoEngine = other->mVideoEngine;
  } else {

#ifdef MOZ_WIDGET_ANDROID
    // get the JVM
    JavaVM *jvm = jsjni_GetVM();

    if (webrtc::VideoEngine::SetAndroidObjects(jvm) != 0) {
      CSFLogError(logTag,  "%s: could not set Android objects", __FUNCTION__);
      return kMediaConduitSessionNotInited;
    }
#endif

    // Per WebRTC APIs below function calls return nullptr on failure
    if( !(mVideoEngine = webrtc::VideoEngine::Create()) )
    {
      CSFLogError(logTag, "%s Unable to create video engine ", __FUNCTION__);
      return kMediaConduitSessionNotInited;
    }

    EnableWebRtcLog();
  }

  if( !(mPtrViEBase = ViEBase::GetInterface(mVideoEngine)))
  {
    CSFLogError(logTag, "%s Unable to get video base interface ", __FUNCTION__);
    return kMediaConduitSessionNotInited;
  }

  if( !(mPtrViECapture = ViECapture::GetInterface(mVideoEngine)))
  {
    CSFLogError(logTag, "%s Unable to get video capture interface", __FUNCTION__);
    return kMediaConduitSessionNotInited;
  }

  if( !(mPtrViECodec = ViECodec::GetInterface(mVideoEngine)))
  {
    CSFLogError(logTag, "%s Unable to get video codec interface ", __FUNCTION__);
    return kMediaConduitSessionNotInited;
  }

  if( !(mPtrViENetwork = ViENetwork::GetInterface(mVideoEngine)))
  {
    CSFLogError(logTag, "%s Unable to get video network interface ", __FUNCTION__);
    return kMediaConduitSessionNotInited;
  }

  if( !(mPtrViERender = ViERender::GetInterface(mVideoEngine)))
  {
    CSFLogError(logTag, "%s Unable to get video render interface ", __FUNCTION__);
    return kMediaConduitSessionNotInited;
  }

  mPtrExtCodec = webrtc::ViEExternalCodec::GetInterface(mVideoEngine);
  if (!mPtrExtCodec) {
    CSFLogError(logTag, "%s Unable to get external codec interface: %d ",
                __FUNCTION__,mPtrViEBase->LastError());
    return kMediaConduitSessionNotInited;
  }

  if( !(mPtrRTP = webrtc::ViERTP_RTCP::GetInterface(mVideoEngine)))
  {
    CSFLogError(logTag, "%s Unable to get video RTCP interface ", __FUNCTION__);
    return kMediaConduitSessionNotInited;
  }

  if ( !(mPtrExtCodec = webrtc::ViEExternalCodec::GetInterface(mVideoEngine)))
  {
    CSFLogError(logTag, "%s Unable to get external codec interface %d ",
                __FUNCTION__, mPtrViEBase->LastError());
    return kMediaConduitSessionNotInited;
  }

  if (other) {
    mChannel = other->mChannel;
    mPtrExtCapture = other->mPtrExtCapture;
    mCapId = other->mCapId;
  } else {
    CSFLogDebug(logTag, "%s Engine Created: Init'ng the interfaces ",__FUNCTION__);

    if(mPtrViEBase->Init() == -1)
    {
      CSFLogError(logTag, " %s Video Engine Init Failed %d ",__FUNCTION__,
                  mPtrViEBase->LastError());
      return kMediaConduitSessionNotInited;
    }

    if(mPtrViEBase->CreateChannel(mChannel) == -1)
    {
      CSFLogError(logTag, " %s Channel creation Failed %d ",__FUNCTION__,
                  mPtrViEBase->LastError());
      return kMediaConduitChannelError;
    }

    if(mPtrViENetwork->RegisterSendTransport(mChannel, *this) == -1)
    {
      CSFLogError(logTag,  "%s ViENetwork Failed %d ", __FUNCTION__,
                  mPtrViEBase->LastError());
      return kMediaConduitTransportRegistrationFail;
    }

    if(mPtrViECapture->AllocateExternalCaptureDevice(mCapId,
                                                     mPtrExtCapture) == -1)
    {
      CSFLogError(logTag, "%s Unable to Allocate capture module: %d ",
                  __FUNCTION__, mPtrViEBase->LastError());
      return kMediaConduitCaptureError;
    }

    if(mPtrViECapture->ConnectCaptureDevice(mCapId,mChannel) == -1)
    {
      CSFLogError(logTag, "%s Unable to Connect capture module: %d ",
                  __FUNCTION__,mPtrViEBase->LastError());
      return kMediaConduitCaptureError;
    }

    if(mPtrViERender->AddRenderer(mChannel,
                                  webrtc::kVideoI420,
                                  (webrtc::ExternalRenderer*) this) == -1)
    {
      CSFLogError(logTag, "%s Failed to added external renderer ", __FUNCTION__);
      return kMediaConduitInvalidRenderer;
    }
    // Set up some parameters, per juberti. Set MTU.
    if(mPtrViENetwork->SetMTU(mChannel, 1200) != 0)
    {
      CSFLogError(logTag,  "%s MTU Failed %d ", __FUNCTION__,
                  mPtrViEBase->LastError());
      return kMediaConduitMTUError;
    }
    // Turn on RTCP and loss feedback reporting.
    if(mPtrRTP->SetRTCPStatus(mChannel, webrtc::kRtcpCompound_RFC4585) != 0)
    {
      CSFLogError(logTag,  "%s RTCPStatus Failed %d ", __FUNCTION__,
                  mPtrViEBase->LastError());
      return kMediaConduitRTCPStatusError;
    }
  }

  CSFLogError(logTag, "%s Initialization Done", __FUNCTION__);
  return kMediaConduitNoError;
}
Ejemplo n.º 23
0
// If you change DataDocumentContentPolicy, make sure to check that
// CHECK_PRINCIPAL_AND_DATA in nsContentPolicyUtils is still valid.
// nsContentPolicyUtils may not pass all the parameters to ShouldLoad.
NS_IMETHODIMP
nsDataDocumentContentPolicy::ShouldLoad(uint32_t aContentType,
                                        nsIURI *aContentLocation,
                                        nsIURI *aRequestingLocation,
                                        nsISupports *aRequestingContext,
                                        const nsACString &aMimeGuess,
                                        nsISupports *aExtra,
                                        nsIPrincipal *aRequestPrincipal,
                                        int16_t *aDecision)
{
  MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
             "We should only see external content policy types here.");

  *aDecision = nsIContentPolicy::ACCEPT;
  // Look for the document.  In most cases, aRequestingContext is a node.
  nsCOMPtr<nsIDocument> doc;
  nsCOMPtr<nsINode> node = do_QueryInterface(aRequestingContext);
  if (node) {
    doc = node->OwnerDoc();
  } else {
    nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aRequestingContext);
    if (window) {
      doc = window->GetDoc();
    }
  }

  // DTDs are always OK to load
  if (!doc || aContentType == nsIContentPolicy::TYPE_DTD) {
    return NS_OK;
  }

  // Nothing else is OK to load for data documents
  if (doc->IsLoadedAsData()) {
    // ...but let static (print/print preview) documents to load fonts.
    if (!doc->IsStaticDocument() || aContentType != nsIContentPolicy::TYPE_FONT) {
      *aDecision = nsIContentPolicy::REJECT_TYPE;
      return NS_OK;
    }
  }

  if (doc->IsBeingUsedAsImage()) {
    // We only allow SVG images to load content from URIs that are local and
    // also satisfy one of the following conditions:
    //  - URI inherits security context, e.g. data URIs
    //   OR
    //  - URI loadable by subsumers, e.g. blob URIs
    // Any URI that doesn't meet these requirements will be rejected below.
    if (!HasFlags(aContentLocation,
                  nsIProtocolHandler::URI_IS_LOCAL_RESOURCE) ||
        (!HasFlags(aContentLocation,
                   nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT) &&
         !HasFlags(aContentLocation,
                   nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS))) {
      *aDecision = nsIContentPolicy::REJECT_TYPE;

      // Report error, if we can.
      if (node) {
        nsIPrincipal* requestingPrincipal = node->NodePrincipal();
        nsRefPtr<nsIURI> principalURI;
        nsresult rv =
          requestingPrincipal->GetURI(getter_AddRefs(principalURI));
        if (NS_SUCCEEDED(rv) && principalURI) {
          nsScriptSecurityManager::ReportError(
            nullptr, NS_LITERAL_STRING("ExternalDataError"), principalURI,
            aContentLocation);
        }
      }
    } else if ((aContentType == nsIContentPolicy::TYPE_IMAGE ||
                aContentType == nsIContentPolicy::TYPE_IMAGESET) &&
               doc->GetDocumentURI()) {
      // Check for (& disallow) recursive image-loads
      bool isRecursiveLoad;
      nsresult rv = aContentLocation->EqualsExceptRef(doc->GetDocumentURI(),
                                                      &isRecursiveLoad);
      if (NS_FAILED(rv) || isRecursiveLoad) {
        NS_WARNING("Refusing to recursively load image");
        *aDecision = nsIContentPolicy::REJECT_TYPE;
      }
    }
    return NS_OK;
  }

  // Allow all loads for non-resource documents
  if (!doc->IsResourceDoc()) {
    return NS_OK;
  }

  // For resource documents, blacklist some load types
  if (aContentType == nsIContentPolicy::TYPE_OBJECT ||
      aContentType == nsIContentPolicy::TYPE_DOCUMENT ||
      aContentType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
      aContentType == nsIContentPolicy::TYPE_SCRIPT ||
      aContentType == nsIContentPolicy::TYPE_XSLT ||
      aContentType == nsIContentPolicy::TYPE_FETCH ||
      aContentType == nsIContentPolicy::TYPE_WEB_MANIFEST) {
    *aDecision = nsIContentPolicy::REJECT_TYPE;
  }

  // If you add more restrictions here, make sure to check that
  // CHECK_PRINCIPAL_AND_DATA in nsContentPolicyUtils is still valid.
  // nsContentPolicyUtils may not pass all the parameters to ShouldLoad

  return NS_OK;
}
Ejemplo n.º 24
0
/* static */ already_AddRefed<Image>
ImageFactory::CreateRasterImage(nsIRequest* aRequest,
                                ProgressTracker* aProgressTracker,
                                const nsCString& aMimeType,
                                ImageURL* aURI,
                                uint32_t aImageFlags,
                                uint32_t aInnerWindowId)
{
  MOZ_ASSERT(aProgressTracker);

  nsresult rv;

  RefPtr<RasterImage> newImage = new RasterImage(aURI);
  aProgressTracker->SetImage(newImage);
  newImage->SetProgressTracker(aProgressTracker);

  nsAutoCString ref;
  aURI->GetRef(ref);
  net::nsMediaFragmentURIParser parser(ref);
  if (parser.HasSampleSize()) {
      /* Get our principal */
      nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
      nsCOMPtr<nsIPrincipal> principal;
      if (chan) {
        nsContentUtils::GetSecurityManager()
          ->GetChannelResultPrincipal(chan, getter_AddRefs(principal));
      }

      if ((principal &&
           principal->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED) ||
          gfxPrefs::ImageMozSampleSizeEnabled()) {
        newImage->SetRequestedSampleSize(parser.GetSampleSize());
      }
  }

  rv = newImage->Init(aMimeType.get(), aImageFlags);
  if (NS_FAILED(rv)) {
    return BadImage("RasterImage::Init failed", newImage);
  }

  newImage->SetInnerWindowID(aInnerWindowId);

  uint32_t len = GetContentSize(aRequest);

  // Pass anything usable on so that the RasterImage can preallocate
  // its source buffer.
  if (len > 0) {
    // Bound by something reasonable
    uint32_t sizeHint = std::min<uint32_t>(len, 20000000);
    rv = newImage->SetSourceSizeHint(sizeHint);
    if (NS_FAILED(rv)) {
      // Flush memory, try to get some back, and try again.
      rv = nsMemory::HeapMinimize(true);
      nsresult rv2 = newImage->SetSourceSizeHint(sizeHint);
      // If we've still failed at this point, things are going downhill.
      if (NS_FAILED(rv) || NS_FAILED(rv2)) {
        NS_WARNING("About to hit OOM in imagelib!");
      }
    }
  }

  return newImage.forget();
}
Ejemplo n.º 25
0
bool
DataTransfer::ConvertFromVariant(nsIVariant* aVariant,
                                 nsISupports** aSupports,
                                 uint32_t* aLength) const
{
  *aSupports = nullptr;
  *aLength = 0;

  uint16_t type;
  aVariant->GetDataType(&type);
  if (type == nsIDataType::VTYPE_INTERFACE ||
      type == nsIDataType::VTYPE_INTERFACE_IS) {
    nsCOMPtr<nsISupports> data;
    if (NS_FAILED(aVariant->GetAsISupports(getter_AddRefs(data)))) {
      return false;
    }

    nsCOMPtr<nsIFlavorDataProvider> fdp = do_QueryInterface(data);
    if (fdp) {
      // for flavour data providers, use kFlavorHasDataProvider (which has the
      // value 0) as the length.
      fdp.forget(aSupports);
      *aLength = nsITransferable::kFlavorHasDataProvider;
    }
    else {
      // wrap the item in an nsISupportsInterfacePointer
      nsCOMPtr<nsISupportsInterfacePointer> ptrSupports =
        do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID);
      if (!ptrSupports) {
        return false;
      }

      ptrSupports->SetData(data);
      ptrSupports.forget(aSupports);

      *aLength = sizeof(nsISupportsInterfacePointer *);
    }

    return true;
  }

  nsAutoString str;
  nsresult rv = aVariant->GetAsAString(str);
  if (NS_FAILED(rv)) {
    return false;
  }

  nsCOMPtr<nsISupportsString>
    strSupports(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
  if (!strSupports) {
    return false;
  }

  strSupports->SetData(str);

  strSupports.forget(aSupports);

  // each character is two bytes
  *aLength = str.Length() * 2;

  return true;
}
Ejemplo n.º 26
0
void
set_a_IFoo( nsCOMPtr<IFoo>* result )
{
  nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
  *result = foop;
}
Ejemplo n.º 27
0
nsSVGAnimatedNumberList::~nsSVGAnimatedNumberList()
{
  nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
  if (val)
    val->RemoveObserver(this);
}
Ejemplo n.º 28
0
nsCOMPtr<IFoo>
return_a_IFoo()
{
  nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
  return foop;
}
Ejemplo n.º 29
0
NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(nsIDOMWindow *parent,
                                                  const char *dialogURL,
                                                  nsISupports *parameters, 
                                                  nsIObserver *openDialogObserver, 
                                                  bool *notifyOnOpen)
{
  *notifyOnOpen = true;
  m_observer = openDialogObserver;

  nsresult rv = NS_ERROR_FAILURE;
  
  if (m_dialog)
    return NS_ERROR_ALREADY_INITIALIZED;
  
  if (!dialogURL || !*dialogURL)
    return NS_ERROR_INVALID_ARG;

  if (parent)
  {
    // Set up window.arguments[0]...
    nsCOMPtr<nsISupportsArray> array;
    rv = NS_NewISupportsArray(getter_AddRefs(array));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsISupportsInterfacePointer> ifptr =
      do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
    
    ifptr->SetData(static_cast<nsIPrintProgress*>(this));
    ifptr->SetDataIID(&NS_GET_IID(nsIPrintProgress));

    array->AppendElement(ifptr);

    array->AppendElement(parameters);

    // We will set the opener of the dialog to be the nsIDOMWindow for the
    // browser XUL window itself, as opposed to the content. That way, the
    // progress window has access to the opener.
    nsCOMPtr<nsPIDOMWindow> pParentWindow = do_QueryInterface(parent);
    NS_ENSURE_STATE(pParentWindow);

    nsCOMPtr<nsIDocShell> docShell = pParentWindow->GetDocShell();
    NS_ENSURE_STATE(docShell);

    nsCOMPtr<nsIDocShellTreeOwner> owner;
    docShell->GetTreeOwner(getter_AddRefs(owner));

    nsCOMPtr<nsIXULWindow> ownerXULWindow = do_GetInterface(owner);
    nsCOMPtr<nsIDOMWindow> ownerWindow = do_GetInterface(ownerXULWindow);
    NS_ENSURE_STATE(ownerWindow);

    // Open the dialog.
    nsCOMPtr<nsIDOMWindow> newWindow;
    rv = ownerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
                                 NS_LITERAL_STRING("_blank"),
                                 NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
                                 array, getter_AddRefs(newWindow));
  }

  return rv;
}
void
EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
                                          WidgetEvent* aEvent,
                                          nsIDOMEvent** aDOMEvent,
                                          EventTarget* aCurrentTarget,
                                          nsEventStatus* aEventStatus)
{
  //Set the value of the internal PreventDefault flag properly based on aEventStatus
  if (*aEventStatus == nsEventStatus_eConsumeNoDefault) {
    aEvent->mFlags.mDefaultPrevented = true;
  }

  nsAutoTObserverArray<Listener, 2>::EndLimitedIterator iter(mListeners);
  Maybe<nsAutoPopupStatePusher> popupStatePusher;
  if (mIsMainThreadELM) {
    popupStatePusher.emplace(Event::GetEventPopupControlState(aEvent, *aDOMEvent));
  }

  bool hasListener = false;
  while (iter.HasMore()) {
    if (aEvent->mFlags.mImmediatePropagationStopped) {
      break;
    }
    Listener* listener = &iter.GetNext();
    // Check that the phase is same in event and event listener.
    // Handle only trusted events, except when listener permits untrusted events.
    if (ListenerCanHandle(listener, aEvent)) {
      hasListener = true;
      if (listener->IsListening(aEvent) &&
          (aEvent->mFlags.mIsTrusted ||
           listener->mFlags.mAllowUntrustedEvents)) {
        if (!*aDOMEvent) {
          // This is tiny bit slow, but happens only once per event.
          nsCOMPtr<EventTarget> et =
            do_QueryInterface(aEvent->originalTarget);
          EventDispatcher::CreateEvent(et, aPresContext,
                                       aEvent, EmptyString(), aDOMEvent);
        }
        if (*aDOMEvent) {
          if (!aEvent->currentTarget) {
            aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
            if (!aEvent->currentTarget) {
              break;
            }
          }

          // Maybe add a marker to the docshell's timeline, but only
          // bother with all the logic if some docshell is recording.
          nsCOMPtr<nsIDocShell> docShell;
          bool isTimelineRecording = false;
          if (mIsMainThreadELM &&
              nsDocShell::gProfileTimelineRecordingsCount > 0 &&
              listener->mListenerType != Listener::eNativeListener) {
            docShell = GetDocShellForTarget();
            if (docShell) {
              docShell->GetRecordProfileTimelineMarkers(&isTimelineRecording);
            }
            if (isTimelineRecording) {
              nsDocShell* ds = static_cast<nsDocShell*>(docShell.get());
              nsAutoString typeStr;
              (*aDOMEvent)->GetType(typeStr);
              uint16_t phase;
              (*aDOMEvent)->GetEventPhase(&phase);
              mozilla::UniquePtr<TimelineMarker> marker =
                MakeUnique<EventTimelineMarker>(ds, TRACING_INTERVAL_START,
                                                phase, typeStr);
              ds->AddProfileTimelineMarker(marker);
            }
          }

          if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent,
                                           aCurrentTarget))) {
            aEvent->mFlags.mExceptionHasBeenRisen = true;
          }

          if (isTimelineRecording) {
            nsDocShell* ds = static_cast<nsDocShell*>(docShell.get());
            ds->AddProfileTimelineMarker("DOMEvent", TRACING_INTERVAL_END);
          }
        }
      }
    }
  }

  aEvent->currentTarget = nullptr;

  if (mIsMainThreadELM && !hasListener) {
    mNoListenerForEvent = aEvent->message;
    mNoListenerForEventAtom = aEvent->userType;
  }

  if (aEvent->mFlags.mDefaultPrevented) {
    *aEventStatus = nsEventStatus_eConsumeNoDefault;
  }
}