nsresult
nsAbLDAPAutoCompFormatter::AppendFirstAttrValue(
    const nsACString &aAttrName, // attr to get
    nsILDAPMessage *aMessage, // msg to get values from
    bool aAttrRequired, // is this a required value?
    nsACString &aValue)
{
    // get the attribute values for the field which will be used 
    // to fill in nsIAutoCompleteItem::value
    //
    PRUint32 numVals;
    PRUnichar **values;

    nsresult rv;
    rv = aMessage->GetValues(nsCString(aAttrName).get(), &numVals, 
                             &values);
    if (NS_FAILED(rv)) {

        switch (rv) {
        case NS_ERROR_LDAP_DECODING_ERROR:
            // this may not be an error, per se; it could just be that the 
            // requested attribute does not exist in this particular message,
            // either because we didn't request it with the search operation,
            // or because it doesn't exist on the server.
            //
            break;

        case NS_ERROR_OUT_OF_MEMORY:
        case NS_ERROR_UNEXPECTED:
            break;

        default:
            NS_ERROR("nsLDAPAutoCompleteSession::OnLDAPSearchEntry(): "
                     "unexpected return code from aMessage->getValues()");
            rv = NS_ERROR_UNEXPECTED;
            break;
        }

        // if this was a required attribute, don't append anything to aValue
        // and return the error code
        //
        if (aAttrRequired) {
            return rv;
        } else {
            // otherwise forget about this attribute, but return NS_OK, which
            // will cause our caller to continue processing nameFormat in 
            // order to generate an nsIAutoCompleteItem.
            //
            return NS_OK;
        }
    }

    // append the value to our string; then free the array of results
    //
    aValue.Append(NS_ConvertUTF16toUTF8(values[0]));
    NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(numVals, values);

    // if this attribute wasn't required, we fall through to here, and return 
    // ok
    //
    return NS_OK;
}
示例#2
0
int main(int argc, char *argv[])
{
  pargc = &argc;
  pargv = &argv;

  // Get current executable path
  char curExePath[MAXPATHLEN];
  if (NS_FAILED(mozilla::BinaryPath::Get(argv[0], curExePath))) {
    ErrorDialog("Couldn't read current executable path");
    return 255;
  }
  char curExeDir[MAXPATHLEN];
  GetDirFromPath(curExeDir, curExePath);

  bool removeApp = false;
  for (int i = 1; i < argc; i++) {
    if (!strcmp(argv[i], "-profile")) {
      isProfileOverridden = true;
    }
    else if (!strcmp(argv[i], "-remove")) {
      removeApp = true;
    }
  }

  char firefoxDir[MAXPATHLEN];

  // Check if Firefox is in the same directory as the webapp runtime.
  // This is the case for webapprt chrome and content tests.
  if (GRELoadAndLaunch(curExeDir, true)) {
    return 0;
  }

  // Set up webAppIniPath with path to webapp.ini
  char webAppIniPath[MAXPATHLEN];
  snprintf(webAppIniPath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_INI);

  // Open webapp.ini as an INI file
  nsINIParser parser;
  if (NS_FAILED(parser.Init(webAppIniPath))) {
    ErrorDialog("Couldn't open webapp.ini");
    return 255;
  }

  // Set up our environment to know where webapp.ini was loaded from
  if (setenv(kAPP_ENV_VAR, webAppIniPath, 1) == -1) {
    ErrorDialog("Couldn't set up app environment");
    return 255;
  }

  // Get profile dir from webapp.ini
  if (NS_FAILED(parser.GetString("Webapp", "Profile", profile, MAXPATHLEN))) {
    ErrorDialog("Couldn't retrieve profile from web app INI file");
    return 255;
  }

  if (removeApp) {
    RemoveApplication(parser, curExeDir, profile);
    return 0;
  }

  // Get the location of Firefox from our webapp.ini
  if (NS_FAILED(parser.GetString("WebappRT", "InstallDir", firefoxDir, MAXPATHLEN))) {
    ErrorDialog("Couldn't find your Firefox install directory.");
    return 255;
  }

  // Set up appIniPath with path to application.ini.
  // This is in the Firefox installation directory.
  char appIniPath[MAXPATHLEN];
  snprintf(appIniPath, MAXPATHLEN, "%s/%s", firefoxDir, kAPP_INI);

  if (NS_FAILED(parser.Init(appIniPath))) {
    ErrorDialog("This app requires that Firefox version 16 or above is installed."
                " Firefox 16+ has not been detected.");
    return 255;
  }

  // Get buildid of Firefox we're trying to load (MAXPATHLEN only for convenience)
  char buildid[MAXPATHLEN];
  if (NS_FAILED(parser.GetString("App", "BuildID", buildid, MAXPATHLEN))) {
    ErrorDialog("Couldn't read BuildID from Firefox application.ini");
    return 255;
  }

  // If WebAppRT version == Firefox version, load XUL and execute the application
  if (!strcmp(buildid, NS_STRINGIFY(GRE_BUILDID))) {
    if (GRELoadAndLaunch(firefoxDir, false))
      return 0;
  }
  // Else, copy WebAppRT from Firefox installation and re-execute the process
  else
    CopyAndRelaunch(firefoxDir, curExePath);

  return 255;
}
示例#3
0
RefPtr<MediaDataDecoder::DecodePromise>
H264Converter::Decode(MediaRawData* aSample)
{
  MOZ_RELEASE_ASSERT(!mDecodePromiseRequest.Exists()
                     && !mInitPromiseRequest.Exists(),
                     "Can't request a new decode until previous one completed");

  if (!mp4_demuxer::AnnexB::ConvertSampleToAVCC(aSample)) {
    // We need AVCC content to be able to later parse the SPS.
    // This is a no-op if the data is already AVCC.
    return DecodePromise::CreateAndReject(
      MediaResult(NS_ERROR_OUT_OF_MEMORY, RESULT_DETAIL("ConvertSampleToAVCC")),
      __func__);
  }

  nsresult rv;
  if (!mDecoder) {
    // It is not possible to create an AVCC H264 decoder without SPS.
    // As such, creation will fail if the extra_data just extracted doesn't
    // contain a SPS.
    rv = CreateDecoderAndInit(aSample);
    if (rv == NS_ERROR_NOT_INITIALIZED) {
      // We are missing the required SPS to create the decoder.
      // Ignore for the time being, the MediaRawData will be dropped.
      return DecodePromise::CreateAndResolve(DecodedData(), __func__);
    }
  } else {
    rv = CheckForSPSChange(aSample);
  }

  if (rv == NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER) {
    // The decoder is pending initialization.
    RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
    return p;
  }

  if (NS_FAILED(rv)) {
    return DecodePromise::CreateAndReject(
      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                  RESULT_DETAIL("Unable to create H264 decoder")),
      __func__);
  }

  if (mNeedKeyframe && !aSample->mKeyframe) {
    return DecodePromise::CreateAndResolve(DecodedData(), __func__);
  }

  if (!mNeedAVCC) {
    mNeedAVCC =
      Some(mDecoder->NeedsConversion() == ConversionRequired::kNeedAVCC);
  }

  if (!*mNeedAVCC
      && !mp4_demuxer::AnnexB::ConvertSampleToAnnexB(aSample, mNeedKeyframe)) {
    return DecodePromise::CreateAndReject(
      MediaResult(NS_ERROR_OUT_OF_MEMORY,
                  RESULT_DETAIL("ConvertSampleToAnnexB")),
      __func__);
  }

  mNeedKeyframe = false;

  aSample->mExtraData = mCurrentConfig.mExtraData;

  return mDecoder->Decode(aSample);
}
/* 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;
}
示例#5
0
bool GRELoadAndLaunch(const char* firefoxDir, bool silentFail)
{
  char xpcomDllPath[MAXPATHLEN];
  snprintf(xpcomDllPath, MAXPATHLEN, "%s/%s", firefoxDir, XPCOM_DLL);

  if (silentFail && access(xpcomDllPath, F_OK) != 0)
    return false;

  if (NS_FAILED(XPCOMGlueStartup(xpcomDllPath))) {
    ErrorDialog("Couldn't load the XPCOM library");
    return false;
  }

  if (NS_FAILED(XPCOMGlueLoadXULFunctions(kXULFuncs))) {
    ErrorDialog("Couldn't load libxul");
    return false;
  }

  // NOTE: The GRE has successfully loaded, so we can use XPCOM now
  { // Scope for any XPCOM stuff we create
    ScopedLogging log;

    // Get the path to the runtime
    char rtPath[MAXPATHLEN];
    snprintf(rtPath, MAXPATHLEN, "%s/%s", firefoxDir, kWEBAPPRT_PATH);

    // Get the path to the runtime's INI file
    char rtIniPath[MAXPATHLEN];
    snprintf(rtIniPath, MAXPATHLEN, "%s/%s", rtPath, kWEBAPPRT_INI);

    // Load the runtime's INI from its path
    nsCOMPtr<nsIFile> rtINI;
    if (NS_FAILED(XRE_GetFileFromPath(rtIniPath, getter_AddRefs(rtINI)))) {
      ErrorDialog("Couldn't load the runtime INI");
      return false;
    }

    bool exists;
    nsresult rv = rtINI->Exists(&exists);
    if (NS_FAILED(rv) || !exists) {
      ErrorDialog("The runtime INI doesn't exist");
      return false;
    }

    nsXREAppData *webShellAppData;
    if (NS_FAILED(XRE_CreateAppData(rtINI, &webShellAppData))) {
      ErrorDialog("Couldn't read WebappRT application.ini");
      return false;
    }

    if (!isProfileOverridden) {
      SetAllocatedString(webShellAppData->profile, profile);
      // nsXREAppData::name is used for the class name part of the WM_CLASS
      // property. Set it so that the DE can match our window to the correct
      // launcher.
      char programClass[MAXPATHLEN];
      snprintf(programClass, MAXPATHLEN, "owa-%s", profile);
      SetAllocatedString(webShellAppData->name, programClass);
    }

    nsCOMPtr<nsIFile> directory;
    if (NS_FAILED(XRE_GetFileFromPath(rtPath, getter_AddRefs(directory)))) {
      ErrorDialog("Couldn't open runtime directory");
      return false;
    }

    nsCOMPtr<nsIFile> xreDir;
    if (NS_FAILED(XRE_GetFileFromPath(firefoxDir, getter_AddRefs(xreDir)))) {
      ErrorDialog("Couldn't open XRE directory");
      return false;
    }

    xreDir.forget(&webShellAppData->xreDirectory);
    NS_IF_RELEASE(webShellAppData->directory);
    directory.forget(&webShellAppData->directory);

    XRE_main(*pargc, *pargv, webShellAppData, 0);

    XRE_FreeAppData(webShellAppData);
  }

  return true;
}
示例#6
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;
}
示例#7
0
nsresult
ResetPermission(uint32_t aAppId, const nsAString& aOriginURL,
                const nsAString& aManifestURL,
                const nsAString& aPermission,
                bool aReadOnly)
{
  AssertIsInMainProcess();
  MOZ_ASSERT(NS_IsMainThread());

  nsresult rv;
  nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  nsCOMPtr<nsIURI> uri;
  rv = ioService->NewURI(NS_ConvertUTF16toUTF8(aOriginURL), nullptr, nullptr,
                         getter_AddRefs(uri));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
  if (!ssm) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIPrincipal> principal;
  rv = ssm->GetAppCodebasePrincipal(uri, aAppId, false,
                                    getter_AddRefs(principal));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  nsCOMPtr<nsIPermissionManager> pm =
    do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
  if (!pm) {
    return NS_ERROR_FAILURE;
  }

  nsCString basePermission;
  basePermission.Append(NS_ConvertUTF16toUTF8(aPermission));

  // Write permission
  {
    nsCString permission;
    permission.Append(basePermission);
    permission.AppendASCII("-write");

    uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
    rv = pm->TestExactPermissionFromPrincipal(principal, permission.get(),
                                              &perm);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }

    if (aReadOnly && perm == nsIPermissionManager::ALLOW_ACTION) {
      rv = pm->RemoveFromPrincipal(principal, permission.get());
    }
    else if (!aReadOnly && perm != nsIPermissionManager::ALLOW_ACTION) {
      rv = pm->AddFromPrincipal(principal, permission.get(),
                                nsIPermissionManager::ALLOW_ACTION,
                                nsIPermissionManager::EXPIRE_NEVER, 0);
    }

    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }

  // Read permission
  {
    nsCString permission;
    permission.Append(basePermission);
    permission.AppendASCII("-read");

    uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
    rv = pm->TestExactPermissionFromPrincipal(principal, permission.get(),
                                              &perm);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }

    if (perm != nsIPermissionManager::ALLOW_ACTION) {
      rv = pm->AddFromPrincipal(principal, permission.get(),
                                nsIPermissionManager::ALLOW_ACTION,
                                nsIPermissionManager::EXPIRE_NEVER, 0);
      if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
      }
    }
  }

  // Generic permission
  uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
  rv = pm->TestExactPermissionFromPrincipal(principal, basePermission.get(),
                                            &perm);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (perm != nsIPermissionManager::ALLOW_ACTION) {
    rv = pm->AddFromPrincipal(principal, basePermission.get(),
                              nsIPermissionManager::ALLOW_ACTION,
                              nsIPermissionManager::EXPIRE_NEVER, 0);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }

  return NS_OK;
}
示例#8
0
nsresult
SpdyConnectTransaction::ReadSegments(nsAHttpSegmentReader *reader,
                                     uint32_t count,
                                     uint32_t *countRead)
{
  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
  LOG(("SpdyConnectTransaction::ReadSegments %p count %d conn %p\n",
       this, count, mTunneledConn.get()));

  mSegmentReader = reader;

  // spdy stream carrying tunnel is not setup yet.
  if (!mTunneledConn) {
    uint32_t toWrite = mConnectString.Length() - mConnectStringOffset;
    toWrite = std::min(toWrite, count);
    *countRead = toWrite;
    if (toWrite) {
      nsresult rv = mSegmentReader->
        OnReadSegment(mConnectString.BeginReading() + mConnectStringOffset,
                      toWrite, countRead);
      if (NS_FAILED(rv) && (rv != NS_BASE_STREAM_WOULD_BLOCK)) {
        LOG(("SpdyConnectTransaction::ReadSegments %p OnReadSegmentError %x\n",
             this, rv));
        CreateShimError(rv);
      } else {
        mConnectStringOffset += toWrite;
        if (mConnectString.Length() == mConnectStringOffset) {
          mConnectString.Truncate();
          mConnectStringOffset = 0;
        }
      }
      return rv;
    }
    return NS_BASE_STREAM_WOULD_BLOCK;
  }

  if (mForcePlainText) {
    // this path just ignores sending the request so that we can
    // send a synthetic reply in writesegments()
    LOG(("SpdyConnectTransaciton::ReadSegments %p dropping %d output bytes "
         "due to synthetic reply\n", this, mOutputDataUsed - mOutputDataOffset));
    *countRead = mOutputDataUsed - mOutputDataOffset;
    mOutputDataOffset = mOutputDataUsed = 0;
    mTunneledConn->DontReuse();
    return NS_OK;
  }

  *countRead = 0;
  Flush(count, countRead);
  if (!mTunnelStreamOut->mCallback) {
    return NS_BASE_STREAM_WOULD_BLOCK;
  }

  nsresult rv =
    mTunnelStreamOut->mCallback->OnOutputStreamReady(mTunnelStreamOut);
  if (NS_FAILED(rv)) {
    return rv;
  }

  uint32_t subtotal;
  count -= *countRead;
  rv = Flush(count, &subtotal);
  *countRead += subtotal;
  return rv;
}
bool
nsXHTMLContentSerializer::SerializeAttributes(nsIContent* aContent,
        nsIContent *aOriginalElement,
        nsAString& aTagPrefix,
        const nsAString& aTagNamespaceURI,
        nsIAtom* aTagName,
        nsAString& aStr,
        uint32_t aSkipAttr,
        bool aAddNSAttr)
{
    nsresult rv;
    uint32_t index, count;
    nsAutoString prefixStr, uriStr, valueStr;
    nsAutoString xmlnsStr;
    xmlnsStr.AssignLiteral(kXMLNS);

    int32_t contentNamespaceID = aContent->GetNameSpaceID();

    // this method is not called by nsHTMLContentSerializer
    // so we don't have to check HTML element, just XHTML

    if (mIsCopying && kNameSpaceID_XHTML == contentNamespaceID) {

        // Need to keep track of OL and LI elements in order to get ordinal number
        // for the LI.
        if (aTagName == nsGkAtoms::ol) {
            // We are copying and current node is an OL;
            // Store its start attribute value in olState->startVal.
            nsAutoString start;
            int32_t startAttrVal = 0;
            aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::start, start);
            if (!start.IsEmpty()) {
                nsresult rv = NS_OK;
                startAttrVal = start.ToInteger(&rv);
                //If OL has "start" attribute, first LI element has to start with that value
                //Therefore subtracting 1 as all the LI elements are incrementing it before using it;
                //In failure of ToInteger(), default StartAttrValue to 0.
                if (NS_SUCCEEDED(rv))
                    --startAttrVal;
                else
                    startAttrVal = 0;
            }
            olState state (startAttrVal, true);
            mOLStateStack.AppendElement(state);
        }
        else if (aTagName == nsGkAtoms::li) {
            mIsFirstChildOfOL = IsFirstChildOfOL(aOriginalElement);
            if (mIsFirstChildOfOL) {
                // If OL is parent of this LI, serialize attributes in different manner.
                NS_ENSURE_TRUE(SerializeLIValueAttribute(aContent, aStr), false);
            }
        }
    }

    // If we had to add a new namespace declaration, serialize
    // and push it on the namespace stack
    if (aAddNSAttr) {
        if (aTagPrefix.IsEmpty()) {
            // Serialize default namespace decl
            NS_ENSURE_TRUE(SerializeAttr(EmptyString(), xmlnsStr,
                                         aTagNamespaceURI,
                                         aStr, true), false);
        } else {
            // Serialize namespace decl
            NS_ENSURE_TRUE(SerializeAttr(xmlnsStr, aTagPrefix,
                                         aTagNamespaceURI,
                                         aStr, true), false);
        }
        PushNameSpaceDecl(aTagPrefix, aTagNamespaceURI, aOriginalElement);
    }

    NS_NAMED_LITERAL_STRING(_mozStr, "_moz");

    count = aContent->GetAttrCount();

    // Now serialize each of the attributes
    // XXX Unfortunately we need a namespace manager to get
    // attribute URIs.
    for (index = 0; index < count; index++) {

        if (aSkipAttr == index) {
            continue;
        }

        const nsAttrName* name = aContent->GetAttrNameAt(index);
        int32_t namespaceID = name->NamespaceID();
        nsIAtom* attrName = name->LocalName();
        nsIAtom* attrPrefix = name->GetPrefix();

        // Filter out any attribute starting with [-|_]moz
        nsDependentAtomString attrNameStr(attrName);
        if (StringBeginsWith(attrNameStr, NS_LITERAL_STRING("_moz")) ||
                StringBeginsWith(attrNameStr, NS_LITERAL_STRING("-moz"))) {
            continue;
        }

        if (attrPrefix) {
            attrPrefix->ToString(prefixStr);
        }
        else {
            prefixStr.Truncate();
        }

        bool addNSAttr = false;
        if (kNameSpaceID_XMLNS != namespaceID) {
            nsContentUtils::NameSpaceManager()->GetNameSpaceURI(namespaceID, uriStr);
            addNSAttr = ConfirmPrefix(prefixStr, uriStr, aOriginalElement, true);
        }

        aContent->GetAttr(namespaceID, attrName, valueStr);

        nsDependentAtomString nameStr(attrName);
        bool isJS = false;

        if (kNameSpaceID_XHTML == contentNamespaceID) {
            //
            // Filter out special case of <br type="_moz"> or <br _moz*>,
            // used by the editor.  Bug 16988.  Yuck.
            //
            if (namespaceID == kNameSpaceID_None && aTagName == nsGkAtoms::br && attrName == nsGkAtoms::type
                    && StringBeginsWith(valueStr, _mozStr)) {
                continue;
            }

            if (mIsCopying && mIsFirstChildOfOL && (aTagName == nsGkAtoms::li)
                    && (attrName == nsGkAtoms::value)) {
                // This is handled separately in SerializeLIValueAttribute()
                continue;
            }

            isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);

            if (namespaceID == kNameSpaceID_None &&
                    ((attrName == nsGkAtoms::href) ||
                     (attrName == nsGkAtoms::src))) {
                // Make all links absolute when converting only the selection:
                if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
                    // Would be nice to handle OBJECT and APPLET tags,
                    // but that gets more complicated since we have to
                    // search the tag list for CODEBASE as well.
                    // For now, just leave them relative.
                    nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
                    if (uri) {
                        nsAutoString absURI;
                        rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
                        if (NS_SUCCEEDED(rv)) {
                            valueStr = absURI;
                        }
                    }
                }
                // Need to escape URI.
                nsAutoString tempURI(valueStr);
                if (!isJS && NS_FAILED(EscapeURI(aContent, tempURI, valueStr)))
                    valueStr = tempURI;
            }

            if (mRewriteEncodingDeclaration && aTagName == nsGkAtoms::meta &&
                    attrName == nsGkAtoms::content) {
                // If we're serializing a <meta http-equiv="content-type">,
                // use the proper value, rather than what's in the document.
                nsAutoString header;
                aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
                if (header.LowerCaseEqualsLiteral("content-type")) {
                    valueStr = NS_LITERAL_STRING("text/html; charset=") +
                               NS_ConvertASCIItoUTF16(mCharset);
                }
            }

            // Expand shorthand attribute.
            if (namespaceID == kNameSpaceID_None && IsShorthandAttr(attrName, aTagName) && valueStr.IsEmpty()) {
                valueStr = nameStr;
            }
        }
        else {
            isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
        }

        NS_ENSURE_TRUE(SerializeAttr(prefixStr, nameStr, valueStr, aStr, !isJS), false);

        if (addNSAttr) {
            NS_ASSERTION(!prefixStr.IsEmpty(),
                         "Namespaced attributes must have a prefix");
            NS_ENSURE_TRUE(SerializeAttr(xmlnsStr, prefixStr, uriStr, aStr, true), false);
            PushNameSpaceDecl(prefixStr, uriStr, aOriginalElement);
        }
    }

    return true;
}
示例#10
0
uint32_t
TrackRunBox::fillSampleTable()
{
  uint32_t table_size = 0;
  nsresult rv;
  nsTArray<RefPtr<EncodedFrame>> frames;
  FragmentBuffer* frag = mControl->GetFragment(mTrackType);

  rv = frag->GetFirstFragment(frames);
  if (NS_FAILED(rv)) {
    return 0;
  }
  uint32_t len = frames.Length();
  sample_info_table = MakeUnique<tbl[]>(len);
  // Create sample table according to 14496-12 8.8.8.2.
  for (uint32_t i = 0; i < len; i++) {
    // Sample size.
    sample_info_table[i].sample_size = 0;
    if (flags.to_ulong() & flags_sample_size_present) {
      sample_info_table[i].sample_size = frames.ElementAt(i)->GetFrameData().Length();
      mAllSampleSize += sample_info_table[i].sample_size;
      table_size += sizeof(uint32_t);
    }

    // Sample flags.
    sample_info_table[i].sample_flags = 0;
    if (flags.to_ulong() & flags_sample_flags_present) {
      sample_info_table[i].sample_flags =
        set_sample_flags(
          (frames.ElementAt(i)->GetFrameType() == EncodedFrame::AVC_I_FRAME));
      table_size += sizeof(uint32_t);
    }

    // Sample duration.
    sample_info_table[i].sample_duration = 0;
    if (flags.to_ulong() & flags_sample_duration_present) {
      // Calculate each frame's duration, it is decided by "current frame
      // timestamp - last frame timestamp".
      uint64_t frame_time = 0;
      if (i == 0) {
        frame_time = frames.ElementAt(i)->GetTimeStamp() -
                     frag->GetLastFragmentLastFrameTime();
      } else {
        frame_time = frames.ElementAt(i)->GetTimeStamp() -
                     frames.ElementAt(i - 1)->GetTimeStamp();
        // Keep the last frame time of current fagment, it will be used to calculate
        // the first frame duration of next fragment.
        if ((len - 1) == i) {
          frag->SetLastFragmentLastFrameTime(frames.ElementAt(i)->GetTimeStamp());
        }
      }

      // In TrackRunBox, there should be exactly one type, either audio or video.
      MOZ_ASSERT((mTrackType & Video_Track) ^ (mTrackType & Audio_Track));
      sample_info_table[i].sample_duration = (mTrackType & Video_Track ?
        frame_time * mVideoMeta->GetVideoClockRate() / USECS_PER_S :
        frame_time * mAudioMeta->GetAudioSampleRate() / USECS_PER_S);

      table_size += sizeof(uint32_t);
    }

    sample_info_table[i].sample_composition_time_offset = 0;
  }
  return table_size;
}
示例#11
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;
}
bool
TextEventDispatcher::DispatchKeyboardEventInternal(
                       EventMessage aMessage,
                       const WidgetKeyboardEvent& aKeyboardEvent,
                       nsEventStatus& aStatus,
                       DispatchTo aDispatchTo,
                       uint32_t aIndexOfKeypress)
{
  MOZ_ASSERT(aMessage == eKeyDown || aMessage == eKeyUp ||
             aMessage == eKeyPress, "Invalid aMessage value");
  nsresult rv = GetState();
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return false;
  }

  // If the key shouldn't cause keypress events, don't this patch them.
  if (aMessage == eKeyPress && !aKeyboardEvent.ShouldCauseKeypressEvents()) {
    return false;
  }

  // Basically, key events shouldn't be dispatched during composition.
  if (IsComposing()) {
    // However, if we need to behave like other browsers, we need the keydown
    // and keyup events.  Note that this behavior is also allowed by D3E spec.
    // FYI: keypress events must not be fired during composition.
    if (!sDispatchKeyEventsDuringComposition || aMessage == eKeyPress) {
      return false;
    }
    // XXX If there was mOnlyContentDispatch for this case, it might be useful
    //     because our chrome doesn't assume that key events are fired during
    //     composition.
  }

  WidgetKeyboardEvent keyEvent(true, aMessage, mWidget);
  InitEvent(keyEvent);
  keyEvent.AssignKeyEventData(aKeyboardEvent, false);

  if (aStatus == nsEventStatus_eConsumeNoDefault) {
    // If the key event should be dispatched as consumed event, marking it here.
    // This is useful to prevent double action.  E.g., when the key was already
    // handled by system, our chrome shouldn't handle it.
    keyEvent.mFlags.mDefaultPrevented = true;
  }

  // Corrects each member for the specific key event type.
  if (aMessage == eKeyDown || aMessage == eKeyUp) {
    MOZ_ASSERT(!aIndexOfKeypress,
      "aIndexOfKeypress must be 0 for either eKeyDown or eKeyUp");
    // charCode of keydown and keyup should be 0.
    keyEvent.charCode = 0;
  } else if (keyEvent.mKeyNameIndex != KEY_NAME_INDEX_USE_STRING) {
    MOZ_ASSERT(!aIndexOfKeypress,
      "aIndexOfKeypress must be 0 for eKeyPress of non-printable key");
    // If keypress event isn't caused by printable key, its charCode should
    // be 0.
    keyEvent.charCode = 0;
  } else {
    MOZ_RELEASE_ASSERT(
      !aIndexOfKeypress || aIndexOfKeypress < keyEvent.mKeyValue.Length(),
      "aIndexOfKeypress must be 0 - mKeyValue.Length() - 1");
    keyEvent.keyCode = 0;
    wchar_t ch =
      keyEvent.mKeyValue.IsEmpty() ? 0 : keyEvent.mKeyValue[aIndexOfKeypress];
    keyEvent.charCode = static_cast<uint32_t>(ch);
    if (ch) {
      keyEvent.mKeyValue.Assign(ch);
    } else {
      keyEvent.mKeyValue.Truncate();
    }
  }
  if (aMessage == eKeyUp) {
    // mIsRepeat of keyup event must be false.
    keyEvent.mIsRepeat = false;
  }
  // mIsComposing should be initialized later.
  keyEvent.mIsComposing = false;
  // XXX Currently, we don't support to dispatch key event with native key
  //     event information.
  keyEvent.mNativeKeyEvent = nullptr;
  // XXX Currently, we don't support to dispatch key events with data for
  // plugins.
  keyEvent.mPluginEvent.Clear();
  // TODO: Manage mUniqueId here.

  DispatchInputEvent(mWidget, keyEvent, aStatus, aDispatchTo);
  return true;
}
示例#13
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();
}
NS_IMETHODIMP
nsAbLDAPAutoCompFormatter::Format(nsILDAPMessage *aMsg, 
                                  nsIAutoCompleteItem **aItem) 
{
    nsresult rv;

    nsCOMPtr<nsIMsgHeaderParser> msgHdrParser = 
        do_GetService("@mozilla.org/messenger/headerparser;1", &rv);
    if (NS_FAILED(rv)) {
        NS_ERROR("nsAbLDAPAutoCompFormatter::Format(): do_GetService()"
                 " failed trying to obtain"
                 " '@mozilla.org/messenger/headerparser;1'");
        return NS_ERROR_NOT_AVAILABLE;
    }

    // generate the appropriate string
    //
    nsCAutoString name;
    rv = ProcessFormat(mNameFormat, aMsg, &name, 0);
    if (NS_FAILED(rv)) {
        // Something went wrong lower down the stack; a message should
        // have already been logged there.  Return an error, rather
        // than trying to generate a bogus nsIAutoCompleteItem
        //
        return rv;
    }

    nsCAutoString address;
    rv = ProcessFormat(mAddressFormat, aMsg, &address, 0);
    if (NS_FAILED(rv)) {
        // Something went wrong lower down the stack; a message should have 
        // already been logged there.  Return an error, rather than trying to 
        // generate a bogus nsIAutoCompleteItem.
        //
        return rv;
    }

    nsCString value;
    rv = msgHdrParser->MakeFullAddressString(name.get(), address.get(), 
                                             getter_Copies(value));
    if (NS_FAILED(rv)) {
        NS_ERROR("nsAbLDAPAutoCompFormatter::Format(): call to"
                 " MakeFullAddressString() failed");
        return rv;
    }

    // create an nsIAutoCompleteItem to hold the returned value
    //
    nsCOMPtr<nsIAutoCompleteItem> item = do_CreateInstance(
        NS_AUTOCOMPLETEITEM_CONTRACTID, &rv);

    if (NS_FAILED(rv)) {
        NS_ERROR("nsAbLDAPAutoCompFormatter::Format(): couldn't"
                 " create " NS_AUTOCOMPLETEITEM_CONTRACTID "\n");
        return NS_ERROR_NOT_AVAILABLE;
    }

    // this is that part that actually gets autocompleted to
    //
    rv = item->SetValue(NS_ConvertUTF8toUTF16(value));
    if (NS_FAILED(rv)) {
        NS_ERROR("nsAbLDAPAutoCompFormatter::Format(): "
                 "item->SetValue failed");
        return rv;
    }

    // generate the appropriate string to appear as a comment off to the side
    //
    nsCAutoString comment;
    rv = ProcessFormat(mCommentFormat, aMsg, &comment, 0);
    if (NS_SUCCEEDED(rv)) {
        rv = item->SetComment(NS_ConvertUTF8toUTF16(comment).get());
        if (NS_FAILED(rv)) {
            NS_WARNING("nsAbLDAPAutoCompFormatter::Format():"
                       " item->SetComment() failed");
        }
    }

    rv = item->SetClassName("remote-abook");
    if (NS_FAILED(rv)) {
        NS_WARNING("nsAbLDAPAutoCompleteFormatter::Format():"
                   " item->SetClassName() failed");
    }

    // all done; return the item
    NS_IF_ADDREF(*aItem = item);
    return NS_OK;
}
// 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;
}
nsresult
nsFileChannel::OpenContentStream(PRBool async, nsIInputStream **result,
                                 nsIChannel** channel)
{
  // NOTE: the resulting file is a clone, so it is safe to pass it to the
  //       file input stream which will be read on a background thread.
  nsCOMPtr<nsIFile> file;
  nsresult rv = GetFile(getter_AddRefs(file));
  if (NS_FAILED(rv))
    return rv;

  nsCOMPtr<nsIFileProtocolHandler> fileHandler;
  rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler));
  if (NS_FAILED(rv))
    return rv;
    
  nsCOMPtr<nsIURI> newURI;
  rv = fileHandler->ReadURLFile(file, getter_AddRefs(newURI));
  if (NS_SUCCEEDED(rv)) {
    nsCOMPtr<nsIChannel> newChannel;
    rv = NS_NewChannel(getter_AddRefs(newChannel), newURI);
    if (NS_FAILED(rv))
      return rv;

    *result = nsnull;
    newChannel.forget(channel);
    return NS_OK;
  }

  nsCOMPtr<nsIInputStream> stream;

  if (mUploadStream) {
    // Pass back a nsFileUploadContentStream instance that knows how to perform
    // the file copy when "read" (the resulting stream in this case does not
    // actually return any data).

    nsCOMPtr<nsIOutputStream> fileStream;
    rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileStream), file,
                                     PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                                     PR_IRUSR | PR_IWUSR);
    if (NS_FAILED(rv))
      return rv;

    nsFileUploadContentStream *uploadStream =
        new nsFileUploadContentStream(async, fileStream, mUploadStream,
                                      mUploadLength, this);
    if (!uploadStream || !uploadStream->IsInitialized()) {
      delete uploadStream;
      return NS_ERROR_OUT_OF_MEMORY;
    }
    stream = uploadStream;

    SetContentLength64(0);

    // Since there isn't any content to speak of we just set the content-type
    // to something other than "unknown" to avoid triggering the content-type
    // sniffer code in nsBaseChannel.
    // However, don't override explicitly set types.
    if (!HasContentTypeHint())
      SetContentType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
  } else {
    nsCAutoString contentType;
    nsresult rv = MakeFileInputStream(file, stream, contentType);
    if (NS_FAILED(rv))
      return rv;

    EnableSynthesizedProgressEvents(PR_TRUE);

    // fixup content length and type
    if (ContentLength64() < 0) {
      PRInt64 size;
      rv = file->GetFileSize(&size);
      if (NS_FAILED(rv))
        return rv;
      SetContentLength64(size);
    }
    if (!contentType.IsEmpty())
      SetContentType(contentType);
  }

  *result = nsnull;
  stream.swap(*result);
  return 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
 // Call this method to interrupt a file copy operation that is occuring on
 // a background thread.  The status parameter passed to this function must
 // be a failure code and is set as the status of this file copy operation.
 void Interrupt(nsresult status) {
   NS_ASSERTION(NS_FAILED(status), "must be a failure code");
   mInterruptStatus = status;
 }
示例#19
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;
}
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;
}
nsresult InputStreamShim::doReadFromJava()
{
    nsresult rv = NS_ERROR_FAILURE;
    PR_ASSERT(mLock);

    PR_LOG(prLogModuleInfo, PR_LOG_DEBUG, 
           ("InputStreamShim::doReadFromJava: entering\n"));

    PR_Lock(mLock);

    // first, see how much data is available
    if (NS_FAILED(rv = doAvailable())) {
        goto DRFJ_CLEANUP;
    }

    // if we have all our data, give the error appropriate result
    if (mAvailable <= 0 ||
        (0 != mCountFromJava && 
         (((PRUint32)mContentLength) == mCountFromJava))) {
        mDoClose = PR_TRUE;
        rv = doClose();
        if (0 == mAvailableForMozilla) {
            rv = NS_ERROR_NOT_AVAILABLE;
        }
        goto DRFJ_CLEANUP;
    }
    
    if (NS_FAILED(doRead())) {
        rv = NS_ERROR_FAILURE;
        goto DRFJ_CLEANUP;
    }
    rv = NS_OK;

    // if we have bytes available for mozilla, and they it has requested
    // a callback when bytes are available.
    if (mCallback && 0 < mAvailableForMozilla 
        && !(mCallbackFlags & WAIT_CLOSURE_ONLY)) {
        rv = mCallback->OnInputStreamReady(this);
        mCallback = nsnull;
        mCallbackFlags = nsnull;
        if (NS_FAILED(rv)) {
            goto DRFJ_CLEANUP;
        }
    }

    // finally, do another check for available bytes
    if (NS_FAILED(doAvailable())) {
        rv = NS_ERROR_FAILURE;
        goto DRFJ_CLEANUP;
    }
    if (mAvailable <= 0 ||
        (0 != mCountFromJava && 
         (((PRUint32)mContentLength) == mCountFromJava))) {
        mDoClose = PR_TRUE;
        rv = doClose();
        if (0 == mAvailableForMozilla) {
            rv = NS_ERROR_NOT_AVAILABLE;
        }

        goto DRFJ_CLEANUP;
    }

 DRFJ_CLEANUP:
    
    PR_Unlock(mLock);

    PR_LOG(prLogModuleInfo, PR_LOG_DEBUG, 
           ("InputStreamShim::doReadFromJava: exiting\n"));
    return rv;
}
NS_IMETHODIMP nsMsgGroupView::CellTextForColumn(int32_t aRow,
                                                const char16_t *aColumnName,
                                                nsAString &aValue) {
  if (!IsValidIndex(aRow))
    return NS_MSG_INVALID_DBVIEW_INDEX;

  if (m_flags[aRow] & MSG_VIEW_FLAG_DUMMY && aColumnName[0] != 'u')
  {
    nsCOMPtr <nsIMsgDBHdr> msgHdr;
    nsresult rv = GetMsgHdrForViewIndex(aRow, getter_AddRefs(msgHdr));
    NS_ENSURE_SUCCESS(rv, rv);
    nsString hashKey;
    rv = HashHdr(msgHdr, hashKey);
    if (NS_FAILED(rv))
      return NS_OK;
    nsCOMPtr<nsIMsgThread> msgThread;
    m_groupsTable.Get(hashKey, getter_AddRefs(msgThread));
    nsMsgGroupThread * groupThread = static_cast<nsMsgGroupThread *>(msgThread.get());
    if (aColumnName[0] == 's'  && aColumnName[1] == 'u' )
    {
      uint32_t flags;
      bool rcvDate = false;
      msgHdr->GetFlags(&flags);
      aValue.Truncate();
      nsString tmp_str;
      switch (m_sortType)
      {
        case nsMsgViewSortType::byReceived:
          rcvDate = true;
        case nsMsgViewSortType::byDate:
        {
          uint32_t ageBucket = 0;
          GetAgeBucketValue(msgHdr, &ageBucket, rcvDate);
          switch (ageBucket)
          {
          case 1:
            if (m_kTodayString.IsEmpty())
              m_kTodayString.Adopt(GetString(u"today"));
            aValue.Assign(m_kTodayString);
            break;
          case 2:
            if (m_kYesterdayString.IsEmpty())
              m_kYesterdayString.Adopt(GetString(u"yesterday"));
            aValue.Assign(m_kYesterdayString);
            break;
          case 3:
            if (m_kLastWeekString.IsEmpty())
              m_kLastWeekString.Adopt(GetString(u"lastWeek"));
            aValue.Assign(m_kLastWeekString);
            break;
          case 4:
            if (m_kTwoWeeksAgoString.IsEmpty())
              m_kTwoWeeksAgoString.Adopt(GetString(u"twoWeeksAgo"));
            aValue.Assign(m_kTwoWeeksAgoString);
            break;
          case 5:
            if (m_kOldMailString.IsEmpty())
              m_kOldMailString.Adopt(GetString(u"older"));
            aValue.Assign(m_kOldMailString);
            break;
          default:
            // Future date, error/spoofed.
            if (m_kFutureDateString.IsEmpty())
              m_kFutureDateString.Adopt(GetString(u"futureDate"));
            aValue.Assign(m_kFutureDateString);
            break;
          }
          break;
        }
        case nsMsgViewSortType::bySubject:
          FetchSubject(msgHdr, m_flags[aRow], aValue);
          break;
        case nsMsgViewSortType::byAuthor:
          FetchAuthor(msgHdr, aValue);
          break;
        case nsMsgViewSortType::byStatus:
          rv = FetchStatus(m_flags[aRow], aValue);
          if (aValue.IsEmpty()) {
            tmp_str.Adopt(GetString(u"messagesWithNoStatus"));
            aValue.Assign(tmp_str);
          }
          break;
        case nsMsgViewSortType::byTags:
          rv = FetchTags(msgHdr, aValue);
          if (aValue.IsEmpty()) {
            tmp_str.Adopt(GetString(u"untaggedMessages"));
            aValue.Assign(tmp_str);
          }
          break;
        case nsMsgViewSortType::byPriority:
          FetchPriority(msgHdr, aValue);
          if (aValue.IsEmpty()) {
            tmp_str.Adopt(GetString(u"noPriority"));
            aValue.Assign(tmp_str);
          }
          break;
        case nsMsgViewSortType::byAccount:
          FetchAccount(msgHdr, aValue);
          break;
        case nsMsgViewSortType::byRecipient:
          FetchRecipients(msgHdr, aValue);
          break;
        case nsMsgViewSortType::byAttachments:
          tmp_str.Adopt(GetString(flags & nsMsgMessageFlags::Attachment ?
            u"attachments" : u"noAttachments"));
          aValue.Assign(tmp_str);
          break;
        case nsMsgViewSortType::byFlagged:
          tmp_str.Adopt(GetString(flags & nsMsgMessageFlags::Marked ?
            u"groupFlagged" : u"notFlagged"));
          aValue.Assign(tmp_str);
          break;
        // byLocation is a special case; we don't want to have duplicate
        //  all this logic in nsMsgSearchDBView, and its hash key is what we
        //  want anyways, so just copy it across.
        case nsMsgViewSortType::byLocation:
        case nsMsgViewSortType::byCorrespondent:
          aValue = hashKey;
          break;
        case nsMsgViewSortType::byCustom:
        {
          nsIMsgCustomColumnHandler* colHandler = GetCurColumnHandler();
          if (colHandler)
          {
            bool isString;
            colHandler->IsString(&isString);
            if (isString)
              rv = colHandler->GetSortStringForRow(msgHdr.get(), aValue);
            else
            {
              uint32_t intKey;
              rv = colHandler->GetSortLongForRow(msgHdr.get(), &intKey);
              aValue.AppendInt(intKey);
            }
          }
          if (aValue.IsEmpty())
            aValue.AssignLiteral("*");
          break;
        }

        default:
          NS_ASSERTION(false, "we don't sort by group for this type");
          break;
      }

      if (groupThread)
      {
        // Get number of messages in group
        nsAutoString formattedCountMsg;
        uint32_t numMsg = groupThread->NumRealChildren();
        formattedCountMsg.AppendInt(numMsg);

        // Get number of unread messages
        nsAutoString formattedCountUnrMsg;
        uint32_t numUnrMsg = 0;
        groupThread->GetNumUnreadChildren(&numUnrMsg);
        formattedCountUnrMsg.AppendInt(numUnrMsg);

        // Add text to header
        aValue.Append(NS_LITERAL_STRING(" ("));
        if (numUnrMsg)
        {
          aValue.Append(formattedCountUnrMsg);
          aValue.Append(NS_LITERAL_STRING("/"));
        }

        aValue.Append(formattedCountMsg);
        aValue.Append(NS_LITERAL_STRING(")"));
      }
    }
    else if (aColumnName[0] == 't' && aColumnName[1] == 'o')
    {
      nsAutoString formattedCountString;
      uint32_t numChildren = (groupThread) ? groupThread->NumRealChildren() : 0;
      formattedCountString.AppendInt(numChildren);
      aValue.Assign(formattedCountString);
    }
    return NS_OK;
  }
  return nsMsgDBView::CellTextForColumn(aRow, aColumnName, aValue);
}
// This is the function that looks for the first folder to purge. It also
// applies retention settings to any folder that hasn't had retention settings
// applied in mMinDelayBetweenPurges minutes (default, 8 hours).
// However, if we've spent more than .5 seconds in this loop, don't
// apply any more retention settings because it might lock up the UI.
// This might starve folders later on in the hierarchy, since we always
// start at the top, but since we also apply retention settings when you
// open a folder, or when you compact all folders, I think this will do
// for now, until we have a cleanup on shutdown architecture.
nsresult nsMsgPurgeService::PerformPurge()
{
  MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("performing purge"));

  nsresult rv;

  nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv,rv);
  bool keepApplyingRetentionSettings = true;

  nsCOMPtr<nsIArray> allServers;
  rv = accountManager->GetAllServers(getter_AddRefs(allServers));
  if (NS_SUCCEEDED(rv) && allServers)
  {
    uint32_t numServers;
    rv = allServers->GetLength(&numServers);
    MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("%d servers", numServers));
    nsCOMPtr<nsIMsgFolder> folderToPurge;
    PRIntervalTime startTime = PR_IntervalNow();
    int32_t purgeIntervalToUse = 0;
    PRTime oldestPurgeTime = 0; // we're going to pick the least-recently purged folder

    // apply retention settings to folders that haven't had retention settings
    // applied in mMinDelayBetweenPurges minutes (default 8 hours)
    // Because we get last purge time from the folder cache,
    // this code won't open db's for folders until it decides it needs
    // to apply retention settings, and since nsIMsgFolder::ApplyRetentionSettings
    // will close any db's it opens, this code won't leave db's open.
    for (uint32_t serverIndex=0; serverIndex < numServers; serverIndex++)
    {
      nsCOMPtr <nsIMsgIncomingServer> server =
        do_QueryElementAt(allServers, serverIndex, &rv);
      if (NS_SUCCEEDED(rv) && server)
      {
        if (keepApplyingRetentionSettings)
        {
          nsCOMPtr <nsIMsgFolder> rootFolder;
          rv = server->GetRootFolder(getter_AddRefs(rootFolder));
          NS_ENSURE_SUCCESS(rv, rv);

          nsCOMPtr<nsIArray> childFolders;
          rv = rootFolder->GetDescendants(getter_AddRefs(childFolders));
          NS_ENSURE_SUCCESS(rv, rv);

          uint32_t cnt = 0;
          childFolders->GetLength(&cnt);

          nsCOMPtr<nsISupports> supports;
          nsCOMPtr<nsIUrlListener> urlListener;
          nsCOMPtr<nsIMsgFolder> childFolder;

          for (uint32_t index = 0; index < cnt; index++)
          {
            childFolder = do_QueryElementAt(childFolders, index);
            if (childFolder)
            {
              uint32_t folderFlags;
              (void) childFolder->GetFlags(&folderFlags);
              if (folderFlags & nsMsgFolderFlags::Virtual)
                continue;
              PRTime curFolderLastPurgeTime = 0;
              nsCString curFolderLastPurgeTimeString, curFolderUri;
              rv = childFolder->GetStringProperty("LastPurgeTime", curFolderLastPurgeTimeString);
              if (NS_FAILED(rv))
                continue; // it is ok to fail, go on to next folder

              if (!curFolderLastPurgeTimeString.IsEmpty())
              {
                PRTime theTime;
                PR_ParseTimeString(curFolderLastPurgeTimeString.get(), false, &theTime);
                curFolderLastPurgeTime = theTime;
              }

              childFolder->GetURI(curFolderUri);
              MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("%s curFolderLastPurgeTime=%s (if blank, then never)", curFolderUri.get(), curFolderLastPurgeTimeString.get()));

              // check if this folder is due to purge
              // has to have been purged at least mMinDelayBetweenPurges minutes ago
              // we don't want to purge the folders all the time - once a day is good enough
              int64_t minDelayBetweenPurges(mMinDelayBetweenPurges);
              int64_t microSecondsPerMinute(60000000);
              PRTime nextPurgeTime = curFolderLastPurgeTime + (minDelayBetweenPurges * microSecondsPerMinute);
              if (nextPurgeTime < PR_Now())
              {
                MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("purging %s", curFolderUri.get()));
                childFolder->ApplyRetentionSettings();
              }
              PRIntervalTime elapsedTime = PR_IntervalNow() - startTime;
              // check if more than 500 milliseconds have elapsed in this purge process
              if (PR_IntervalToMilliseconds(elapsedTime) > 500)
              {
                keepApplyingRetentionSettings = false;
                break;
              }
            }
          }
        }
        nsCString type;
        nsresult rv = server->GetType(type);
        NS_ENSURE_SUCCESS(rv, rv);

        nsCString realHostName;
        server->GetRealHostName(realHostName);
        MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] %s (%s)", serverIndex, realHostName.get(), type.get()));

        nsCOMPtr <nsISpamSettings> spamSettings;
        rv = server->GetSpamSettings(getter_AddRefs(spamSettings));
        NS_ENSURE_SUCCESS(rv, rv);

        int32_t spamLevel;
        spamSettings->GetLevel(&spamLevel);
        MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] spamLevel=%d (if 0, don't purge)", serverIndex, spamLevel));
        if (!spamLevel)
          continue;

        // check if we are set up to purge for this server
        // if not, skip it.
        bool purgeSpam;
        spamSettings->GetPurge(&purgeSpam);

        MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] purgeSpam=%s (if false, don't purge)", serverIndex, purgeSpam ? "true" : "false"));
        if (!purgeSpam)
          continue;

        // check if the spam folder uri is set for this server
        // if not skip it.
        nsCString junkFolderURI;
        rv = spamSettings->GetSpamFolderURI(getter_Copies(junkFolderURI));
        NS_ENSURE_SUCCESS(rv,rv);

        MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] junkFolderURI=%s (if empty, don't purge)", serverIndex, junkFolderURI.get()));
        if (junkFolderURI.IsEmpty())
          continue;

        // if the junk folder doesn't exist
        // because the folder pane isn't built yet, for example
        // skip this account
        nsCOMPtr<nsIMsgFolder> junkFolder;
        rv = FindFolder(junkFolderURI, getter_AddRefs(junkFolder));
        NS_ENSURE_SUCCESS(rv, rv);

        MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] %s exists? %s (if doesn't exist, don't purge)", serverIndex, junkFolderURI.get(), junkFolder ? "true" : "false"));
        if (!junkFolder)
          continue;

        PRTime curJunkFolderLastPurgeTime = 0;
        nsCString curJunkFolderLastPurgeTimeString;
        rv = junkFolder->GetStringProperty("curJunkFolderLastPurgeTime", curJunkFolderLastPurgeTimeString);
        if (NS_FAILED(rv))
          continue; // it is ok to fail, junk folder may not exist

        if (!curJunkFolderLastPurgeTimeString.IsEmpty())
        {
          PRTime theTime;
          PR_ParseTimeString(curJunkFolderLastPurgeTimeString.get(), false, &theTime);
          curJunkFolderLastPurgeTime = theTime;
        }

        MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] %s curJunkFolderLastPurgeTime=%s (if blank, then never)", serverIndex, junkFolderURI.get(), curJunkFolderLastPurgeTimeString.get()));

        // check if this account is due to purge
        // has to have been purged at least mMinDelayBetweenPurges minutes ago
        // we don't want to purge the folders all the time
        PRTime nextPurgeTime = curJunkFolderLastPurgeTime + mMinDelayBetweenPurges * 60000000 /* convert mMinDelayBetweenPurges to into microseconds */;
        if (nextPurgeTime < PR_Now())
        {
          MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] last purge greater than min delay", serverIndex));

          nsCOMPtr <nsIMsgIncomingServer> junkFolderServer;
          rv = junkFolder->GetServer(getter_AddRefs(junkFolderServer));
          NS_ENSURE_SUCCESS(rv,rv);

          bool serverBusy = false;
          bool serverRequiresPassword = true;
          bool passwordPromptRequired;
          bool canSearchMessages = false;
          junkFolderServer->GetPasswordPromptRequired(&passwordPromptRequired);
          junkFolderServer->GetServerBusy(&serverBusy);
          junkFolderServer->GetServerRequiresPasswordForBiff(&serverRequiresPassword);
          junkFolderServer->GetCanSearchMessages(&canSearchMessages);
          // Make sure we're logged on before doing the search (assuming we need to be)
          // and make sure the server isn't already in the middle of downloading new messages
          // and make sure a search isn't already going on
          MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] (search in progress? %s)", serverIndex, mSearchSession ? "true" : "false"));
          MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] (server busy? %s)", serverIndex, serverBusy ? "true" : "false"));
          MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] (serverRequiresPassword? %s)", serverIndex, serverRequiresPassword ? "true" : "false"));
          MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] (passwordPromptRequired? %s)", serverIndex, passwordPromptRequired ? "true" : "false"));
          if (canSearchMessages && !mSearchSession && !serverBusy && (!serverRequiresPassword || !passwordPromptRequired))
          {
            int32_t purgeInterval;
            spamSettings->GetPurgeInterval(&purgeInterval);

            if ((oldestPurgeTime == 0) || (curJunkFolderLastPurgeTime < oldestPurgeTime))
            {
              MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] purging! searching for messages older than %d days", serverIndex, purgeInterval));
              oldestPurgeTime = curJunkFolderLastPurgeTime;
              purgeIntervalToUse = purgeInterval;
              folderToPurge = junkFolder;
              // if we've never purged this folder, do it...
              if (curJunkFolderLastPurgeTime == 0)
                break;
            }
          }
          else {
            NS_ASSERTION(canSearchMessages, "unexpected, you should be able to search");
            MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] not a good time for this server, try again later", serverIndex));
          }
        }
        else {
          MOZ_LOG(MsgPurgeLogModule, mozilla::LogLevel::Info, ("[%d] last purge too recent", serverIndex));
        }
      }
    }
    if (folderToPurge && purgeIntervalToUse != 0)
      rv = SearchFolderToPurge(folderToPurge, purgeIntervalToUse);
  }

  // set up timer to check accounts again
  SetupNextPurge();
  return rv;
}
nsresult
nsMsgSendLater::DeliverQueuedLine(char *line, int32_t length)
{
    int32_t flength = length;

    m_bytesRead += length;

// convert existing newline to CRLF
// Don't need this because the calling routine is taking care of it.
//  if (length > 0 && (line[length-1] == '\r' ||
//     (line[length-1] == '\n' && (length < 2 || line[length-2] != '\r'))))
//  {
//    line[length-1] = '\r';
//    line[length++] = '\n';
//  }
//
    //
    // We are going to check if we are looking at a "From - " line. If so,
    // then just eat it and return NS_OK
    //
    if (!PL_strncasecmp(line, "From - ", 7))
        return NS_OK;

    if (m_inhead)
    {
        if (m_headersPosition == 0)
        {
            // This line is the first line in a header block.
            // Remember its position.
            m_headersPosition = m_position;

            // Also, since we're now processing the headers, clear out the
            // slots which we will parse data into, so that the values that
            // were used the last time around do not persist.

            // We must do that here, and not in the previous clause of this
            // `else' (the "I've just seen a `From ' line clause") because
            // that clause happens before delivery of the previous message is
            // complete, whereas this clause happens after the previous msg
            // has been delivered.  If we did this up there, then only the
            // last message in the folder would ever be able to be both
            // mailed and posted (or fcc'ed.)
            PR_FREEIF(m_to);
            PR_FREEIF(m_bcc);
            PR_FREEIF(m_newsgroups);
            PR_FREEIF(m_newshost);
            PR_FREEIF(m_fcc);
            PR_FREEIF(mIdentityKey);
        }

        if (line[0] == '\r' || line[0] == '\n' || line[0] == 0)
        {
            // End of headers.  Now parse them; open the temp file;
            // and write the appropriate subset of the headers out.
            m_inhead = false;

            nsresult rv = MsgNewBufferedFileOutputStream(getter_AddRefs(mOutFile), mTempFile, -1, 00600);
            if (NS_FAILED(rv))
                return NS_MSG_ERROR_WRITING_FILE;

            nsresult status = BuildHeaders();
            if (NS_FAILED(status))
                return status;

            uint32_t n;
            rv = mOutFile->Write(m_headers, m_headersFP, &n);
            if (NS_FAILED(rv) || n != (uint32_t)m_headersFP)
                return NS_MSG_ERROR_WRITING_FILE;
        }
        else
        {
            // Otherwise, this line belongs to a header.  So append it to the
            // header data.

            if (!PL_strncasecmp (line, HEADER_X_MOZILLA_STATUS, PL_strlen(HEADER_X_MOZILLA_STATUS)))
                // Notice the position of the flags.
                m_flagsPosition = m_position;
            else if (m_headersFP == 0)
                m_flagsPosition = 0;

            nsresult status = do_grow_headers (length + m_headersFP + 10);
            if (NS_FAILED(status))
                return status;

            memcpy(m_headers + m_headersFP, line, length);
            m_headersFP += length;
        }
    }
    else
    {
        // This is a body line.  Write it to the file.
        PR_ASSERT(mOutFile);
        if (mOutFile)
        {
            uint32_t wrote;
            nsresult rv = mOutFile->Write(line, length, &wrote);
            if (NS_FAILED(rv) || wrote < (uint32_t) length)
                return NS_MSG_ERROR_WRITING_FILE;
        }
    }

    m_position += flength;
    return NS_OK;
}
示例#25
0
void RemoveApplication(nsINIParser& parser, const char* curExeDir, const char* profile)  {
  if (!isProfileOverridden) {
    // Remove the desktop entry file.
    char desktopEntryFilePath[MAXPATHLEN];

    char* dataDir = getenv("XDG_DATA_HOME");

    if (dataDir && *dataDir) {
      snprintf(desktopEntryFilePath, MAXPATHLEN, "%s/applications/owa-%s.desktop", dataDir, profile);
    } else {
      char* home = getenv("HOME");
      snprintf(desktopEntryFilePath, MAXPATHLEN, "%s/.local/share/applications/owa-%s.desktop", home, profile);
    }

    unlink(desktopEntryFilePath);
  }

  // Remove the files from the installation directory.
  char webAppIniPath[MAXPATHLEN];
  snprintf(webAppIniPath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_INI);
  unlink(webAppIniPath);

  char curExePath[MAXPATHLEN];
  snprintf(curExePath, MAXPATHLEN, "%s/%s", curExeDir, kAPP_RT);
  unlink(curExePath);

  char webAppJsonPath[MAXPATHLEN];
  snprintf(webAppJsonPath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_JSON);
  unlink(webAppJsonPath);

  char iconPath[MAXPATHLEN];
  snprintf(iconPath, MAXPATHLEN, "%s/icon.png", curExeDir);
  unlink(iconPath);

  char packagePath[MAXPATHLEN];
  snprintf(packagePath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_PACKAGE);
  unlink(packagePath);

  char appName[MAXPATHLEN];
  if (NS_FAILED(parser.GetString("Webapp", "Name", appName, MAXPATHLEN))) {
    strcpy(appName, profile);
  }

  char uninstallMsg[MAXPATHLEN];
  if (NS_SUCCEEDED(parser.GetString("Webapp", "UninstallMsg", uninstallMsg, MAXPATHLEN))) {
    /**
     * The only difference between libnotify.so.4 and libnotify.so.1 for these symbols
     * is that notify_notification_new takes three arguments in libnotify.so.4 and
     * four in libnotify.so.1.
     * Passing the fourth argument as nullptr is binary compatible.
     */
    typedef void  (*notify_init_t)(const char*);
    typedef void* (*notify_notification_new_t)(const char*, const char*, const char*, const char*);
    typedef void  (*notify_notification_show_t)(void*, void**);

    void *handle = dlopen("libnotify.so.4", RTLD_LAZY);
    if (!handle) {
      handle = dlopen("libnotify.so.1", RTLD_LAZY);
      if (!handle)
        return;
    }

    notify_init_t nn_init = (notify_init_t)(uintptr_t)dlsym(handle, "notify_init");
    notify_notification_new_t nn_new = (notify_notification_new_t)(uintptr_t)dlsym(handle, "notify_notification_new");
    notify_notification_show_t nn_show = (notify_notification_show_t)(uintptr_t)dlsym(handle, "notify_notification_show");
    if (!nn_init || !nn_new || !nn_show) {
      dlclose(handle);
      return;
    }

    nn_init(appName);

    void* n = nn_new(uninstallMsg, nullptr, "dialog-information", nullptr);

    nn_show(n, nullptr);

    dlclose(handle);
  }
}
nsresult
nsMsgSendLater::CompleteMailFileSend()
{
    // get the identity from the key
    // if no key, or we fail to find the identity
    // use the default identity on the default account
    nsCOMPtr<nsIMsgIdentity> identity;
    nsresult rv = GetIdentityFromKey(mIdentityKey, getter_AddRefs(identity));
    NS_ENSURE_SUCCESS(rv,rv);

    // If for some reason the tmp file didn't get created, we've failed here
    bool created;
    mTempFile->Exists(&created);
    if (!created)
        return NS_ERROR_FAILURE;

    // Get the recipients...
    nsCString recips;
    nsCString ccList;
    if (NS_FAILED(mMessage->GetRecipients(getter_Copies(recips))))
        return NS_ERROR_UNEXPECTED;
    else
        mMessage->GetCcList(getter_Copies(ccList));

    nsCOMPtr<nsIMsgCompFields> compFields = do_CreateInstance(NS_MSGCOMPFIELDS_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv,rv);

    nsCOMPtr<nsIMsgSend> pMsgSend = do_CreateInstance(NS_MSGSEND_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv,rv);

    nsCOMPtr<nsIMimeConverter> mimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    // Since we have already parsed all of the headers, we are simply going to
    // set the composition fields and move on.
    //
    nsCString author;
    mMessage->GetAuthor(getter_Copies(author));

    nsMsgCompFields * fields = (nsMsgCompFields *)compFields.get();

    nsCString decodedString;
    // decoded string is null if the input is not MIME encoded
    mimeConverter->DecodeMimeHeaderToCharPtr(author.get(), nullptr, false,
            true,
            getter_Copies(decodedString));

    fields->SetFrom(decodedString.IsEmpty() ? author.get() : decodedString.get());

    if (m_to)
    {
        mimeConverter->DecodeMimeHeaderToCharPtr(m_to, nullptr, false, true,
                getter_Copies(decodedString));
        fields->SetTo(decodedString.IsEmpty() ? m_to : decodedString.get());
    }

    if (m_bcc)
    {
        mimeConverter->DecodeMimeHeaderToCharPtr(m_bcc, nullptr, false, true,
                getter_Copies(decodedString));
        fields->SetBcc(decodedString.IsEmpty() ? m_bcc : decodedString.get());
    }

    if (m_fcc)
    {
        mimeConverter->DecodeMimeHeaderToCharPtr(m_fcc, nullptr, false, true,
                getter_Copies(decodedString));
        fields->SetFcc(decodedString.IsEmpty() ? m_fcc : decodedString.get());
    }

    if (m_newsgroups)
        fields->SetNewsgroups(m_newsgroups);

#if 0
    // needs cleanup. Is this needed?
    if (m_newshost)
        fields->SetNewspostUrl(m_newshost);
#endif

    // Create the listener for the send operation...
    SendOperationListener *sendListener = new SendOperationListener(this);
    if (!sendListener)
        return NS_ERROR_OUT_OF_MEMORY;

    NS_ADDREF(sendListener);

    NS_ADDREF(this);  //TODO: We should remove this!!!
    rv = pMsgSend->SendMessageFile(identity,
                                   mAccountKey,
                                   compFields, // nsIMsgCompFields *fields,
                                   mTempFile, // nsIFile *sendFile,
                                   true, // bool deleteSendFileOnCompletion,
                                   false, // bool digest_p,
                                   nsIMsgSend::nsMsgSendUnsent, // nsMsgDeliverMode mode,
                                   nullptr, // nsIMsgDBHdr *msgToReplace,
                                   sendListener,
                                   mFeedback,
                                   nullptr);
    NS_RELEASE(sendListener);
    return rv;
}
示例#27
0
nsresult
H264Converter::CheckForSPSChange(MediaRawData* aSample)
{
  RefPtr<MediaByteBuffer> extra_data =
    mp4_demuxer::AnnexB::ExtractExtraData(aSample);
  if (!mp4_demuxer::AnnexB::HasSPS(extra_data)
      || mp4_demuxer::AnnexB::CompareExtraData(extra_data,
                                               mCurrentConfig.mExtraData)) {
        return NS_OK;
      }

  mPendingSample = aSample;

  if (CanRecycleDecoder()) {
    // Do not recreate the decoder, reuse it.
    UpdateConfigFromExtraData(extra_data);
    // Ideally we would want to drain the decoder instead of flushing it.
    // However the draining operation requires calling Drain and looping several
    // times which isn't possible from within the H264Converter. So instead we
    // flush the decoder. In practice, this is a no-op as SPS change will only
    // be used with MSE. And with MSE, the MediaFormatReader would have drained
    // the decoder already.
    RefPtr<H264Converter> self = this;
    mDecoder->Flush()
      ->Then(AbstractThread::GetCurrent()->AsTaskQueue(),
             __func__,
             [self, this]() {
               mFlushRequest.Complete();
               DecodeFirstSample(mPendingSample);
               mPendingSample = nullptr;
             },
             [self, this](const MediaResult& aError) {
               mFlushRequest.Complete();
               mDecodePromise.Reject(aError, __func__);
             })
      ->Track(mFlushRequest);
    mNeedKeyframe = true;
    // This is not really initializing the decoder, but it will do as it
    // indicates an operation is pending.
    return NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER;
  }

  // The SPS has changed, signal to flush the current decoder and create a
  // new one.
  RefPtr<H264Converter> self = this;
  mDecoder->Flush()
    ->Then(AbstractThread::GetCurrent()->AsTaskQueue(),
           __func__,
           [self, this]() {
             mFlushRequest.Complete();
             mShutdownPromise = Shutdown();
             mShutdownPromise
               ->Then(AbstractThread::GetCurrent()->AsTaskQueue(),
                      __func__,
                      [self, this]() {
                        mShutdownRequest.Complete();
                        mShutdownPromise = nullptr;
                        mNeedAVCC.reset();
                        RefPtr<MediaRawData> sample = mPendingSample.forget();
                        nsresult rv = CreateDecoderAndInit(sample);
                        if (rv == NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER) {
                          // All good so far, will continue later.
                          return;
                        }
                        MOZ_ASSERT(NS_FAILED(rv));
                        mDecodePromise.Reject(rv, __func__);
                        return;
                      },
                      [] { MOZ_CRASH("Can't reach here'"); })
               ->Track(mShutdownRequest);
           },
           [self, this](const MediaResult& aError) {
             mFlushRequest.Complete();
             mDecodePromise.Reject(aError, __func__);
           })
    ->Track(mFlushRequest);
  return NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER;
}
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;
}
示例#29
0
int main(int argc, _CONST char* argv[])
{
#ifndef MOZ_B2G_LOADER
  char exePath[MAXPATHLEN];
#endif

#ifdef MOZ_WIDGET_GONK
  // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
  // receive binder calls, though not necessary to send binder calls.
  // ProcessState::Self() also needs to be called once on the main thread to
  // register the main thread with the binder driver.
  android::ProcessState::self()->startThreadPool();
#endif

  nsresult rv;
#ifndef MOZ_B2G_LOADER
  rv = mozilla::BinaryPath::Get(argv[0], exePath);
  if (NS_FAILED(rv)) {
    Output("Couldn't calculate the application directory.\n");
    return 255;
  }

  char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
  if (!lastSlash || ((lastSlash - exePath) + sizeof(XPCOM_DLL) + 1 > MAXPATHLEN))
    return 255;

  strcpy(++lastSlash, XPCOM_DLL);
#endif // MOZ_B2G_LOADER

#if defined(XP_UNIX)
  // If the b2g app is launched from adb shell, then the shell will wind
  // up being the process group controller. This means that we can't send
  // signals to the process group (useful for profiling).
  // We ignore the return value since setsid() fails if we're already the
  // process group controller (the normal situation).
  (void)setsid();
#endif

#ifdef HAS_DLL_BLOCKLIST
  DllBlocklist_Initialize();
#endif

  // B2G loader has already initialized Gecko so we can't initialize
  // it again here.
#ifndef MOZ_B2G_LOADER
  // We do this because of data in bug 771745
  XPCOMGlueEnablePreload();

  rv = XPCOMGlueStartup(exePath);
  if (NS_FAILED(rv)) {
    Output("Couldn't load XPCOM.\n");
    return 255;
  }
  // Reset exePath so that it is the directory name and not the xpcom dll name
  *lastSlash = 0;
#endif // MOZ_B2G_LOADER

  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
  if (NS_FAILED(rv)) {
    Output("Couldn't load XRE functions.\n");
    return 255;
  }

  int result;
  {
    ScopedLogging log;
    char **_argv;

    /*
     * Duplicate argument vector to conform non-const argv of
     * do_main() since XRE_main() is very stupid with non-const argv.
     */
    _argv = new char *[argc + 1];
    for (int i = 0; i < argc; i++) {
      size_t len = strlen(argv[i]) + 1;
      _argv[i] = new char[len];
      MOZ_ASSERT(_argv[i] != nullptr);
      memcpy(_argv[i], argv[i], len);
    }
    _argv[argc] = nullptr;

    result = do_main(argc, _argv);

    for (int i = 0; i < argc; i++) {
      delete[] _argv[i];
    }
    delete[] _argv;
  }

  return result;
}
// parse and process a formatting attribute.
// Generate an autocomplete value from the
// information in aMessage and append it to aValue.  Any errors
// (including failure to find a required attribute while building up aValue) 
// return an NS_ERROR_* up the stack so that the caller doesn't try and
// generate an nsIAutoCompleteItem from this.
//
nsresult
nsAbLDAPAutoCompFormatter::ProcessFormat(const nsAString & aFormat,
                                         nsILDAPMessage *aMessage, 
                                         nsACString *aValue,
                                         nsCString *aAttrs)
{
    nsresult rv;    // temp for return values

    // get some iterators to parse aFormat
    //
    const PRUnichar *iter = aFormat.BeginReading();
    const PRUnichar *iterEnd = aFormat.EndReading();

    // get the console service for error logging
    //
    nsCOMPtr<nsIConsoleService> consoleSvc = 
        do_GetService("@mozilla.org/consoleservice;1", &rv);
    if (NS_FAILED(rv)) {
        NS_WARNING("nsAbLDAPAutoCompFormatter::ProcessFormat(): "
                   "couldn't get console service");
    }

    bool attrRequired = false;     // is this attr required or optional?
    nsCAutoString attrName;             // current attr to get

    // parse until we hit the end of the string
    //
    while (iter != iterEnd) {

        switch (*iter) {            // process the next char

        case PRUnichar('{'):

            attrRequired = true;  // this attribute is required

            /*FALLTHROUGH*/

        case PRUnichar('['):

            rv = ParseAttrName(&iter, iterEnd, attrRequired,
                               consoleSvc, attrName);

            if ( NS_FAILED(rv) ) {

                // something unrecoverable happened; stop parsing and 
                // propagate the error up the stack
                //
                return rv;
            }

            // If we're building a string of attributes...
            if (aAttrs) { 
                // ...and it doesn't already contain this string
                if (aAttrs->Find(attrName, CaseInsensitiveCompare) == kNotFound)
                {
                    // add it
                    if (!aAttrs->IsEmpty())
                        aAttrs->Append(',');
                    aAttrs->Append(attrName);
                }
            } else {

                // otherwise, append the first value of this attr to aValue
                // XXXdmose should do better than this; bug 76595

                rv = AppendFirstAttrValue(attrName, aMessage, attrRequired, 
                                          *aValue);
                if ( NS_FAILED(rv) ) {

                    // something unrecoverable happened; stop parsing and 
                    // propagate the error up the stack
                    //
                    return rv;
                }
            }

            attrName.Truncate();     // clear out for next pass
            attrRequired = false; // reset to the default for the next pass

            break;

        case PRUnichar('\\'):

            // advance the iterator and be sure we haven't run off the end
            //
            ++iter;
            if (iter == iterEnd) {

                // abort; missing escaped char
                //
                if (consoleSvc) {
                    consoleSvc->LogStringMessage(
                        NS_LITERAL_STRING(
                            "LDAP addressbook autocomplete formatter: error parsing format string: premature end of string after \\ escape").get());

                    NS_ERROR("LDAP addressbook autocomplete formatter: error "
                             "parsing format string: premature end of string "
                             "after \\ escape");
                }

                return NS_ERROR_ILLEGAL_VALUE;
            }

            /*FALLTHROUGH*/

        default:
            
            // if we're not just building an array of attribute names, append
            // this character to the item we're generating.
            //
            if (!aAttrs) {

                // this character gets treated as a literal
                //
                aValue->Append(NS_ConvertUTF16toUTF8(iter, 1));
            }
        }

        ++iter; // advance the iterator
    }

    return NS_OK;
}