예제 #1
0
void
HTMLTrackElement::LoadResource()
{
  // Find our 'src' url
  nsAutoString src;
  if (!GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
    return;
  }

  nsCOMPtr<nsIURI> uri;
  nsresult rv = NewURIFromString(src, getter_AddRefs(uri));
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  LOG(PR_LOG_ALWAYS, ("%p Trying to load from src=%s", this,
      NS_ConvertUTF16toUTF8(src).get()));

  if (mChannel) {
    mChannel->Cancel(NS_BINDING_ABORTED);
    mChannel = nullptr;
  }

  rv = nsContentUtils::GetSecurityManager()->
    CheckLoadURIWithPrincipal(NodePrincipal(), uri,
                              nsIScriptSecurityManager::STANDARD);
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_MEDIA,
                                 uri,
                                 NodePrincipal(),
                                 static_cast<Element*>(this),
                                 NS_LITERAL_CSTRING("text/vtt"), // mime type
                                 nullptr, // extra
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  if (NS_CP_REJECTED(shouldLoad)) {
    return;
  }

  CreateTextTrack();

  // Check for a Content Security Policy to pass down to the channel
  // created to load the media content.
  nsCOMPtr<nsIChannelPolicy> channelPolicy;
  nsCOMPtr<nsIContentSecurityPolicy> csp;
  rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  if (csp) {
    channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
    if (!channelPolicy) {
      return;
    }
    channelPolicy->SetContentSecurityPolicy(csp);
    channelPolicy->SetLoadType(nsIContentPolicy::TYPE_MEDIA);
  }
  nsCOMPtr<nsIChannel> channel;
  nsCOMPtr<nsILoadGroup> loadGroup = OwnerDoc()->GetDocumentLoadGroup();
  rv = NS_NewChannel(getter_AddRefs(channel),
                     uri,
                     nullptr,
                     loadGroup,
                     nullptr,
                     nsIRequest::LOAD_NORMAL,
                     channelPolicy);
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  mListener = new WebVTTListener(this);
  rv = mListener->LoadResource();
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
  channel->SetNotificationCallbacks(mListener);

  LOG(PR_LOG_DEBUG, ("opening webvtt channel"));
  rv = channel->AsyncOpen(mListener, nullptr);
  NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));

  mChannel = channel;
}
예제 #2
0
// this is identical to nsHTMLContainerFrame::Paint except for the background and border. 
NS_IMETHODIMP
nsFieldSetFrame::Paint(nsPresContext*       aPresContext,
                       nsIRenderingContext& aRenderingContext,
                       const nsRect&        aDirtyRect,
                       nsFramePaintLayer    aWhichLayer,
                       PRUint32             aFlags)
{
  if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
    // Paint our background and border
    PRBool isVisible;
    if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && 
                     isVisible && mRect.width && mRect.height) {
      PRIntn skipSides = GetSkipSides();
      const nsStyleBorder* borderStyle = GetStyleBorder();
      const nsStylePadding* paddingStyle = GetStylePadding();
       
      nscoord topBorder = borderStyle->GetBorderWidth(NS_SIDE_TOP);

      nscoord yoff = 0;
      
      // if the border is smaller than the legend. Move the border down
      // to be centered on the legend. 
      if (topBorder < mLegendRect.height)
        yoff = (mLegendRect.height - topBorder)/2;
      
      nsRect rect(0, yoff, mRect.width, mRect.height - yoff);

      nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
                                      aDirtyRect, rect, *borderStyle,
                                      *paddingStyle, PR_TRUE);

      if (mLegendFrame) {

        // Use the rect of the legend frame, not mLegendRect, so we draw our
        // border under the legend's left and right margins.
        const nsRect & legendRect = mLegendFrame->GetRect();
      
        // we should probably use PaintBorderEdges to do this but for now just use clipping
        // to achieve the same effect.

        // draw left side
        nsRect clipRect(rect);
        clipRect.width = legendRect.x - rect.x;
        clipRect.height = topBorder;

        aRenderingContext.PushState();
        aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
        nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
                                    aDirtyRect, rect, *borderStyle, mStyleContext, skipSides);
  
        aRenderingContext.PopState();


        // draw right side
        clipRect = rect;
        clipRect.x = legendRect.x + legendRect.width;
        clipRect.width -= (legendRect.x + legendRect.width);
        clipRect.height = topBorder;

        aRenderingContext.PushState();
        aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
        nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
                                    aDirtyRect, rect, *borderStyle, mStyleContext, skipSides);
  
        aRenderingContext.PopState();

      
        // draw bottom
        clipRect = rect;
        clipRect.y += topBorder;
        clipRect.height = mRect.height - (yoff + topBorder);
      
        aRenderingContext.PushState();
        aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
        nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
                                    aDirtyRect, rect, *borderStyle, mStyleContext, skipSides);
  
        aRenderingContext.PopState();
      } else {

        nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
                                    aDirtyRect,
                                    nsRect(0,0,mRect.width, mRect.height),
                                    *borderStyle, mStyleContext, skipSides);
      }
    }
  }

  PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);

#ifdef DEBUG
  if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) {
    if (HasView()) {
      aRenderingContext.SetColor(NS_RGB(0,0,255));
    }
    else {
      aRenderingContext.SetColor(NS_RGB(255,0,0));
    }
    aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height);
  }
#endif
  DO_GLOBAL_REFLOW_COUNT_DSP("nsFieldSetFrame", &aRenderingContext);
  return NS_OK;
}
예제 #3
0
NS_IMETHODIMP
nsAuthSASL::GetNextToken(const void *inToken,
                         uint32_t    inTokenLen,
                         void      **outToken,
                         uint32_t   *outTokenLen)
{
    nsresult rv;
    void *unwrappedToken;
    char *message;
    uint32_t unwrappedTokenLen, messageLen;
    nsAutoCString userbuf;
    
    if (!mInnerModule) 
        return NS_ERROR_NOT_INITIALIZED;

    if (mSASLReady) {
        // If the server COMPLETEs with an empty token, Cyrus sends us that token.
        // I don't think this is correct, but we need to handle that behaviour.
        // Cyrus ignores the contents of our reply token.
        if (inTokenLen == 0) {
            *outToken = nullptr;
            *outTokenLen = 0;
            return NS_OK;
        }
        // We've completed the GSSAPI portion of the handshake, and are
        // now ready to do the SASL security layer and authzid negotiation

        // Input packet from the server needs to be unwrapped.
        rv = mInnerModule->Unwrap(inToken, inTokenLen, &unwrappedToken, 
                                  &unwrappedTokenLen);
        if (NS_FAILED(rv)) {
            Reset();
            return rv;
        }
        
        // If we were doing security layers then we'd care what the
        // server had sent us. We're not, so all we had to do was make
        // sure that the signature was correct with the above unwrap()
        nsMemory::Free(unwrappedToken);
        
        NS_CopyUnicodeToNative(mUsername, userbuf);
        messageLen = userbuf.Length() + 4 + 1;
        message = (char *)nsMemory::Alloc(messageLen);
        if (!message) {
          Reset();
          return NS_ERROR_OUT_OF_MEMORY;
        }
        message[0] = 0x01; // No security layer
        message[1] = 0x00;
        message[2] = 0x00;
        message[3] = 0x00; // Maxbuf must be zero if we've got no sec layer
        strcpy(message+4, userbuf.get());
        // Userbuf should not be nullptr terminated, so trim the trailing nullptr
        // when wrapping the message
        rv = mInnerModule->Wrap((void *) message, messageLen-1, false, 
                                outToken, outTokenLen);
        nsMemory::Free(message);
        Reset(); // All done
        return NS_SUCCEEDED(rv) ? NS_SUCCESS_AUTH_FINISHED : rv;
    }
    rv = mInnerModule->GetNextToken(inToken, inTokenLen, outToken, 
                                    outTokenLen);
    if (rv == NS_SUCCESS_AUTH_FINISHED) {
        mSASLReady = true;
        rv = NS_OK;
    }
    return rv;
}
예제 #4
0
static nsresult
InitOperators(void)
{
  // Load the property file containing the Operator Dictionary
  nsresult rv;
  nsCOMPtr<nsIPersistentProperties> mathfontProp;
  rv = NS_LoadPersistentPropertiesFromURISpec(
         getter_AddRefs(mathfontProp),
         NS_LITERAL_CSTRING("resource://gre/res/fonts/mathfont.properties"),
         nsContentUtils::GetSystemPrincipal(),
         nsIContentPolicy::TYPE_OTHER);

  if (NS_FAILED(rv)) return rv;

  // Parse the Operator Dictionary in two passes.
  // The first pass is to count the number of operators; the second pass is to
  // allocate the necessary space for them and to add them in the hash table.
  for (int32_t pass = 1; pass <= 2; pass++) {
    OperatorData dummyData;
    OperatorData* operatorData = &dummyData;
    nsCOMPtr<nsISimpleEnumerator> iterator;
    if (NS_SUCCEEDED(mathfontProp->Enumerate(getter_AddRefs(iterator)))) {
      bool more;
      uint32_t index = 0;
      nsAutoCString name;
      nsAutoString attributes;
      while ((NS_SUCCEEDED(iterator->HasMoreElements(&more))) && more) {
        nsCOMPtr<nsISupports> supports;
        nsCOMPtr<nsIPropertyElement> element;
        if (NS_SUCCEEDED(iterator->GetNext(getter_AddRefs(supports)))) {
          element = do_QueryInterface(supports);
          if (NS_SUCCEEDED(element->GetKey(name)) &&
              NS_SUCCEEDED(element->GetValue(attributes))) {
            // expected key: operator.\uNNNN.{infix,postfix,prefix}
            if ((21 <= name.Length()) && (0 == name.Find("operator.\\u"))) {
              name.Cut(0, 9); // 9 is the length of "operator.";
              int32_t len = name.Length();
              nsOperatorFlags form = 0;
              if (kNotFound != name.RFind(".infix")) {
                form = NS_MATHML_OPERATOR_FORM_INFIX;
                len -= 6;  // 6 is the length of ".infix";
              }
              else if (kNotFound != name.RFind(".postfix")) {
                form = NS_MATHML_OPERATOR_FORM_POSTFIX;
                len -= 8; // 8 is the length of ".postfix";
              }
              else if (kNotFound != name.RFind(".prefix")) {
                form = NS_MATHML_OPERATOR_FORM_PREFIX;
                len -= 7; // 7 is the length of ".prefix";
              }
              else continue; // input is not applicable
              name.SetLength(len);
              if (2 == pass) { // allocate space and start the storage
                if (!gOperatorArray) {
                  if (0 == gOperatorCount) return NS_ERROR_UNEXPECTED;
                  gOperatorArray = new OperatorData[gOperatorCount];
                  if (!gOperatorArray) return NS_ERROR_OUT_OF_MEMORY;
                }
                operatorData = &gOperatorArray[index];
              }
              else {
                form = 0; // to quickly return from SetOperator() at pass 1
              }
              // See if the operator should be retained
              if (SetOperator(operatorData, form, name, attributes)) {
                index++;
                if (1 == pass) gOperatorCount = index;
              }
            }
          }
        }
      }
    }
  }
  return NS_OK;
}
예제 #5
0
char *MsgMapiListContext::ConvertBodyToMapiFormat (nsIMsgDBHdr *hdr)
{
  const int kBufLen = 64000; // I guess we only return the first 64K of a message.
  int bytesUsed = 0;
#define EMPTY_MESSAGE_LINE(buf) (buf[0] == '\r' || buf[0] == '\n' || buf[0] == '\0')

  nsCOMPtr <nsIMsgFolder> folder;
  hdr->GetFolder(getter_AddRefs(folder));
  if (!folder)
    return nullptr;

  nsCOMPtr <nsIInputStream> inputStream;
  nsCOMPtr <nsIFile> localFile;
  folder->GetFilePath(getter_AddRefs(localFile));

  nsresult rv;
  nsCOMPtr<nsIFileInputStream> fileStream = do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, nullptr);

  rv = fileStream->Init(localFile,  PR_RDONLY, 0664, false);  //just have to read the messages
  inputStream = do_QueryInterface(fileStream);

  if (inputStream)
  {
    nsCOMPtr <nsILineInputStream> fileLineStream = do_QueryInterface(inputStream);
    if (!fileLineStream)
      return nullptr;
    // ### really want to skip past headers...
    uint64_t messageOffset;
    uint32_t lineCount;
    hdr->GetMessageOffset(&messageOffset);
    hdr->GetLineCount(&lineCount);
    nsCOMPtr <nsISeekableStream> seekableStream = do_QueryInterface(inputStream);
    seekableStream->Seek(PR_SEEK_SET, messageOffset);
    bool hasMore = true;
    nsAutoCString curLine;
    bool inMessageBody = false;
    nsresult rv = NS_OK;
    while (hasMore) // advance past message headers
    {
      nsresult rv = fileLineStream->ReadLine(curLine, &hasMore);
      if (NS_FAILED(rv) || EMPTY_MESSAGE_LINE(curLine))
        break;
    }
    uint32_t msgSize;
    hdr->GetMessageSize(&msgSize);
    if (msgSize > kBufLen)
      msgSize = kBufLen - 1;
    // this is too big, since it includes the msg hdr size...oh well
    char *body = (char*) CoTaskMemAlloc (msgSize + 1);

    if (!body)
      return nullptr;
    int32_t bytesCopied = 0;
    for (hasMore = TRUE; lineCount > 0 && hasMore && NS_SUCCEEDED(rv); lineCount--)
    {
      rv = fileLineStream->ReadLine(curLine, &hasMore);
      if (NS_FAILED(rv))
        break;
      curLine.Append(CRLF);
      // make sure we have room left
      if (bytesCopied + curLine.Length() < msgSize)
      {
        strcpy(body + bytesCopied, curLine.get());
        bytesCopied += curLine.Length();
      }
    }
    PR_LOG(MAPI, PR_LOG_DEBUG, ("ConvertBodyToMapiFormat size=%x allocated size %x body = %100.100s\n", 
        bytesCopied, msgSize + 1, (char *) body) );
    body[bytesCopied] = '\0';   // rhp - fix last line garbage...
    return body;
  }
  return nullptr;
}
예제 #6
0
NS_IMETHODIMP
nsParserUtils::ParseFragment(const nsAString& aFragment,
                             PRUint32 aFlags,
                             bool aIsXML,
                             nsIURI* aBaseURI,
                             nsIDOMElement* aContextElement,
                             nsIDOMDocumentFragment** aReturn)
{
  NS_ENSURE_ARG(aContextElement);
  *aReturn = nsnull;

  nsresult rv;
  nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIDocument> document;
  nsCOMPtr<nsIDOMDocument> domDocument;
  nsCOMPtr<nsIDOMNode> contextNode;
  contextNode = do_QueryInterface(aContextElement);
  contextNode->GetOwnerDocument(getter_AddRefs(domDocument));
  document = do_QueryInterface(domDocument);
  NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);

  nsAutoScriptBlockerSuppressNodeRemoved autoBlocker;

  // stop scripts
  nsRefPtr<nsScriptLoader> loader;
  bool scripts_enabled = false;
  if (document) {
    loader = document->ScriptLoader();
    scripts_enabled = loader->GetEnabled();
  }
  if (scripts_enabled) {
    loader->SetEnabled(false);
  }

  // Wrap things in a div or body for parsing, but it won't show up in
  // the fragment.
  nsAutoTArray<nsString, 2> tagStack;
  nsCAutoString base, spec;
  if (aIsXML) {
    // XHTML
    if (aBaseURI) {
      base.Append(NS_LITERAL_CSTRING(XHTML_DIV_TAG));
      base.Append(NS_LITERAL_CSTRING(" xml:base=\""));
      aBaseURI->GetSpec(spec);
      // nsEscapeHTML is good enough, because we only need to get
      // quotes, ampersands, and angle brackets
      char* escapedSpec = nsEscapeHTML(spec.get());
      if (escapedSpec)
        base += escapedSpec;
      NS_Free(escapedSpec);
      base.Append(NS_LITERAL_CSTRING("\""));
      tagStack.AppendElement(NS_ConvertUTF8toUTF16(base));
    }  else {
      tagStack.AppendElement(NS_LITERAL_STRING(XHTML_DIV_TAG));
    }
  }

  if (NS_SUCCEEDED(rv)) {
    nsCOMPtr<nsIContent> fragment;
    if (aIsXML) {
      rv = nsContentUtils::ParseFragmentXML(aFragment,
                                            document,
                                            tagStack,
                                            true,
                                            aReturn);
      fragment = do_QueryInterface(*aReturn);
    } else {
      NS_NewDocumentFragment(aReturn,
                             document->NodeInfoManager());
      fragment = do_QueryInterface(*aReturn);
      rv = nsContentUtils::ParseFragmentHTML(aFragment,
                                             fragment,
                                             nsGkAtoms::body,
                                             kNameSpaceID_XHTML,
                                             false,
                                             true);
      // Now, set the base URI on all subtree roots.
      if (aBaseURI) {
        aBaseURI->GetSpec(spec);
        nsAutoString spec16;
        CopyUTF8toUTF16(spec, spec16);
        nsIContent* node = fragment->GetFirstChild();
        while (node) {
          if (node->IsElement()) {
            node->SetAttr(kNameSpaceID_XML,
                          nsGkAtoms::base,
                          nsGkAtoms::xml,
                          spec16,
                          false);
          }
          node = node->GetNextSibling();
        }
      }
    }
    if (fragment) {
      nsTreeSanitizer sanitizer(aFlags);
      sanitizer.Sanitize(fragment);
    }
  }

  if (scripts_enabled)
      loader->SetEnabled(true);
  
  return rv;
}
예제 #7
0
// static
nsresult
IDBFactory::AllowedForWindowInternal(nsPIDOMWindow* aWindow,
                                     nsIPrincipal** aPrincipal)
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(aWindow);
  MOZ_ASSERT(aWindow->IsInnerWindow());

  if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) {
    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
  }

  nsIDocument* document = aWindow->GetExtantDoc();
  if (document->GetSandboxFlags() & SANDBOXED_ORIGIN) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

  nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
  MOZ_ASSERT(sop);

  nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
  if (NS_WARN_IF(!principal)) {
    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
  }

  if (nsContentUtils::IsSystemPrincipal(principal)) {
    principal.forget(aPrincipal);
    return NS_OK;
  }

  bool isNullPrincipal;
  if (NS_WARN_IF(NS_FAILED(principal->GetIsNullPrincipal(&isNullPrincipal))) ||
      isNullPrincipal) {
    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
  }

  // Whitelist about:home, since it doesn't have a base domain it would not
  // pass the ThirdPartyUtil check, though it should be able to use indexedDB.
  bool skipThirdPartyCheck = false;

  nsCOMPtr<nsIURI> uri;
  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(principal->GetURI(getter_AddRefs(uri))));

  bool isAbout;
  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(uri->SchemeIs("about", &isAbout)));

  if (isAbout) {
    nsCOMPtr<nsIAboutModule> module;
    if (NS_SUCCEEDED(NS_GetAboutModule(uri, getter_AddRefs(module)))) {
      uint32_t flags;
      if (NS_SUCCEEDED(module->GetURIFlags(uri, &flags))) {
        skipThirdPartyCheck = flags & nsIAboutModule::ENABLE_INDEXED_DB;
      } else {
        NS_WARNING("GetURIFlags failed!");
      }
    } else {
      NS_WARNING("NS_GetAboutModule failed!");
    }
  }

  if (!skipThirdPartyCheck) {
    nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
      do_GetService(THIRDPARTYUTIL_CONTRACTID);
    MOZ_ASSERT(thirdPartyUtil);

    bool isThirdParty;
    if (NS_WARN_IF(NS_FAILED(
          thirdPartyUtil->IsThirdPartyWindow(aWindow,
                                             nullptr,
                                             &isThirdParty)))) {
      return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
    }

    if (isThirdParty) {
      return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    }
  }

  principal.forget(aPrincipal);
  return NS_OK;
}
예제 #8
0
 ~ScopedXPCOM()
 {
   if (NS_SUCCEEDED(rv))
     NS_ShutdownXPCOM(nsnull);
 }
예제 #9
0
int
main(PRInt32 argc, char *argv[])
{
    if (test_common_init(&argc, &argv) != 0)
        return -1;

    PRBool allTestsPassed = PR_TRUE;

    ScopedXPCOM xpcom;
    if (NS_FAILED(xpcom.rv))
      return -1;

    {
      nsresult rv0;

      nsCOMPtr<nsICookieService> cookieService =
        do_GetService(kCookieServiceCID, &rv0);
      if (NS_FAILED(rv0)) return -1;

      nsCOMPtr<nsIPrefBranch> prefBranch =
        do_GetService(kPrefServiceCID, &rv0);
      if (NS_FAILED(rv0)) return -1;

      InitPrefs(prefBranch);

      PRBool rv[20];
      nsCString cookie;

      /* The basic idea behind these tests is the following:
       *
       * we set() some cookie, then try to get() it in various ways. we have
       * several possible tests we perform on the cookie string returned from
       * get():
       *
       * a) check whether the returned string is null (i.e. we got no cookies
       *    back). this is used e.g. to ensure a given cookie was deleted
       *    correctly, or to ensure a certain cookie wasn't returned to a given
       *    host.
       * b) check whether the returned string exactly matches a given string.
       *    this is used where we want to make sure our cookie service adheres to
       *    some strict spec (e.g. ordering of multiple cookies), or where we
       *    just know exactly what the returned string should be.
       * c) check whether the returned string contains/does not contain a given
       *    string. this is used where we don't know/don't care about the
       *    ordering of multiple cookies - we just want to make sure the cookie
       *    string contains them all, in some order.
       *
       * the results of each individual testing operation from CheckResult() is
       * stored in an array of bools, which is then checked against the expected
       * outcomes (all successes), by PrintResult(). the overall result of all
       * tests to date is kept in |allTestsPassed|, for convenient display at the
       * end.
       *
       * Interpreting the output:
       * each setting/getting operation will print output saying exactly what
       * it's doing and the outcome, respectively. this information is only
       * useful for debugging purposes; the actual result of the tests is
       * printed at the end of each block of tests. this will either be "all
       * tests passed" or "tests X Y Z failed", where X, Y, Z are the indexes
       * of rv (i.e. zero-based). at the conclusion of all tests, the overall
       * passed/failed result is printed.
       *
       * NOTE: this testsuite is not yet comprehensive or complete, and is
       * somewhat contrived - still under development, and needs improving!
       */

      // *** basic tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning basic tests...\n");

      // test some basic variations of the domain & path
      SetACookie(cookieService, "http://www.basic.com", nsnull, "test=basic", nsnull);
      GetACookie(cookieService, "http://www.basic.com", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic");
      GetACookie(cookieService, "http://www.basic.com/testPath/testfile.txt", nsnull, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic");
      GetACookie(cookieService, "http://www.basic.com./", nsnull, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://www.basic.com.", nsnull, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://www.basic.com./testPath/testfile.txt", nsnull, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://www.basic2.com/", nsnull, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://www.basic.com", nsnull, "test=basic; max-age=-1", nsnull);
      GetACookie(cookieService, "http://www.basic.com/", nsnull, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 7) && allTestsPassed;


      // *** domain tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning domain tests...\n");

      // test some variations of the domain & path, for different domains of
      // a domain cookie
      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=domain.com", nsnull);
      GetACookie(cookieService, "http://domain.com", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      GetACookie(cookieService, "http://domain.com.", nsnull, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://www.domain.com", nsnull, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      GetACookie(cookieService, "http://foo.domain.com", nsnull, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=domain.com; max-age=-1", nsnull);
      GetACookie(cookieService, "http://domain.com", nsnull, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=.domain.com", nsnull);
      GetACookie(cookieService, "http://domain.com", nsnull, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      GetACookie(cookieService, "http://www.domain.com", nsnull, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      GetACookie(cookieService, "http://bah.domain.com", nsnull, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain");
      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=.domain.com; max-age=-1", nsnull);
      GetACookie(cookieService, "http://domain.com", nsnull, getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=.foo.domain.com", nsnull);
      GetACookie(cookieService, "http://foo.domain.com", nsnull, getter_Copies(cookie));
      rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=moose.com", nsnull);
      GetACookie(cookieService, "http://foo.domain.com", nsnull, getter_Copies(cookie));
      rv[10] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=domain.com.", nsnull);
      GetACookie(cookieService, "http://foo.domain.com", nsnull, getter_Copies(cookie));
      rv[11] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=..domain.com", nsnull);
      GetACookie(cookieService, "http://foo.domain.com", nsnull, getter_Copies(cookie));
      rv[12] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://www.domain.com", nsnull, "test=domain; domain=..domain.com.", nsnull);
      GetACookie(cookieService, "http://foo.domain.com", nsnull, getter_Copies(cookie));
      rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 14) && allTestsPassed;


      // *** path tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path tests...\n");

      // test some variations of the domain & path, for different paths of
      // a path cookie
      SetACookie(cookieService, "http://path.net/path/file", nsnull, "test=path; path=/path", nsnull);
      GetACookie(cookieService, "http://path.net/path", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path/", nsnull, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path/hithere.foo", nsnull, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path?hithere/foo", nsnull, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path2", nsnull, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://path.net/path2/", nsnull, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://path.net/path/file", nsnull, "test=path; path=/path; max-age=-1", nsnull);
      GetACookie(cookieService, "http://path.net/path/", nsnull, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://path.net/path/file", nsnull, "test=path; path=/path/", nsnull);
      GetACookie(cookieService, "http://path.net/path", nsnull, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      GetACookie(cookieService, "http://path.net/path/", nsnull, getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      SetACookie(cookieService, "http://path.net/path/file", nsnull, "test=path; path=/path/; max-age=-1", nsnull);
      GetACookie(cookieService, "http://path.net/path/", nsnull, getter_Copies(cookie));
      rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);

      // note that a site can set a cookie for a path it's not on.
      // this is an intentional deviation from spec (see comments in
      // nsCookieService::CheckPath()), so we test this functionality too
      SetACookie(cookieService, "http://path.net/path/file", nsnull, "test=path; path=/foo/", nsnull);
      GetACookie(cookieService, "http://path.net/path", nsnull, getter_Copies(cookie));
      rv[10] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://path.net/foo", nsnull, getter_Copies(cookie));
      rv[11] = CheckResult(cookie.get(), MUST_EQUAL, "test=path");
      SetACookie(cookieService, "http://path.net/path/file", nsnull, "test=path; path=/foo/; max-age=-1", nsnull);
      GetACookie(cookieService, "http://path.net/foo/", nsnull, getter_Copies(cookie));
      rv[12] = CheckResult(cookie.get(), MUST_BE_NULL);

      // bug 373228: make sure cookies with paths longer than 1024 bytes,
      // and cookies with paths or names containing tabs, are rejected.
      // the following cookie has a path > 1024 bytes explicitly specified in the cookie
      SetACookie(cookieService, "http://path.net/", nsnull, "test=path; path=/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nsnull);
      GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", nsnull, getter_Copies(cookie));
      rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);
      // the following cookie has a path > 1024 bytes implicitly specified by the uri path
      SetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nsnull, "test=path", nsnull);
      GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nsnull, getter_Copies(cookie));
      rv[14] = CheckResult(cookie.get(), MUST_BE_NULL);
      // the following cookie includes a tab in the path
      SetACookie(cookieService, "http://path.net/", nsnull, "test=path; path=/foo\tbar/", nsnull);
      GetACookie(cookieService, "http://path.net/foo\tbar/", nsnull, getter_Copies(cookie));
      rv[15] = CheckResult(cookie.get(), MUST_BE_NULL);
      // the following cookie includes a tab in the name
      SetACookie(cookieService, "http://path.net/", nsnull, "test\ttabs=tab", nsnull);
      GetACookie(cookieService, "http://path.net/", nsnull, getter_Copies(cookie));
      rv[16] = CheckResult(cookie.get(), MUST_BE_NULL);
      // the following cookie includes a tab in the value - allowed
      SetACookie(cookieService, "http://path.net/", nsnull, "test=tab\ttest", nsnull);
      GetACookie(cookieService, "http://path.net/", nsnull, getter_Copies(cookie));
      rv[17] = CheckResult(cookie.get(), MUST_EQUAL, "test=tab\ttest");
      SetACookie(cookieService, "http://path.net/", nsnull, "test=tab\ttest; max-age=-1", nsnull);
      GetACookie(cookieService, "http://path.net/", nsnull, getter_Copies(cookie));
      rv[18] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 19) && allTestsPassed;


      // *** expiry & deletion tests
      // XXX add server time str parsing tests here
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning expiry & deletion tests...\n");

      // test some variations of the expiry time,
      // and test deletion of previously set cookies
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; max-age=-1", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; max-age=0", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; expires=bad", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT\"", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; max-age=60", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; max-age=-20", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; max-age=60", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[9] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=expiry; max-age=60", nsnull);
      SetACookie(cookieService, "http://expireme.org/", nsnull, "newtest=expiry; max-age=60", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[10] = CheckResult(cookie.get(), MUST_CONTAIN, "test=expiry");
      rv[11] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=expiry");
      SetACookie(cookieService, "http://expireme.org/", nsnull, "test=differentvalue; max-age=0", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[12] = CheckResult(cookie.get(), MUST_EQUAL, "newtest=expiry");
      SetACookie(cookieService, "http://expireme.org/", nsnull, "newtest=evendifferentvalue; max-age=0", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[13] = CheckResult(cookie.get(), MUST_BE_NULL);

      SetACookie(cookieService, "http://foo.expireme.org/", nsnull, "test=expiry; domain=.expireme.org; max-age=60", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry");
      SetACookie(cookieService, "http://bar.expireme.org/", nsnull, "test=differentvalue; domain=.expireme.org; max-age=0", nsnull);
      GetACookie(cookieService, "http://expireme.org/", nsnull, getter_Copies(cookie));
      rv[15] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 16) && allTestsPassed;


      // *** multiple cookie tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning multiple cookie tests...\n");

      // test the setting of multiple cookies, and test the order of precedence
      // (a later cookie overwriting an earlier one, in the same header string)
      SetACookie(cookieService, "http://multiple.cookies/", nsnull, "test=multiple; domain=.multiple.cookies \n test=different \n test=same; domain=.multiple.cookies \n newtest=ciao \n newtest=foo; max-age=-6 \n newtest=reincarnated", nsnull);
      GetACookie(cookieService, "http://multiple.cookies/", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=multiple");
      rv[1] = CheckResult(cookie.get(), MUST_CONTAIN, "test=different");
      rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=same");
      rv[3] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=ciao");
      rv[4] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=foo");
      rv[5] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=reincarnated") != nsnull;
      SetACookie(cookieService, "http://multiple.cookies/", nsnull, "test=expiry; domain=.multiple.cookies; max-age=0", nsnull);
      GetACookie(cookieService, "http://multiple.cookies/", nsnull, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=same");
      SetACookie(cookieService, "http://multiple.cookies/", nsnull,  "\n test=different; max-age=0 \n", nsnull);
      GetACookie(cookieService, "http://multiple.cookies/", nsnull, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=different");
      SetACookie(cookieService, "http://multiple.cookies/", nsnull,  "newtest=dead; max-age=0", nsnull);
      GetACookie(cookieService, "http://multiple.cookies/", nsnull, getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 9) && allTestsPassed;


      // *** parser tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning parser tests...\n");

      // test the cookie header parser, under various circumstances.
      SetACookie(cookieService, "http://parser.test/", nsnull, "test=parser; domain=.parser.test; ;; ;=; ,,, ===,abc,=; abracadabra! max-age=20;=;;", nsnull);
      GetACookie(cookieService, "http://parser.test/", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=parser");
      SetACookie(cookieService, "http://parser.test/", nsnull, "test=parser; domain=.parser.test; max-age=0", nsnull);
      GetACookie(cookieService, "http://parser.test/", nsnull, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://parser.test/", nsnull, "test=\"fubar! = foo;bar\\\";\" parser; domain=.parser.test; max-age=6\nfive; max-age=2.63,", nsnull);
      GetACookie(cookieService, "http://parser.test/", nsnull, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=\"fubar! = foo");
      rv[3] = CheckResult(cookie.get(), MUST_CONTAIN, "five");
      SetACookie(cookieService, "http://parser.test/", nsnull, "test=kill; domain=.parser.test; max-age=0 \n five; max-age=0", nsnull);
      GetACookie(cookieService, "http://parser.test/", nsnull, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);

      // test the handling of VALUE-only cookies (see bug 169091),
      // i.e. "six" should assume an empty NAME, which allows other VALUE-only
      // cookies to overwrite it
      SetACookie(cookieService, "http://parser.test/", nsnull, "six", nsnull);
      GetACookie(cookieService, "http://parser.test/", nsnull, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "six");
      SetACookie(cookieService, "http://parser.test/", nsnull, "seven", nsnull);
      GetACookie(cookieService, "http://parser.test/", nsnull, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "seven");
      SetACookie(cookieService, "http://parser.test/", nsnull, " =eight", nsnull);
      GetACookie(cookieService, "http://parser.test/", nsnull, getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "eight");
      SetACookie(cookieService, "http://parser.test/", nsnull, "test=six", nsnull);
      GetACookie(cookieService, "http://parser.test/", nsnull, getter_Copies(cookie));
      rv[9] = CheckResult(cookie.get(), MUST_CONTAIN, "test=six");

      allTestsPassed = PrintResult(rv, 10) && allTestsPassed;


      // *** mailnews tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning mailnews tests...\n");

      // test some mailnews cookies to ensure blockage.
      // we use null firstURI's deliberately, since we have hacks to deal with
      // this situation...
      SetACookie(cookieService, "mailbox://mail.co.uk/", nsnull, "test=mailnews", nsnull);
      GetACookie(cookieService, "mailbox://mail.co.uk/", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://mail.co.uk/", nsnull, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_BE_NULL);
      SetACookie(cookieService, "http://mail.co.uk/", nsnull, "test=mailnews", nsnull);
      GetACookie(cookieService, "mailbox://mail.co.uk/", nsnull, getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_BE_NULL);
      GetACookie(cookieService, "http://mail.co.uk/", nsnull, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=mailnews");
      SetACookie(cookieService, "http://mail.co.uk/", nsnull, "test=mailnews; max-age=0", nsnull);
      GetACookie(cookieService, "http://mail.co.uk/", nsnull, getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);

      allTestsPassed = PrintResult(rv, 5) && allTestsPassed;


      // *** path ordering tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path ordering tests...\n");

      // test that cookies are returned in path order - longest to shortest.
      // if the header doesn't specify a path, it's taken from the host URI.
      SetACookie(cookieService, "http://multi.path.tests/", nsnull, "test1=path; path=/one/two/three", nsnull);
      SetACookie(cookieService, "http://multi.path.tests/", nsnull, "test2=path; path=/one \n test3=path; path=/one/two/three/four \n test4=path; path=/one/two \n test5=path; path=/one/two/", nsnull);
      SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/", nsnull, "test6=path", nsnull);
      SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nsnull, "test7=path; path=", nsnull);
      SetACookie(cookieService, "http://multi.path.tests/", nsnull, "test8=path; path=/", nsnull);
      GetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test7=path; test6=path; test3=path; test1=path; test5=path; test4=path; test2=path; test8=path");

      allTestsPassed = PrintResult(rv, 1) && allTestsPassed;


      // *** httponly tests 
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning httponly tests...\n");

      // Since this cookie is NOT set via http, setting it fails
      SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly");
      GetACookie(cookieService, "http://httponly.test/", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_BE_NULL);
      // Since this cookie is set via http, it can be retrieved
      SetACookie(cookieService, "http://httponly.test/", nsnull, "test=httponly; httponly", nsnull);
      GetACookie(cookieService, "http://httponly.test/", nsnull, getter_Copies(cookie));
      rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
      // ... but not by web content
      GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
      rv[2] = CheckResult(cookie.get(), MUST_BE_NULL);
      // Non-Http cookies should not replace HttpOnly cookies
      SetACookie(cookieService, "http://httponly.test/", nsnull, "test=httponly; httponly", nsnull);
      SetACookieNoHttp(cookieService, "http://httponly.test/", "test=not-httponly");
      GetACookie(cookieService, "http://httponly.test/", nsnull, getter_Copies(cookie));
      rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
      // ... and, if an HttpOnly cookie already exists, should not be set at all
      GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
      rv[4] = CheckResult(cookie.get(), MUST_BE_NULL);
      // Non-Http cookies should not delete HttpOnly cookies
      SetACookie(cookieService, "http://httponly.test/", nsnull, "test=httponly; httponly", nsnull);
      SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; max-age=-1");
      GetACookie(cookieService, "http://httponly.test/", nsnull, getter_Copies(cookie));
      rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly");
      // ... but HttpOnly cookies should
      SetACookie(cookieService, "http://httponly.test/", nsnull, "test=httponly; httponly; max-age=-1", nsnull);
      GetACookie(cookieService, "http://httponly.test/", nsnull, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_BE_NULL);
      // Non-Httponly cookies can replace HttpOnly cookies when set over http
      SetACookie(cookieService, "http://httponly.test/", nsnull, "test=httponly; httponly", nsnull);
      SetACookie(cookieService, "http://httponly.test/", nsnull, "test=not-httponly", nsnull);
      GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly");
      // scripts should not be able to set httponly cookies by replacing an existing non-httponly cookie
      SetACookie(cookieService, "http://httponly.test/", nsnull, "test=not-httponly", nsnull);
      SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly");
      GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie));
      rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly");

      allTestsPassed = PrintResult(rv, 9) && allTestsPassed;


      // *** nsICookieManager{2} interface tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning nsICookieManager{2} interface tests...\n");
      nsCOMPtr<nsICookieManager> cookieMgr = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv0);
      if (NS_FAILED(rv0)) return -1;
      nsCOMPtr<nsICookieManager2> cookieMgr2 = do_QueryInterface(cookieMgr);
      if (!cookieMgr2) return -1;
      
      // first, ensure a clean slate
      rv[0] = NS_SUCCEEDED(cookieMgr->RemoveAll());
      // add some cookies
      rv[1] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
                                           NS_LITERAL_CSTRING("/foo"),           // path
                                           NS_LITERAL_CSTRING("test1"),          // name
                                           NS_LITERAL_CSTRING("yes"),            // value
                                           PR_FALSE,                             // is secure
                                           PR_FALSE,                             // is httponly
                                           PR_TRUE,                              // is session
                                           LL_MAXINT));                          // expiry time
      rv[2] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain
                                           NS_LITERAL_CSTRING("/foo"),           // path
                                           NS_LITERAL_CSTRING("test2"),          // name
                                           NS_LITERAL_CSTRING("yes"),            // value
                                           PR_FALSE,                             // is secure
                                           PR_TRUE,                              // is httponly
                                           PR_TRUE,                              // is session
                                           PR_Now() / PR_USEC_PER_SEC + 2));     // expiry time
      rv[3] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"),     // domain
                                           NS_LITERAL_CSTRING("/rabbit"),        // path
                                           NS_LITERAL_CSTRING("test3"),          // name
                                           NS_LITERAL_CSTRING("yes"),            // value
                                           PR_FALSE,                             // is secure
                                           PR_FALSE,                             // is httponly
                                           PR_TRUE,                              // is session
                                           LL_MAXINT));                          // expiry time
      // confirm using enumerator
      nsCOMPtr<nsISimpleEnumerator> enumerator;
      rv[4] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator)));
      PRInt32 i = 0;
      PRBool more;
      nsCOMPtr<nsICookie2> expiredCookie, newDomainCookie;
      while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
        nsCOMPtr<nsISupports> cookie;
        if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break;
        ++i;
        
        // keep tabs on the second and third cookies, so we can check them later
        nsCOMPtr<nsICookie2> cookie2(do_QueryInterface(cookie));
        if (!cookie2) break;
        nsCAutoString name;
        cookie2->GetName(name);
        if (name == NS_LITERAL_CSTRING("test2"))
          expiredCookie = cookie2;
        else if (name == NS_LITERAL_CSTRING("test3"))
          newDomainCookie = cookie2;
      }
      rv[5] = i == 3;
      // check the httpOnly attribute of the second cookie is honored
      GetACookie(cookieService, "http://cookiemgr.test/foo/", nsnull, getter_Copies(cookie));
      rv[6] = CheckResult(cookie.get(), MUST_CONTAIN, "test2=yes");
      GetACookieNoHttp(cookieService, "http://cookiemgr.test/foo/", getter_Copies(cookie));
      rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test2=yes");
      // check CountCookiesFromHost()
      PRUint32 hostCookies = 0;
      rv[8] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) &&
              hostCookies == 2;
      // check CookieExists() using the third cookie
      PRBool found;
      rv[9] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && found;
      // remove the cookie, block it, and ensure it can't be added again
      rv[10] = NS_SUCCEEDED(cookieMgr->Remove(NS_LITERAL_CSTRING("new.domain"), // domain
                                              NS_LITERAL_CSTRING("test3"),      // name
                                              NS_LITERAL_CSTRING("/rabbit"),    // path
                                              PR_TRUE));                        // is blocked
      rv[11] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found;
      rv[12] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"),     // domain
                                            NS_LITERAL_CSTRING("/rabbit"),        // path
                                            NS_LITERAL_CSTRING("test3"),          // name
                                            NS_LITERAL_CSTRING("yes"),            // value
                                            PR_FALSE,                             // is secure
                                            PR_FALSE,                             // is httponly
                                            PR_TRUE,                              // is session
                                            LL_MININT));                          // expiry time
      rv[13] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found;
      // sleep four seconds, to make sure the second cookie has expired
      PR_Sleep(4 * PR_TicksPerSecond());
      // check that both CountCookiesFromHost() and CookieExists() count the
      // expired cookie
      rv[14] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) &&
              hostCookies == 2;
      rv[15] = NS_SUCCEEDED(cookieMgr2->CookieExists(expiredCookie, &found)) && found;
      // double-check RemoveAll() using the enumerator
      rv[16] = NS_SUCCEEDED(cookieMgr->RemoveAll());
      rv[17] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))) &&
               NS_SUCCEEDED(enumerator->HasMoreElements(&more)) &&
               !more;

      allTestsPassed = PrintResult(rv, 18) && allTestsPassed;


      // *** eviction and creation ordering tests
      sBuffer = PR_sprintf_append(sBuffer, "*** Beginning eviction and creation ordering tests...\n");

      // test that cookies are
      // a) returned by order of creation time (oldest first, newest last)
      // b) evicted by order of lastAccessed time, if the limit on cookies per host (50) is reached
      nsCAutoString name;
      nsCAutoString expected;
      for (PRInt32 i = 0; i < 60; ++i) {
        name = NS_LITERAL_CSTRING("test");
        name.AppendInt(i);
        name += NS_LITERAL_CSTRING("=creation");
        SetACookie(cookieService, "http://creation.ordering.tests/", nsnull, name.get(), nsnull);

        if (i >= 10) {
          expected += name;
          if (i < 59)
            expected += NS_LITERAL_CSTRING("; ");
        }
      }
      GetACookie(cookieService, "http://creation.ordering.tests/", nsnull, getter_Copies(cookie));
      rv[0] = CheckResult(cookie.get(), MUST_EQUAL, expected.get());

      allTestsPassed = PrintResult(rv, 1) && allTestsPassed;


      // XXX the following are placeholders: add these tests please!
      // *** "noncompliant cookie" tests
      // *** IP address tests
      // *** speed tests


      sBuffer = PR_sprintf_append(sBuffer, "\n*** Result: %s!\n\n", allTestsPassed ? "all tests passed" : "TEST(S) FAILED");
    }

    if (!allTestsPassed) {
      // print the entire log
      printf("%s", sBuffer);
      return 1;
    }

    PR_smprintf_free(sBuffer);
    sBuffer = nsnull;

    return 0;
}
예제 #10
0
// |decode_mime_part2_str| taken from comi18n.c
// Decode RFC2047-encoded words in the input and convert the result to UTF-8.
// If aOverrideCharset is true, charset in RFC2047-encoded words is 
// ignored and aDefaultCharset is assumed, instead. aDefaultCharset
// is also used to convert raw octets (without RFC 2047 encoding) to UTF-8.
//static
nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset, 
                          PRBool aOverrideCharset, nsACString &aResult)
{
  const char *p, *q, *r;
  char *decodedText;
  const char *begin; // tracking pointer for where we are in the input buffer
  PRInt32 isLastEncodedWord = 0;
  const char *charsetStart, *charsetEnd;
  char charset[80];

  // initialize charset name to an empty string
  charset[0] = '\0';

  begin = aHeader;

  // To avoid buffer realloc, if possible, set capacity in advance. No 
  // matter what,  more than 3x expansion can never happen for all charsets
  // supported by Mozilla. SCSU/BCSU with the sliding window set to a
  // non-BMP block may be exceptions, but Mozilla does not support them. 
  // Neither any known mail/news program use them. Even if there's, we're
  // safe because we don't use a raw *char any more.
  aResult.SetCapacity(3 * strlen(aHeader));

  while ((p = PL_strstr(begin, "=?")) != 0) {
    if (isLastEncodedWord) {
      // See if it's all whitespace.
      for (q = begin; q < p; ++q) {
        if (!PL_strchr(" \t\r\n", *q)) break;
      }
    }

    if (!isLastEncodedWord || q < p) {
      // copy the part before the encoded-word
      CopyRawHeader(begin, p - begin, aDefaultCharset, aResult);
      begin = p;
    }

    p += 2;

    // Get charset info
    charsetStart = p;
    charsetEnd = 0;
    for (q = p; *q != '?'; q++) {
      if (*q <= ' ' || PL_strchr(especials, *q)) {
        goto badsyntax;
      }

      // RFC 2231 section 5
      if (!charsetEnd && *q == '*') {
        charsetEnd = q; 
      }
    }
    if (!charsetEnd) {
      charsetEnd = q;
    }

    // Check for too-long charset name
    if (PRUint32(charsetEnd - charsetStart) >= sizeof(charset)) 
      goto badsyntax;
    
    memcpy(charset, charsetStart, charsetEnd - charsetStart);
    charset[charsetEnd - charsetStart] = 0;

    q++;
    if (*q != 'Q' && *q != 'q' && *q != 'B' && *q != 'b')
      goto badsyntax;

    if (q[1] != '?')
      goto badsyntax;

    r = q;
    for (r = q + 2; *r != '?'; r++) {
      if (*r < ' ') goto badsyntax;
    }
    if (r[1] != '=')
        goto badsyntax;
    else if (r == q + 2) {
        // it's empty, skip
        begin = r + 2;
        isLastEncodedWord = 1;
        continue;
    }

    if(*q == 'Q' || *q == 'q')
      decodedText = DecodeQ(q + 2, r - (q + 2));
    else {
      // bug 227290. ignore an extraneous '=' at the end.
      // (# of characters in B-encoded part has to be a multiple of 4)
      PRInt32 n = r - (q + 2);
      n -= (n % 4 == 1 && !PL_strncmp(r - 3, "===", 3)) ? 1 : 0;
      decodedText = PL_Base64Decode(q + 2, n, nsnull);
    }

    if (decodedText == nsnull)
      goto badsyntax;

    // Override charset if requested.  Never override labeled UTF-8.
    // Use default charset instead of UNKNOWN-8BIT
    if ((aOverrideCharset && 0 != nsCRT::strcasecmp(charset, "UTF-8")) ||
        (aDefaultCharset && 0 == nsCRT::strcasecmp(charset, "UNKNOWN-8BIT"))) {
      PL_strncpy(charset, aDefaultCharset, sizeof(charset) - 1);
      charset[sizeof(charset) - 1] = '\0';
    }

    {
      nsCOMPtr<nsIUTF8ConverterService> 
        cvtUTF8(do_GetService(NS_UTF8CONVERTERSERVICE_CONTRACTID));
      nsCAutoString utf8Text;
      // skip ASCIIness/UTF8ness test if aCharset is 7bit non-ascii charset.
      if (cvtUTF8 &&
          NS_SUCCEEDED(
            cvtUTF8->ConvertStringToUTF8(nsDependentCString(decodedText),
            charset, IS_7BIT_NON_ASCII_CHARSET(charset), utf8Text))) {
        aResult.Append(utf8Text);
      } else {
        aResult.Append(REPLACEMENT_CHAR);
      }
    }
    PR_Free(decodedText);
    begin = r + 2;
    isLastEncodedWord = 1;
    continue;

  badsyntax:
    // copy the part before the encoded-word
    aResult.Append(begin, p - begin);
    begin = p;
    isLastEncodedWord = 0;
  }

  // put the tail back
  CopyRawHeader(begin, strlen(begin), aDefaultCharset, aResult);

  nsCAutoString tempStr(aResult);
  tempStr.ReplaceChar('\t', ' ');
  aResult = tempStr;

  return NS_OK;
}
// Extracts whatever information we need out of fd (using SSL_*) and passes it
// to SSLServerCertVerificationJob::Dispatch. SSLServerCertVerificationJob should
// never do anything with fd except logging.
SECStatus
AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
{
  // Runs on the socket transport thread

  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
         ("[%p] starting AuthCertificateHook\n", fd));

  // Modern libssl always passes PR_TRUE for checkSig, and we have no means of
  // doing verification without checking signatures.
  NS_ASSERTION(checkSig, "AuthCertificateHook: checkSig unexpectedly false");

  // PSM never causes libssl to call this function with PR_TRUE for isServer,
  // and many things in PSM assume that we are a client.
  NS_ASSERTION(!isServer, "AuthCertificateHook: isServer unexpectedly true");

  nsNSSSocketInfo *socketInfo = static_cast<nsNSSSocketInfo*>(arg);
  
  if (socketInfo) {
    // This is the first callback during full handshakes.
    socketInfo->SetFirstServerHelloReceived();
  }

  CERTCertificate *serverCert = SSL_PeerCertificate(fd);
  CERTCertificateCleaner serverCertCleaner(serverCert);

  if (!checkSig || isServer || !socketInfo || !serverCert) {
      PR_SetError(PR_INVALID_STATE_ERROR, 0);
      return SECFailure;
  }
      
  if (BlockServerCertChangeForSpdy(socketInfo, serverCert) != SECSuccess)
    return SECFailure;

  bool onSTSThread;
  nsresult nrv;
  nsCOMPtr<nsIEventTarget> sts
    = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &nrv);
  if (NS_SUCCEEDED(nrv)) {
    nrv = sts->IsOnCurrentThread(&onSTSThread);
  }

  if (NS_FAILED(nrv)) {
    NS_ERROR("Could not get STS service or IsOnCurrentThread failed");
    PR_SetError(PR_UNKNOWN_ERROR, 0);
    return SECFailure;
  }
  
  if (onSTSThread) {
    // We *must* do certificate verification on a background thread because
    // we need the socket transport thread to be free for our OCSP requests,
    // and we *want* to do certificate verification on a background thread
    // because of the performance benefits of doing so.
    socketInfo->SetCertVerificationWaiting();
    SECStatus rv = SSLServerCertVerificationJob::Dispatch(
                        static_cast<const void *>(fd), socketInfo, serverCert);
    return rv;
  }
  
  // We can't do certificate verification on a background thread, because the
  // thread doing the network I/O may not interrupt its network I/O on receipt
  // of our SSLServerCertVerificationResult event, and/or it might not even be
  // a non-blocking socket.
  SECStatus rv = AuthCertificate(socketInfo, serverCert);
  if (rv == SECSuccess) {
    return SECSuccess;
  }

  PRErrorCode error = PR_GetError();
  if (error != 0) {
    nsRefPtr<CertErrorRunnable> runnable = CreateCertErrorRunnable(
                    error, socketInfo, serverCert,
                    static_cast<const void *>(fd));
    if (!runnable) {
      // CreateCertErrorRunnable sets a new error code when it fails
      error = PR_GetError();
    } else {
      // We have to return SECSuccess or SECFailure based on the result of the
      // override processing, so we must block this thread waiting for it. The
      // CertErrorRunnable will NOT dispatch the result at all, since we passed
      // false for CreateCertErrorRunnable's async parameter
      nrv = runnable->DispatchToMainThreadAndWait();
      if (NS_FAILED(nrv)) {
        NS_ERROR("Failed to dispatch CertErrorRunnable");
        PR_SetError(PR_INVALID_STATE_ERROR, 0);
        return SECFailure;
      }

      if (!runnable->mResult) {
        NS_ERROR("CertErrorRunnable did not set result");
        PR_SetError(PR_INVALID_STATE_ERROR, 0);
        return SECFailure;
      }

      if (runnable->mResult->mErrorCode == 0) {
        return SECSuccess; // cert error override occurred.
      }

      // We must call SetCanceled here to set the error message type
      // in case it isn't PlainErrorMessage, which is what we would
      // default to if we just called
      // PR_SetError(runnable->mResult->mErrorCode, 0) and returned
      // SECFailure without doing this.
      socketInfo->SetCanceled(runnable->mResult->mErrorCode,
                              runnable->mResult->mErrorMessageType);
      error = runnable->mResult->mErrorCode;
    }
  }

  if (error == 0) {
    NS_ERROR("error code not set");
    error = PR_UNKNOWN_ERROR;
  }

  PR_SetError(error, 0);
  return SECFailure;
}
//-------------------------------------------------------------------------
//
// Show - Display the file dialog
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::Show(int16_t *retval)
{
  NS_ENSURE_ARG_POINTER(retval);

  bool result = false;
  nsAutoCString fileBuffer;
  char *converted = ConvertToFileSystemCharset(mDefault);
  if (nullptr == converted) {
    LossyCopyUTF16toASCII(mDefault, fileBuffer);
  }
  else {
    fileBuffer.Assign(converted);
    nsMemory::Free( converted );
  }

  char *title = ConvertToFileSystemCharset(mTitle);
  if (nullptr == title)
    title = ToNewCString(mTitle);
  nsAutoCString initialDir;
  if (mDisplayDirectory)
    mDisplayDirectory->GetNativePath(initialDir);
  // If no display directory, re-use the last one.
  if(initialDir.IsEmpty())
    initialDir = mLastUsedDirectory;

  mFile.Truncate();

  FILEDLG filedlg;
  memset(&filedlg, 0, sizeof(FILEDLG));
  filedlg.cbSize = sizeof(FILEDLG);
  filedlg.pszTitle = title;

  if (mMode == modeGetFolder) {
    PL_strncat(filedlg.szFullFile, initialDir.get(), MAX_PATH);
    if (filedlg.szFullFile[0] && 
        filedlg.szFullFile[strlen(filedlg.szFullFile) - 1] != '\\') 
      PL_strncat(filedlg.szFullFile, "\\", 1);
    PL_strncat(filedlg.szFullFile, "^", 1);
    filedlg.fl = FDS_OPEN_DIALOG | FDS_CENTER;
    filedlg.pfnDlgProc = DirDialogProc;
    DosError(FERR_DISABLEHARDERR);
    WinFileDlg(HWND_DESKTOP, mWnd, &filedlg);
    DosError(FERR_ENABLEHARDERR);
    char* tempptr = strchr(filedlg.szFullFile, '^');
    if (tempptr)
      *tempptr = '\0';
    if (filedlg.lReturn == DID_OK) {
      result = true;
      if (!mDisplayDirectory)
        mDisplayDirectory = do_CreateInstance("@mozilla.org/file/local;1");
      if (mDisplayDirectory)
        mDisplayDirectory->InitWithNativePath(nsDependentCString(filedlg.szFullFile));
      mFile.Assign(filedlg.szFullFile);
    }
  }
  else {
    PL_strncpy(filedlg.szFullFile, initialDir.get(), MAX_PATH);
    if (filedlg.szFullFile[0] && 
        filedlg.szFullFile[strlen(filedlg.szFullFile) - 1] != '\\') 
      PL_strncat(filedlg.szFullFile, "\\", 1);
    PL_strncat(filedlg.szFullFile, fileBuffer.get(), MAX_PATH);
    filedlg.fl = FDS_CENTER;
    if (mMode == modeSave) {
       filedlg.fl |= FDS_SAVEAS_DIALOG | FDS_ENABLEFILELB;
    } else if (mMode == modeOpenMultiple) {
       filedlg.fl |= FDS_MULTIPLESEL | FDS_OPEN_DIALOG;
    } else {
       filedlg.fl |= FDS_OPEN_DIALOG;
    }
    PMYDATA pmydata;
    pmydata = (PMYDATA)calloc(1, sizeof(MYDATA));
    filedlg.ulUser = (ULONG)pmydata;
    filedlg.pfnDlgProc = FileDialogProc;

    uint32_t i;

    PSZ *apszTypeList;
    apszTypeList = (PSZ *)malloc(mTitles.Length()*sizeof(PSZ)+1);
    for (i = 0; i < mTitles.Length(); i++)
    {
      const nsString& typeWide = mTitles[i];
      nsAutoCharBuffer buffer;
      int32_t bufLength;
      WideCharToMultiByte(0, typeWide.get(), typeWide.Length(),
                          buffer, bufLength);
      apszTypeList[i] = ToNewCString(nsDependentCString(buffer.Elements()));
    }
    apszTypeList[i] = 0;
    filedlg.papszITypeList = (PAPSZ)apszTypeList;

    PSZ *apszFilterList;
    apszFilterList = (PSZ *)malloc(mFilters.Length()*sizeof(PSZ)+1);
    for (i = 0; i < mFilters.Length(); i++)
    {
      const nsString& filterWide = mFilters[i];
      apszFilterList[i] = ToNewCString(filterWide);
    }
    apszFilterList[i] = 0;
    pmydata->papszIFilterList = (PAPSZ)apszFilterList;

    pmydata->ulCurExt = mSelectedType;

    bool fileExists = true;
    do {
      DosError(FERR_DISABLEHARDERR);
      WinFileDlg(HWND_DESKTOP, mWnd, &filedlg);
      DosError(FERR_ENABLEHARDERR);
      if ((filedlg.lReturn == DID_OK) && (mMode == modeSave)) {
         PRFileInfo64 fileinfo64;
         PRStatus status = PR_GetFileInfo64(filedlg.szFullFile, &fileinfo64);
         if (status == PR_SUCCESS) {
            fileExists = true;
         } else {
            fileExists = false;
         }
         if (fileExists) {
            if (!gpszFDSaveCaption) {
              HMODULE hmod;
              char LoadError[CCHMAXPATH];
              char loadedString[256];
              int length;
              DosLoadModule(LoadError, CCHMAXPATH, "PMSDMRI", &hmod);
              length = WinLoadString((HAB)0, hmod, 1110, 256, loadedString);
              gpszFDSaveCaption = (char*)malloc(length+1);
              strcpy(gpszFDSaveCaption, loadedString);
              length = WinLoadString((HAB)0, hmod, 1135, 256, loadedString);
              gpszFDFileExists = (char*)malloc(length+1);
              strcpy(gpszFDFileExists, loadedString);
              length = WinLoadString((HAB)0, hmod, 1136, 256, loadedString);
              gpszFDFileReadOnly = (char*)malloc(length+1);
              strcpy(gpszFDFileReadOnly, loadedString);
              int i;
              for (i=0;i<256 && gpszFDFileExists[i];i++ ) {
                if (gpszFDFileExists[i] == '%') {
                  gpszFDFileExists[i+1] = 's';
                  break;
                }
              }
              for (i=0;i<256 && gpszFDFileReadOnly[i];i++ ) {
                if (gpszFDFileReadOnly[i] == '%') {
                  gpszFDFileReadOnly[i+1] = 's';
                  break;
                }
              }
              DosFreeModule(hmod);

            }
            char pszFullText[256+CCHMAXPATH];
            FILESTATUS3 fsts3;
            ULONG ulResponse;
            DosQueryPathInfo( filedlg.szFullFile, FIL_STANDARD, &fsts3, sizeof(FILESTATUS3));
            if (fsts3.attrFile & FILE_READONLY) {
              sprintf(pszFullText, gpszFDFileReadOnly, filedlg.szFullFile);
              ulResponse = WinMessageBox(HWND_DESKTOP, mWnd, pszFullText,
                                               gpszFDSaveCaption, 0,
                                               MB_OK | MB_MOVEABLE | MB_WARNING);
            } else {
              sprintf(pszFullText, gpszFDFileExists, filedlg.szFullFile);
              ulResponse = WinMessageBox(HWND_DESKTOP, mWnd, pszFullText,
                                               gpszFDSaveCaption, 0,
                                               MB_YESNO | MB_MOVEABLE | MB_WARNING);
            }

            if (ulResponse == MBID_YES) {
               fileExists = false;
            }
         }
      }
    } while (mMode == modeSave && fileExists && filedlg.lReturn == DID_OK);

    if (filedlg.lReturn == DID_OK) {
      result = true;
      if (mMode == modeOpenMultiple) {
        nsresult rv;

        if (filedlg.papszFQFilename) {
          for (ULONG i=0;i<filedlg.ulFQFCount;i++) {
            nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1", &rv);
            NS_ENSURE_SUCCESS(rv,rv);

            rv = file->InitWithNativePath(nsDependentCString(*(filedlg.papszFQFilename)[i]));
            NS_ENSURE_SUCCESS(rv,rv);

            rv = mFiles.AppendObject(file);
            NS_ENSURE_SUCCESS(rv,rv);
          }
          WinFreeFileDlgList(filedlg.papszFQFilename);
        } else {
          nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1", &rv);
          NS_ENSURE_SUCCESS(rv,rv);

          rv = file->InitWithNativePath(nsDependentCString(filedlg.szFullFile));
          NS_ENSURE_SUCCESS(rv,rv);

          rv = mFiles.AppendObject(file);
          NS_ENSURE_SUCCESS(rv,rv);
        }
      } else {
        mFile.Assign(filedlg.szFullFile);
      }
      mSelectedType = (int16_t)pmydata->ulCurExt;
    }

    for (i = 0; i < mTitles.Length(); i++)
    {
      nsMemory::Free(*(filedlg.papszITypeList[i]));
    }
    free(filedlg.papszITypeList);

    for (i = 0; i < mFilters.Length(); i++)
    {
      nsMemory::Free(*(pmydata->papszIFilterList[i]));
    }
    free(pmydata->papszIFilterList);
    free(pmydata);
  }

  if (title)
    nsMemory::Free( title );

  if (result) {
    int16_t returnOKorReplace = returnOK;

    nsresult rv;
    // Remember last used directory.
    nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1", &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    file->InitWithNativePath(mFile);
    nsCOMPtr<nsIFile> dir;
    if (NS_SUCCEEDED(file->GetParent(getter_AddRefs(dir)))) {
      nsAutoCString newDir;
      dir->GetNativePath(newDir);
      if(!newDir.IsEmpty())
        PL_strncpyz(mLastUsedDirectory, newDir.get(), MAX_PATH+1);
      // Update mDisplayDirectory with this directory, also.
      // Some callers rely on this.
      if (!mDisplayDirectory)
         mDisplayDirectory = do_CreateInstance("@mozilla.org/file/local;1");
      if (mDisplayDirectory)
         mDisplayDirectory->InitWithNativePath( nsDependentCString(mLastUsedDirectory) );
    }

    if (mMode == modeSave) {
      // Windows does not return resultReplace,
      //   we must check if file already exists
      bool exists = false;
      file->Exists(&exists);
      if (exists)
        returnOKorReplace = returnReplace;
    }
    *retval = returnOKorReplace;
  }
  else {
    *retval = returnCancel;
  }
  return NS_OK;
}
int
main(int argc, char* argv[])
{
    if (test_common_init(&argc, &argv) != 0)
        return -1;

    nsresult rv;

    if (argc < 2) {
        printf("usage: %s <file-to-read>\n", argv[0]);
        return -1;
    }
    char* fileName = argv[1];
    {
        nsCOMPtr<nsIServiceManager> servMan;
        NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
        nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
        NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
        if (registrar)
            registrar->AutoRegister(nsnull);

#if defined(PR_LOGGING)
        gTestLog = PR_NewLogModule("Test");
#endif

        nsCOMPtr<nsILocalFile> srcFile;
        rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(srcFile));
        if (NS_FAILED(rv)) return rv;

        nsCOMPtr<nsIFile> destFile;
        rv = srcFile->Clone(getter_AddRefs(destFile));
        if (NS_FAILED(rv)) return rv;

        nsCAutoString leafName;
        rv = destFile->GetNativeLeafName(leafName);
        if (NS_FAILED(rv)) return rv;

        nsCAutoString newName(leafName);
        newName.Append(NS_LITERAL_CSTRING(".1"));
        rv = destFile->SetNativeLeafName(newName);
        if (NS_FAILED(rv)) return rv;

        rv = RunTest(srcFile, destFile);
        NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed");

        newName = leafName;
        newName.Append(NS_LITERAL_CSTRING(".2"));
        rv = destFile->SetNativeLeafName(newName);
        if (NS_FAILED(rv)) return rv;

        rv = RunBlockingTest(srcFile, destFile);
        NS_ASSERTION(NS_SUCCEEDED(rv), "RunBlockingTest failed");

        // give background threads a chance to finish whatever work they may
        // be doing.
        PR_Sleep(PR_SecondsToInterval(1));
    } // this scopes the nsCOMPtrs
    // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
    rv = NS_ShutdownXPCOM(nsnull);
    NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
    return NS_OK;
}
예제 #14
0
nsresult
RDFContentSinkImpl::OpenProperty(const PRUnichar* aName, const PRUnichar** aAttributes)
{
    nsresult rv;

    // an "object" non-terminal is either a "description", a "typed
    // node", or a "container", so this change the content sink's
    // state appropriately.
    nsCOMPtr<nsIAtom> localName;
    const nsDependentSubstring& nameSpaceURI =
        SplitExpatName(aName, getter_AddRefs(localName));

    const char* attrName;
    localName->GetUTF8String(&attrName);

    NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI);
    propertyStr.Append(attrName);

    nsCOMPtr<nsIRDFResource> property;
    rv = gRDFService->GetResource(propertyStr, getter_AddRefs(property));
    if (NS_FAILED(rv)) return rv;

    // See if they've specified a 'resource' attribute, in which case
    // they mean *that* to be the object of this property.
    nsCOMPtr<nsIRDFResource> target;
    GetResourceAttribute(aAttributes, getter_AddRefs(target));

    PRBool isAnonymous = PR_FALSE;

    if (! target) {
        // See if an 'ID' attribute has been specified, in which case
        // this corresponds to the fourth form of [6.12].

        // XXX strictly speaking, we should reject the RDF/XML as
        // invalid if they've specified both an 'ID' and a 'resource'
        // attribute. Bah.

        // XXX strictly speaking, 'about=' isn't allowed here, but
        // what the hell.
        GetIdAboutAttribute(aAttributes, getter_AddRefs(target), &isAnonymous);
    }

    if (target) {
        // They specified an inline resource for the value of this
        // property. Create an RDF resource for the inline resource
        // URI, add the properties to it, and attach the inline
        // resource to its parent.
        PRInt32 count;
        rv = AddProperties(aAttributes, target, &count);
        NS_ASSERTION(NS_SUCCEEDED(rv), "problem adding properties");
        if (NS_FAILED(rv)) return rv;

        if (count || !isAnonymous) {
            // If the resource was "anonymous" (i.e., they hadn't
            // explicitly set an ID or resource attribute), then we'll
            // only assert this property from the context element *if*
            // there were properties specified on the anonymous
            // resource.
            rv = mDataSource->Assert(GetContextElement(0), property, target, PR_TRUE);
            if (NS_FAILED(rv)) return rv;
        }

        // XXX Technically, we should _not_ fall through here and push
        // the element onto the stack: this is supposed to be a closed
        // node. But right now I'm lazy and the code will just Do The
        // Right Thing so long as the RDF is well-formed.
    }

    // Push the element onto the context stack and change state.
    PushContext(property, mState, mParseMode);
    mState = eRDFContentSinkState_InPropertyElement;
    SetParseMode(aAttributes);

    return NS_OK;
}
예제 #15
0
// not from interface
nsresult
nsHtml5Parser::ParseUntilBlocked()
{
  nsresult rv = mExecutor->IsBroken();
  NS_ENSURE_SUCCESS(rv, rv);
  if (mBlocked || mExecutor->IsComplete()) {
    return NS_OK;
  }
  NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle.");
  NS_ASSERTION(!mInDocumentWrite,
    "ParseUntilBlocked entered while in doc.write!");

  mDocWriteSpeculatorActive = false;

  for (;;) {
    if (!mFirstBuffer->hasMore()) {
      if (mFirstBuffer == mLastBuffer) {
        if (mExecutor->IsComplete()) {
          // something like cache manisfests stopped the parse in mid-flight
          return NS_OK;
        }
        if (mDocumentClosed) {
          nsresult rv;
          NS_ASSERTION(!GetStreamParser(),
                       "This should only happen with script-created parser.");
          if (NS_SUCCEEDED((rv = mExecutor->IsBroken()))) {
            mTokenizer->eof();
            if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
              mExecutor->MarkAsBroken(rv);
            } else {
              mTreeBuilder->StreamEnded();
            }
          }
          mTreeBuilder->Flush();
          mExecutor->FlushDocumentWrite();
          // The below call does memory cleanup, so call it even if the
          // parser has been marked as broken.
          mTokenizer->end();
          return rv;
        }
        // never release the last buffer.
        NS_ASSERTION(!mLastBuffer->getStart() && !mLastBuffer->getEnd(),
                     "Sentinel buffer had its indeces changed.");
        if (GetStreamParser()) {
          if (mReturnToStreamParserPermitted &&
              !mExecutor->IsScriptExecuting()) {
            mTreeBuilder->Flush();
            mReturnToStreamParserPermitted = false;
            GetStreamParser()->ContinueAfterScripts(mTokenizer,
                                                mTreeBuilder,
                                                mLastWasCR);
          }
        } else {
          // Script-created parser
          mTreeBuilder->Flush();
          // No need to flush the executor, because the executor is already
          // in a flush
          NS_ASSERTION(mExecutor->IsInFlushLoop(),
              "How did we come here without being in the flush loop?");
        }
        return NS_OK; // no more data for now but expecting more
      }
      mFirstBuffer = mFirstBuffer->next;
      continue;
    }

    if (mBlocked || mExecutor->IsComplete()) {
      return NS_OK;
    }

    // now we have a non-empty buffer
    mFirstBuffer->adjust(mLastWasCR);
    mLastWasCR = false;
    if (mFirstBuffer->hasMore()) {
      bool inRootContext = (!GetStreamParser() && !mFirstBuffer->key);
      if (inRootContext) {
        mTokenizer->setLineNumber(mRootContextLineNumber);
      }
      if (!mTokenizer->EnsureBufferSpace(mFirstBuffer->getLength())) {
        return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
      }
      mLastWasCR = mTokenizer->tokenizeBuffer(mFirstBuffer);
      nsresult rv;
      if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
        return mExecutor->MarkAsBroken(rv);
      }
      if (inRootContext) {
        mRootContextLineNumber = mTokenizer->getLineNumber();
      }
      if (mTreeBuilder->HasScript()) {
        mTreeBuilder->Flush();
        rv = mExecutor->FlushDocumentWrite();
        NS_ENSURE_SUCCESS(rv, rv);
      }
      if (mBlocked) {
        return NS_OK;
      }
    }
    continue;
  }
}
예제 #16
0
nsresult
FetchDriver::BasicFetch()
{
  nsAutoCString url;
  mRequest->GetURL(url);
  nsCOMPtr<nsIURI> uri;
  nsresult rv = NS_NewURI(getter_AddRefs(uri),
                 url,
                 nullptr,
                 nullptr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    FailWithNetworkError();
    return rv;
  }

  nsAutoCString scheme;
  rv = uri->GetScheme(scheme);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    FailWithNetworkError();
    return rv;
  }

  if (scheme.LowerCaseEqualsLiteral("about")) {
    if (url.EqualsLiteral("about:blank")) {
      nsRefPtr<InternalResponse> response =
        new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
      ErrorResult result;
      response->Headers()->Append(NS_LITERAL_CSTRING("content-type"),
                                  NS_LITERAL_CSTRING("text/html;charset=utf-8"),
                                  result);
      MOZ_ASSERT(!result.Failed());
      nsCOMPtr<nsIInputStream> body;
      rv = NS_NewCStringInputStream(getter_AddRefs(body), EmptyCString());
      if (NS_WARN_IF(NS_FAILED(rv))) {
        FailWithNetworkError();
        return rv;
      }

      response->SetBody(body);
      BeginResponse(response);
      return SucceedWithResponse();
    }
    return FailWithNetworkError();
  }

  if (scheme.LowerCaseEqualsLiteral("blob")) {
    nsRefPtr<FileImpl> blobImpl;
    rv = NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl));
    FileImpl* blob = static_cast<FileImpl*>(blobImpl.get());
    if (NS_WARN_IF(NS_FAILED(rv))) {
      FailWithNetworkError();
      return rv;
    }

    nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
    {
      ErrorResult result;
      uint64_t size = blob->GetSize(result);
      if (NS_WARN_IF(result.Failed())) {
        FailWithNetworkError();
        return result.ErrorCode();
      }

      nsAutoString sizeStr;
      sizeStr.AppendInt(size);
      response->Headers()->Append(NS_LITERAL_CSTRING("Content-Length"), NS_ConvertUTF16toUTF8(sizeStr), result);
      if (NS_WARN_IF(result.Failed())) {
        FailWithNetworkError();
        return result.ErrorCode();
      }

      nsAutoString type;
      blob->GetType(type);
      response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), NS_ConvertUTF16toUTF8(type), result);
      if (NS_WARN_IF(result.Failed())) {
        FailWithNetworkError();
        return result.ErrorCode();
      }
    }

    nsCOMPtr<nsIInputStream> stream;
    rv = blob->GetInternalStream(getter_AddRefs(stream));
    if (NS_WARN_IF(NS_FAILED(rv))) {
      FailWithNetworkError();
      return rv;
    }

    response->SetBody(stream);
    BeginResponse(response);
    return SucceedWithResponse();
  }

  if (scheme.LowerCaseEqualsLiteral("data")) {
    nsAutoCString method;
    mRequest->GetMethod(method);
    if (method.LowerCaseEqualsASCII("get")) {
      // Use nsDataHandler directly so that we can extract the content type.
      // XXX(nsm): Is there a way to acquire the charset without such tight
      // coupling with the DataHandler? nsIProtocolHandler does not provide
      // anything similar.
      nsAutoCString contentType, contentCharset, dataBuffer, hashRef;
      bool isBase64;
      rv = nsDataHandler::ParseURI(url,
                                   contentType,
                                   contentCharset,
                                   isBase64,
                                   dataBuffer,
                                   hashRef);
      if (NS_SUCCEEDED(rv)) {
        ErrorResult result;
        nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
        if (!contentCharset.IsEmpty()) {
          contentType.Append(";charset=");
          contentType.Append(contentCharset);
        }

        response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, result);
        if (!result.Failed()) {
          nsCOMPtr<nsIInputStream> stream;
          rv = NS_NewCStringInputStream(getter_AddRefs(stream), dataBuffer);
          if (NS_SUCCEEDED(rv)) {
            response->SetBody(stream);
            BeginResponse(response);
            return SucceedWithResponse();
          }
        }
      }
    }

    return FailWithNetworkError();
  }

  if (scheme.LowerCaseEqualsLiteral("file")) {
  } else if (scheme.LowerCaseEqualsLiteral("http") ||
             scheme.LowerCaseEqualsLiteral("https")) {
    return HttpFetch();
  }

  return FailWithNetworkError();
}
예제 #17
0
void CProfileManager::DoManageProfilesDialog()
{
    nsresult rv;
    StDialogHandler	theHandler(dlog_ManageProfiles, LCommander::GetTopCommander());
    LWindow			 *theDialog = theHandler.GetDialog();

    nsCOMPtr<nsIProfile> profileService = 
             do_GetService(NS_PROFILE_CONTRACTID, &rv);
    ThrowIfNil_(profileService);
        
    // Set up the dialog by filling the list of current profiles
    LTextTableView *table = (LTextTableView*) theDialog->FindPaneByID('List');    
    ThrowIfNil_(table);
    LPushButton *deleteButton = (LPushButton *) theDialog->FindPaneByID('Dele');
    ThrowIfNil_(deleteButton);
    
    //Str255 pascalStr;
    nsAutoString unicodeStr;
    nsCAutoString cStr;
    char dataBuf[256];
    UInt32 dataSize;
    
    // PowerPlant stuff to set up the list view
    STableCell selectedCell(1, 1);
    SDimension16 tableSize;
    TableIndexT rows, cols;

    table->GetFrameSize(tableSize);
	table->SetTableGeometry(new LTableMonoGeometry(table, tableSize.width, 16));
	table->SetTableStorage(new LTableArrayStorage(table, 0UL));
	table->SetTableSelector(new LTableSingleSelector(table));
	table->InsertCols(1, 0);

    // Get the name of the current profile so we can select it
    nsXPIDLString   currProfileName;
    profileService->GetCurrentProfile(getter_Copies(currProfileName));
    
    // Get the list of profile names and add them to the list
    PRUint32 listLen;
    PRUnichar **profileList;
    rv = profileService->GetProfileList(&listLen, &profileList);
    ThrowIfError_(rv);
    
    for (PRUint32 index = 0; index < listLen; index++)
    {
          CPlatformUCSConversion::GetInstance()->UCSToPlatform(nsDependentString(profileList[index]), cStr);
          table->InsertRows(1, LONG_MAX, cStr.get(), cStr.Length(), true);
          
          if (nsCRT::strcmp(profileList[index], currProfileName.get()) == 0)
            selectedCell.row = index + 1;
    }
    
    PRInt32 numProfiles;
    rv = profileService->GetProfileCount(&numProfiles);
    ThrowIfError_(rv);    
    (numProfiles > 1) ? deleteButton->Enable() : deleteButton->Disable();
    table->SelectCell(selectedCell);


    // Handle the "Ask At StartUp" checkbox    
    LCheckBox *showAtStartCheck = (LCheckBox*) theDialog->FindPaneByID('Show');
    ThrowIfNil_(showAtStartCheck);
    PRBool showIt;
    rv = GetShowDialogOnStart(&showIt);
    if (NS_FAILED(rv))
        showIt = PR_TRUE;
    showAtStartCheck->SetValue(showIt);

    
    theDialog->Show();
    theDialog->Select();
	
  	while (true)  // This is our modal dialog event loop
  	{				
  		MessageT	hitMessage = theHandler.DoDialog();
  		
  		if (hitMessage == msg_OK)
  		{
  		    theDialog->Hide();
            SetShowDialogOnStart(showAtStartCheck->GetValue());
   		    selectedCell = table->GetFirstSelectedCell();
   		    if (selectedCell.row > 0)
   		    {
   		        dataSize = sizeof(dataBuf) - 1;
   		        table->GetCellData(selectedCell, dataBuf, dataSize);
   		        dataBuf[dataSize] = '\0';
                CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsDependentCString(dataBuf), unicodeStr);
   		        rv = profileService->SetCurrentProfile(unicodeStr.get());
            }
  		    break;
  		}
        else if (hitMessage == msg_Cancel)
        {
           	break;
        }
        else if (hitMessage == msg_OnNewProfile)
   		{
   		    if (DoNewProfileDialog(dataBuf, sizeof(dataBuf)))
   		    {
   		        CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsDependentCString(dataBuf), unicodeStr);
   		        rv = profileService->CreateNewProfile(unicodeStr.get(), nsnull, nsnull, PR_FALSE);
   		        if (NS_FAILED(rv))
   		            break;
   		        
                table->InsertRows(1, LONG_MAX, dataBuf, strlen(dataBuf), true);
                table->GetTableSize(rows, cols);
                table->SelectCell(STableCell(rows, cols));
                
                rv = profileService->GetProfileCount(&numProfiles);
                (NS_SUCCEEDED(rv) && numProfiles > 1) ? deleteButton->Enable() : deleteButton->Disable();
   		    }    
   		}
   		else if (hitMessage == msg_OnDeleteProfile)
   		{
   		    selectedCell = table->GetFirstSelectedCell();
   		    if (selectedCell.row > 0)
   		    {
   		        dataSize = sizeof(dataBuf) - 1;
   		        table->GetCellData(selectedCell, dataBuf, dataSize);
   		        dataBuf[dataSize] = '\0';
   		        CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsDependentCString(dataBuf), unicodeStr);
   		        
   		        rv = profileService->DeleteProfile(unicodeStr.get(), PR_TRUE);
   		        if (NS_FAILED(rv))
   		            break;
   		        
   		        table->RemoveRows(1, selectedCell.row, true);
   		        table->GetTableSize(rows, cols);    
   		        if (selectedCell.row >= rows)
   		            selectedCell.row = rows - 1;
   		        table->SelectCell(selectedCell);
   		        
                rv = profileService->GetProfileCount(&numProfiles);
                (NS_SUCCEEDED(rv) && numProfiles > 1) ? deleteButton->Enable() : deleteButton->Disable();
   		    }
   		}
   		else if (hitMessage == msg_OnRenameProfile)
   		{
	        nsAutoString oldName;

   		    selectedCell = table->GetFirstSelectedCell();
	        dataSize = sizeof(dataBuf) - 1;
	        table->GetCellData(selectedCell, dataBuf, dataSize);
	        dataBuf[dataSize] = '\0';
	        CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsDependentCString(dataBuf), oldName);

   		    if (DoNewProfileDialog(dataBuf, sizeof(dataBuf)))
   		    {
   		        CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsDependentCString(dataBuf), unicodeStr);
                profileService->RenameProfile(oldName.get(), unicodeStr.get());
                table->SetCellData(selectedCell, dataBuf, strlen(dataBuf)); 		        
   		    }
   		}
  	}  
}
예제 #18
0
nsresult
FetchDriver::ContinueFetch(bool aCORSFlag)
{
  workers::AssertIsOnMainThread();

  nsAutoCString url;
  mRequest->GetURL(url);
  nsCOMPtr<nsIURI> requestURI;
  nsresult rv = NS_NewURI(getter_AddRefs(requestURI), url,
                          nullptr, nullptr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return FailWithNetworkError();
  }

  // CSP/mixed content checks.
  int16_t shouldLoad;
  rv = NS_CheckContentLoadPolicy(mRequest->ContentPolicyType(),
                                 requestURI,
                                 mPrincipal,
                                 mDocument,
                                 // FIXME(nsm): Should MIME be extracted from
                                 // Content-Type header?
                                 EmptyCString(), /* mime guess */
                                 nullptr, /* extra */
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 nsContentUtils::GetSecurityManager());
  if (NS_WARN_IF(NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad))) {
    // Disallowed by content policy.
    return FailWithNetworkError();
  }

  // Begin Step 4 of the Fetch algorithm
  // https://fetch.spec.whatwg.org/#fetching

  nsAutoCString scheme;
  rv = requestURI->GetScheme(scheme);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return FailWithNetworkError();
  }

  rv = mPrincipal->CheckMayLoad(requestURI, false /* report */, false /* allowIfInheritsPrincipal */);
  if ((!aCORSFlag && NS_SUCCEEDED(rv)) ||
      (scheme.EqualsLiteral("data") && mRequest->SameOriginDataURL()) ||
      scheme.EqualsLiteral("about")) {
    return BasicFetch();
  }

  if (mRequest->Mode() == RequestMode::Same_origin) {
    return FailWithNetworkError();
  }

  if (mRequest->Mode() == RequestMode::No_cors) {
    mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_OPAQUE);
    return BasicFetch();
  }

  if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("https")) {
    return FailWithNetworkError();
  }

  bool corsPreflight = false;
  if (mRequest->Mode() == RequestMode::Cors_with_forced_preflight ||
      (mRequest->UnsafeRequest() && (!mRequest->HasSimpleMethod() || !mRequest->Headers()->HasOnlySimpleHeaders()))) {
    corsPreflight = true;
  }

  mRequest->SetResponseTainting(InternalRequest::RESPONSETAINT_CORS);
  return HttpFetch(true /* aCORSFlag */, corsPreflight);
}
NS_IMETHODIMP
nsXULTemplateQueryProcessorStorage::CompareResults(nsIXULTemplateResult* aLeft,
                                                   nsIXULTemplateResult* aRight,
                                                   nsIAtom* aVar,
                                                   PRUint32 aSortHints,
                                                   PRInt32* aResult)
{
    *aResult = 0;
    if (!aVar)
      return NS_OK;

    // We're going to see if values are integers or float, to perform
    // a suitable comparison
    nsCOMPtr<nsISupports> leftValue, rightValue;
    if (aLeft)
      aLeft->GetBindingObjectFor(aVar, getter_AddRefs(leftValue));
    if (aRight)
      aRight->GetBindingObjectFor(aVar, getter_AddRefs(rightValue));

    if (leftValue && rightValue) {
        nsCOMPtr<nsIVariant> vLeftValue = do_QueryInterface(leftValue);
        nsCOMPtr<nsIVariant> vRightValue = do_QueryInterface(rightValue);

        if (vLeftValue && vRightValue) {
            nsresult rv1, rv2;
            PRUint16 vtypeL, vtypeR;
            vLeftValue->GetDataType(&vtypeL);
            vRightValue->GetDataType(&vtypeR);

            if (vtypeL == vtypeR) {
                if (vtypeL == nsIDataType::VTYPE_INT64) {
                    PRInt64 leftValue, rightValue;
                    rv1 = vLeftValue->GetAsInt64(&leftValue);
                    rv2 = vRightValue->GetAsInt64(&rightValue);
                    if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2)) {
                        if (leftValue > rightValue)
                            *aResult = 1;
                        else if (leftValue < rightValue)
                            *aResult = -1;
                        return NS_OK;
                    }
                }
                else if (vtypeL == nsIDataType::VTYPE_DOUBLE) {
                    double leftValue, rightValue;
                    rv1 = vLeftValue->GetAsDouble(&leftValue);
                    rv2 = vRightValue->GetAsDouble(&rightValue);
                    if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2)) {
                        if (leftValue > rightValue)
                            *aResult = 1;
                        else if (leftValue < rightValue)
                            *aResult = -1;
                        return NS_OK;
                    }
                }
            }
        }
    }

    // Values are not integers or floats, so we just compare them as simple strings
    nsAutoString leftVal;
    if (aLeft)
        aLeft->GetBindingFor(aVar, leftVal);

    nsAutoString rightVal;
    if (aRight)
        aRight->GetBindingFor(aVar, rightVal);

    *aResult = XULSortServiceImpl::CompareValues(leftVal, rightVal, aSortHints);
    return NS_OK;
}
예제 #20
0
void GetInterfaceNameByIID(const GUID &aIID, BSTR *aName)
{
    AssertPtrReturnVoid(aName);
    *aName = NULL;

#if !defined(VBOX_WITH_XPCOM)

    LONG rc;
    LPOLESTR iidStr = NULL;
    if (StringFromIID(aIID, &iidStr) == S_OK)
    {
        HKEY ifaceKey;
        rc = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Interface",
                           0, KEY_QUERY_VALUE, &ifaceKey);
        if (rc == ERROR_SUCCESS)
        {
            HKEY iidKey;
            rc = RegOpenKeyExW(ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey);
            if (rc == ERROR_SUCCESS)
            {
                /* determine the size and type */
                DWORD sz, type;
                rc = RegQueryValueExW(iidKey, NULL, NULL, &type, NULL, &sz);
                if (rc == ERROR_SUCCESS && type == REG_SZ)
                {
                    /* query the value to BSTR */
                    *aName = SysAllocStringLen(NULL, (sz + 1) / sizeof(TCHAR) + 1);
                    rc = RegQueryValueExW(iidKey, NULL, NULL, NULL, (LPBYTE) *aName, &sz);
                    if (rc != ERROR_SUCCESS)
                    {
                        SysFreeString(*aName);
                        *aName = NULL;
                    }
                }
                RegCloseKey(iidKey);
            }
            RegCloseKey(ifaceKey);
        }
        CoTaskMemFree(iidStr);
    }

#else /* !defined (VBOX_WITH_XPCOM) */

    nsresult rv;
    nsCOMPtr<nsIInterfaceInfoManager> iim =
        do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);
    if (NS_SUCCEEDED(rv))
    {
        nsCOMPtr<nsIInterfaceInfo> iinfo;
        rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
        if (NS_SUCCEEDED(rv))
        {
            const char *iname = NULL;
            iinfo->GetNameShared(&iname);
            char *utf8IName = NULL;
            if (RT_SUCCESS(RTStrCurrentCPToUtf8(&utf8IName, iname)))
            {
                PRTUTF16 utf16IName = NULL;
                if (RT_SUCCESS(RTStrToUtf16(utf8IName, &utf16IName)))
                {
                    *aName = SysAllocString((OLECHAR *) utf16IName);
                    RTUtf16Free(utf16IName);
                }
                RTStrFree(utf8IName);
            }
        }
    }

#endif /* !defined (VBOX_WITH_XPCOM) */
}
예제 #21
0
already_AddRefed<IDBOpenDBRequest>
IDBFactory::OpenInternal(nsIPrincipal* aPrincipal,
                         const nsAString& aName,
                         const Optional<uint64_t>& aVersion,
                         const Optional<StorageType>& aStorageType,
                         bool aDeleting,
                         ErrorResult& aRv)
{
  MOZ_ASSERT(mWindow || mOwningObject);
  MOZ_ASSERT_IF(!mWindow, !mPrivateBrowsingMode);

  CommonFactoryRequestParams commonParams;
  commonParams.privateBrowsingMode() = mPrivateBrowsingMode;

  PrincipalInfo& principalInfo = commonParams.principalInfo();

  if (aPrincipal) {
    if (!NS_IsMainThread()) {
      MOZ_CRASH("Figure out security checks for workers!");
    }
    MOZ_ASSERT(nsContentUtils::IsCallerChrome());

    if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(aPrincipal,
                                                      &principalInfo)))) {
      IDB_REPORT_INTERNAL_ERR();
      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
      return nullptr;
    }

    if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
        principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
      IDB_REPORT_INTERNAL_ERR();
      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
      return nullptr;
    }
  } else {
    principalInfo = *mPrincipalInfo;
  }

  uint64_t version = 0;
  if (!aDeleting && aVersion.WasPassed()) {
    if (aVersion.Value() < 1) {
      aRv.ThrowTypeError(MSG_INVALID_VERSION);
      return nullptr;
    }
    version = aVersion.Value();
  }

  // Nothing can be done here if we have previously failed to create a
  // background actor.
  if (mBackgroundActorFailed) {
    IDB_REPORT_INTERNAL_ERR();
    aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
    return nullptr;
  }

  PersistenceType persistenceType;

  if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
    // Chrome privilege always gets persistent storage.
    persistenceType = PERSISTENCE_TYPE_PERSISTENT;
  } else {
    persistenceType = PersistenceTypeFromStorage(aStorageType);
  }

  DatabaseMetadata& metadata = commonParams.metadata();
  metadata.name() = aName;
  metadata.persistenceType() = persistenceType;

  FactoryRequestParams params;
  if (aDeleting) {
    metadata.version() = 0;
    params = DeleteDatabaseRequestParams(commonParams);
  } else {
    metadata.version() = version;
    params = OpenDatabaseRequestParams(commonParams);
  }

  if (!mBackgroundActor && mPendingRequests.IsEmpty()) {
    // We need to start the sequence to create a background actor for this
    // thread.
    BackgroundChildImpl::ThreadLocal* threadLocal =
      BackgroundChildImpl::GetThreadLocalForCurrentThread();

    nsAutoPtr<ThreadLocal> newIDBThreadLocal;
    ThreadLocal* idbThreadLocal;

    if (threadLocal && threadLocal->mIndexedDBThreadLocal) {
      idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
    } else {
      nsCOMPtr<nsIUUIDGenerator> uuidGen =
        do_GetService("@mozilla.org/uuid-generator;1");
      MOZ_ASSERT(uuidGen);

      nsID id;
      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(uuidGen->GenerateUUIDInPlace(&id)));

      newIDBThreadLocal = idbThreadLocal = new ThreadLocal(id);
    }

    nsRefPtr<BackgroundCreateCallback> cb =
      new BackgroundCreateCallback(this, idbThreadLocal->GetLoggingInfo());
    if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(cb))) {
      IDB_REPORT_INTERNAL_ERR();
      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
      return nullptr;
    }

    if (newIDBThreadLocal) {
      if (!threadLocal) {
        threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread();
      }
      MOZ_ASSERT(threadLocal);
      MOZ_ASSERT(!threadLocal->mIndexedDBThreadLocal);

      threadLocal->mIndexedDBThreadLocal = newIDBThreadLocal.forget();
    }
  }

  AutoJSAPI autoJS;
  nsRefPtr<IDBOpenDBRequest> request;

  if (mWindow) {
    AutoJSContext cx;
    if (NS_WARN_IF(!autoJS.Init(mWindow, cx))) {
      IDB_REPORT_INTERNAL_ERR();
      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
      return nullptr;
    }

    JS::Rooted<JSObject*> scriptOwner(cx,
      static_cast<nsGlobalWindow*>(mWindow.get())->FastGetGlobalJSObject());
    MOZ_ASSERT(scriptOwner);

    request = IDBOpenDBRequest::CreateForWindow(this, mWindow, scriptOwner);
  } else {
    autoJS.Init(mOwningObject.get());
    JS::Rooted<JSObject*> scriptOwner(autoJS.cx(), mOwningObject);

    request = IDBOpenDBRequest::CreateForJS(this, scriptOwner);
  }

  MOZ_ASSERT(request);

  if (aDeleting) {
    IDB_LOG_MARK("IndexedDB %s: Child  Request[%llu]: "
                   "indexedDB.deleteDatabase(\"%s\")",
                 "IndexedDB %s: C R[%llu]: IDBFactory.deleteDatabase()",
                 IDB_LOG_ID_STRING(),
                 request->LoggingSerialNumber(),
                 NS_ConvertUTF16toUTF8(aName).get());
  } else {
    IDB_LOG_MARK("IndexedDB %s: Child  Request[%llu]: "
                   "indexedDB.open(\"%s\", %s)",
                 "IndexedDB %s: C R[%llu]: IDBFactory.open()",
                 IDB_LOG_ID_STRING(),
                 request->LoggingSerialNumber(),
                 NS_ConvertUTF16toUTF8(aName).get(),
                 IDB_LOG_STRINGIFY(aVersion));
  }

  // If we already have a background actor then we can start this request now.
  if (mBackgroundActor) {
    nsresult rv = InitiateRequest(request, params);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      IDB_REPORT_INTERNAL_ERR();
      aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
      return nullptr;
    }
  } else {
    mPendingRequests.AppendElement(new PendingRequestInfo(request, params));
  }

  return request.forget();
}
예제 #22
0
NS_IMETHODIMP
nsLocalFile::CreateUnique(uint32_t type, uint32_t attributes)
{
    nsresult rv;
    bool longName;

#ifdef XP_WIN
    nsAutoString pathName, leafName, rootName, suffix;
    rv = GetPath(pathName);
#else
    nsAutoCString pathName, leafName, rootName, suffix; 
    rv = GetNativePath(pathName);
#endif
    if (NS_FAILED(rv))
        return rv;

    longName = (pathName.Length() + kMaxSequenceNumberLength >
                kMaxFilenameLength);
    if (!longName)
    {
        rv = Create(type, attributes);
        if (rv != NS_ERROR_FILE_ALREADY_EXISTS)
            return rv;
    }

#ifdef XP_WIN
    rv = GetLeafName(leafName);
    if (NS_FAILED(rv))
        return rv;

    const int32_t lastDot = leafName.RFindChar(PRUnichar('.'));
#else
    rv = GetNativeLeafName(leafName);
    if (NS_FAILED(rv))
        return rv;

    const int32_t lastDot = leafName.RFindChar('.');
#endif

    if (lastDot == kNotFound)
    {
        rootName = leafName;
    } 
    else
    {
        suffix = Substring(leafName, lastDot);      // include '.'
        rootName = Substring(leafName, 0, lastDot); // strip suffix and dot
    }

    if (longName)
    {
        int32_t maxRootLength = (kMaxFilenameLength -
                                 (pathName.Length() - leafName.Length()) -
                                 suffix.Length() - kMaxSequenceNumberLength);

        // We cannot create an item inside a directory whose name is too long.
        // Also, ensure that at least one character remains after we truncate
        // the root name, as we don't want to end up with an empty leaf name.
        if (maxRootLength < 2)
            return NS_ERROR_FILE_UNRECOGNIZED_PATH;

#ifdef XP_WIN
        // ensure that we don't cut the name in mid-UTF16-character
        rootName.SetLength(NS_IS_LOW_SURROGATE(rootName[maxRootLength]) ?
                           maxRootLength - 1 : maxRootLength);
        SetLeafName(rootName + suffix);
#else
        if (NS_IsNativeUTF8())
        {
            // ensure that we don't cut the name in mid-UTF8-character
            // (assume the name is valid UTF8 to begin with)
            while (UTF8traits::isInSeq(rootName[maxRootLength]))
                --maxRootLength;

            // Another check to avoid ending up with an empty leaf name.
            if (maxRootLength == 0 && suffix.IsEmpty())
                return NS_ERROR_FILE_UNRECOGNIZED_PATH;
        }

        rootName.SetLength(maxRootLength);
        SetNativeLeafName(rootName + suffix);
#endif
        nsresult rv = Create(type, attributes);
        if (rv != NS_ERROR_FILE_ALREADY_EXISTS)
            return rv;
    }

    for (int indx = 1; indx < 10000; indx++)
    {
        // start with "Picture-1.jpg" after "Picture.jpg" exists
#ifdef XP_WIN
        SetLeafName(rootName +
                    NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) +
                    suffix);
#else
        SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix);
#endif
        rv = Create(type, attributes);
        if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS) 
            return rv;
    }
 
    // The disk is full, sort of
    return NS_ERROR_FILE_TOO_BIG;
}
예제 #23
0
static void
AppendErrorTextMismatch(const nsString &host,
                        nsIX509Cert* ix509,
                        nsINSSComponent *component,
                        bool wantsHtml,
                        nsString &returnedMessage)
{
  const char16_t *params[1];
  nsresult rv;

  ScopedCERTCertificate nssCert(ix509->GetCert());

  if (!nssCert) {
    // We are unable to extract the valid names, say "not valid for name".
    params[0] = host.get();
    nsString formattedString;
    rv = component->PIPBundleFormatStringFromName("certErrorMismatch", 
                                                  params, 1, 
                                                  formattedString);
    if (NS_SUCCEEDED(rv)) {
      returnedMessage.Append(formattedString);
      returnedMessage.Append('\n');
    }
    return;
  }

  nsString allNames;
  uint32_t nameCount = 0;
  bool useSAN = false;

  if (nssCert)
    useSAN = GetSubjectAltNames(nssCert.get(), component, allNames, nameCount);

  if (!useSAN) {
    char *certName = CERT_GetCommonName(&nssCert->subject);
    if (certName) {
      nsDependentCSubstring commonName(certName, strlen(certName));
      if (IsUTF8(commonName)) {
        // Bug 1024781
        // We should actually check that the common name is a valid dns name or
        // ip address and not any string value before adding it to the display
        // list.
        ++nameCount;
        allNames.Assign(NS_ConvertUTF8toUTF16(commonName));
      }
      PORT_Free(certName);
    }
  }

  if (nameCount > 1) {
    nsString message;
    rv = component->GetPIPNSSBundleString("certErrorMismatchMultiple", 
                                          message);
    if (NS_SUCCEEDED(rv)) {
      returnedMessage.Append(message);
      returnedMessage.AppendLiteral("\n  ");
      returnedMessage.Append(allNames);
      returnedMessage.AppendLiteral("  \n");
    }
  }
  else if (nameCount == 1) {
    const char16_t *params[1];
    params[0] = allNames.get();
    
    const char *stringID;
    if (wantsHtml)
      stringID = "certErrorMismatchSingle2";
    else
      stringID = "certErrorMismatchSinglePlain";

    nsString formattedString;
    rv = component->PIPBundleFormatStringFromName(stringID, 
                                                  params, 1, 
                                                  formattedString);
    if (NS_SUCCEEDED(rv)) {
      returnedMessage.Append(formattedString);
      returnedMessage.Append('\n');
    }
  }
  else { // nameCount == 0
    nsString message;
    nsresult rv = component->GetPIPNSSBundleString("certErrorMismatchNoNames",
                                                   message);
    if (NS_SUCCEEDED(rv)) {
      returnedMessage.Append(message);
      returnedMessage.Append('\n');
    }
  }
}
예제 #24
0
nsresult
nsAboutCacheEntry::WriteCacheEntryDescription(nsICacheEntryDescriptor *descriptor)
{
    nsresult rv;
    nsCString buffer;
    uint32_t n;

    nsAutoCString str;

    rv = descriptor->GetKey(str);
    if (NS_FAILED(rv)) return rv;

    buffer.SetCapacity(4096);
    buffer.AssignLiteral("<table>\n"
                         "  <tr>\n"
                         "    <th>key:</th>\n"
                         "    <td id=\"td-key\">");

    // Test if the key is actually a URI
    nsCOMPtr<nsIURI> uri;
    bool isJS = false;
    bool isData = false;

    rv = NS_NewURI(getter_AddRefs(uri), str);
    // javascript: and data: URLs should not be linkified
    // since clicking them can cause scripts to run - bug 162584
    if (NS_SUCCEEDED(rv)) {
        uri->SchemeIs("javascript", &isJS);
        uri->SchemeIs("data", &isData);
    }
    char* escapedStr = nsEscapeHTML(str.get());
    if (NS_SUCCEEDED(rv) && !(isJS || isData)) {
        buffer.AppendLiteral("<a href=\"");
        buffer.Append(escapedStr);
        buffer.AppendLiteral("\">");
        buffer.Append(escapedStr);
        buffer.AppendLiteral("</a>");
        uri = 0;
    }
    else
        buffer.Append(escapedStr);
    nsMemory::Free(escapedStr);
    buffer.AppendLiteral("</td>\n"
                         "  </tr>\n");

    // temp vars for reporting
    char timeBuf[255];
    uint32_t u = 0;
    int32_t  i = 0;
    nsAutoCString s;

    // Fetch Count
    s.Truncate();
    descriptor->GetFetchCount(&i);
    s.AppendInt(i);
    APPEND_ROW("fetch count", s);

    // Last Fetched
    descriptor->GetLastFetched(&u);
    if (u) {
        PrintTimeString(timeBuf, sizeof(timeBuf), u);
        APPEND_ROW("last fetched", timeBuf);
    } else {
        APPEND_ROW("last fetched", "No last fetch time");
    }

    // Last Modified
    descriptor->GetLastModified(&u);
    if (u) {
        PrintTimeString(timeBuf, sizeof(timeBuf), u);
        APPEND_ROW("last modified", timeBuf);
    } else {
        APPEND_ROW("last modified", "No last modified time");
    }

    // Expiration Time
    descriptor->GetExpirationTime(&u);
    if (u < 0xFFFFFFFF) {
        PrintTimeString(timeBuf, sizeof(timeBuf), u);
        APPEND_ROW("expires", timeBuf);
    } else {
        APPEND_ROW("expires", "No expiration time");
    }

    // Data Size
    s.Truncate();
    uint32_t dataSize;
    descriptor->GetStorageDataSize(&dataSize);
    s.AppendInt((int32_t)dataSize);     // XXX nsICacheEntryInfo interfaces should be fixed.
    APPEND_ROW("Data size", s);

    // Storage Policy

    // XXX Stream Based?

    // XXX Cache Device
    // File on disk
    nsCOMPtr<nsIFile> cacheFile;
    rv = descriptor->GetFile(getter_AddRefs(cacheFile));
    if (NS_SUCCEEDED(rv)) {
        nsAutoString filePath;
        cacheFile->GetPath(filePath);
        APPEND_ROW("file on disk", NS_ConvertUTF16toUTF8(filePath));
    }
    else
        APPEND_ROW("file on disk", "none");

    // Security Info
    nsCOMPtr<nsISupports> securityInfo;
    descriptor->GetSecurityInfo(getter_AddRefs(securityInfo));
    if (securityInfo) {
        APPEND_ROW("Security", "This is a secure document.");
    } else {
        APPEND_ROW("Security",
                   "This document does not have any security info associated with it.");
    }

    buffer.AppendLiteral("</table>\n"
                         "<hr/>\n"
                         "<table>\n");
    // Meta Data
    // let's just look for some well known (HTTP) meta data tags, for now.

    // Client ID
    nsXPIDLCString str2;
    descriptor->GetClientID(getter_Copies(str2));
    if (!str2.IsEmpty())  APPEND_ROW("Client", str2);


    mBuffer = &buffer;  // make it available for VisitMetaDataElement().
    // nsCacheEntryDescriptor::VisitMetaData calls
    // nsCacheEntry.h VisitMetaDataElements, which returns
    // nsCacheMetaData::VisitElements, which calls
    // nsAboutCacheEntry::VisitMetaDataElement (below) in a loop.
    descriptor->VisitMetaData(this);
    mBuffer = nullptr;

    buffer.AppendLiteral("</table>\n");
    mOutputStream->Write(buffer.get(), buffer.Length(), &n);

    buffer.Truncate();

    // Provide a hexdump of the data
    if (dataSize) { // don't draw an <hr> if the Data Size is 0.
        nsCOMPtr<nsIInputStream> stream;
        descriptor->OpenInputStream(0, getter_AddRefs(stream));
        if (stream) {
            buffer.AssignLiteral("<hr/>\n"
                                 "<pre>");
            uint32_t hexDumpState = 0;
            char chunk[4096];
            while(NS_SUCCEEDED(stream->Read(chunk, sizeof(chunk), &n)) && 
                  n > 0) {
                HexDump(&hexDumpState, chunk, n, buffer);
                mOutputStream->Write(buffer.get(), buffer.Length(), &n);
                buffer.Truncate();
            }
            buffer.AssignLiteral("</pre>\n");
            mOutputStream->Write(buffer.get(), buffer.Length(), &n);
      }
    }
    return NS_OK;
}
예제 #25
0
NS_IMETHODIMP
nsDOMDataTransfer::MozGetDataAt(const nsAString& aFormat,
                                PRUint32 aIndex,
                                nsIVariant** aData)
{
  *aData = nsnull;

  if (aFormat.IsEmpty())
    return NS_OK;

  if (aIndex >= mItems.Length())
    return NS_ERROR_DOM_INDEX_SIZE_ERR;

  nsAutoString format;
  GetRealFormat(aFormat, format);

  nsTArray<TransferItem>& item = mItems[aIndex];

  // allow access to any data in the drop and dragdrop events, or if the
  // UniversalBrowserRead privilege is set, otherwise only allow access to
  // data from the same principal.
  nsIPrincipal* principal = nsnull;
  if (mEventType != NS_DRAGDROP_DROP && mEventType != NS_DRAGDROP_DRAGDROP &&
      !nsContentUtils::IsCallerTrustedForCapability("UniversalBrowserRead")) {
    nsresult rv = NS_OK;
    principal = GetCurrentPrincipal(&rv);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  PRUint32 count = item.Length();
  for (PRUint32 i = 0; i < count; i++) {
    TransferItem& formatitem = item[i];
    if (formatitem.mFormat.Equals(format)) {
      PRBool subsumes;
      if (formatitem.mPrincipal && principal &&
          (NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || !subsumes))
        return NS_ERROR_DOM_SECURITY_ERR;

      if (!formatitem.mData) {
        FillInExternalDragData(formatitem, aIndex);
      } else {
        nsCOMPtr<nsISupports> data;
        formatitem.mData->GetAsISupports(getter_AddRefs(data));
        // Make sure the code that is calling us is same-origin with the data.
        nsCOMPtr<nsIDOMEventTarget> pt = do_QueryInterface(data);
        if (pt) {
          nsresult rv = NS_OK;
          nsIScriptContext* c = pt->GetContextForEventHandlers(&rv);
          NS_ENSURE_TRUE(c && NS_SUCCEEDED(rv), NS_ERROR_DOM_SECURITY_ERR);
          nsIScriptObjectPrincipal* sp = c->GetObjectPrincipal();
          NS_ENSURE_TRUE(sp, NS_ERROR_DOM_SECURITY_ERR);
          nsIPrincipal* dataPrincipal = sp->GetPrincipal();
          NS_ENSURE_TRUE(dataPrincipal, NS_ERROR_DOM_SECURITY_ERR);
          NS_ENSURE_TRUE(principal || (principal = GetCurrentPrincipal(&rv)),
                         NS_ERROR_DOM_SECURITY_ERR);
          NS_ENSURE_SUCCESS(rv, rv);
          PRBool equals = PR_FALSE;
          NS_ENSURE_TRUE(NS_SUCCEEDED(principal->Equals(dataPrincipal, &equals)) && equals,
                         NS_ERROR_DOM_SECURITY_ERR);
        }
      }
      *aData = formatitem.mData;
      NS_IF_ADDREF(*aData);
      return NS_OK;
    }
  }

  return NS_OK;
}
nsresult nsMsgQuickSearchDBView::GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result)
{
  uint32_t numChildren;
  nsresult rv = NS_OK;
  uint8_t minLevel = 0xff;
  threadHdr->GetNumChildren(&numChildren);
  nsMsgKey threadRootKey;
  nsCOMPtr<nsIMsgDBHdr> rootParent;
  int32_t rootIndex;
  threadHdr->GetRootHdr(&rootIndex, getter_AddRefs(rootParent));
  if (rootParent)
    rootParent->GetMessageKey(&threadRootKey);
  else
    threadHdr->GetThreadKey(&threadRootKey);

  if ((int32_t) numChildren < 0)
    numChildren = 0;

  nsCOMPtr <nsIMsgDBHdr> retHdr;

  // iterate over thread, finding mgsHdr in view with the lowest level.
  for (uint32_t childIndex = 0; childIndex < numChildren; childIndex++)
  {
    nsCOMPtr <nsIMsgDBHdr> child;
    rv = threadHdr->GetChildHdrAt(childIndex, getter_AddRefs(child));
    if (NS_SUCCEEDED(rv) && child)
    {
      nsMsgKey msgKey;
      child->GetMessageKey(&msgKey);

      // this works because we've already sorted m_keys by id.
      nsMsgViewIndex keyIndex = m_origKeys.BinaryIndexOf(msgKey);
      if (keyIndex != nsMsgViewIndex_None)
      {
        // this is the root, so it's the best we're going to do.
        if (msgKey == threadRootKey)
        {
          retHdr = child;
          break;
        }
        uint8_t level = 0;
        nsMsgKey parentId;
        child->GetThreadParent(&parentId);
        nsCOMPtr <nsIMsgDBHdr> parent;
        // count number of ancestors - that's our level
        while (parentId != nsMsgKey_None)
        {
          rv = m_db->GetMsgHdrForKey(parentId, getter_AddRefs(parent));
          if (parent)
          {
            nsMsgKey saveParentId = parentId;
            parent->GetThreadParent(&parentId);
            // message is it's own parent - bad, let's break out of here.
            // Or we've got some circular ancestry.
            if (parentId == saveParentId || level > numChildren)
              break;
            level++;
          }
          else // if we can't find the parent, don't loop forever.
            break;
        }
        if (level < minLevel)
        {
          minLevel = level;
          retHdr = child;
        }
      }
    }
  }
  NS_IF_ADDREF(*result = retHdr);
  return NS_OK; 
}
예제 #27
0
NS_IMETHODIMP
nsXMLDocument::Load(const nsAString& aUrl, bool *aReturn)
{
  bool hasHadScriptObject = true;
  nsIScriptGlobalObject* scriptObject =
    GetScriptHandlingObject(hasHadScriptObject);
  NS_ENSURE_STATE(scriptObject || !hasHadScriptObject);

  ReportUseOfDeprecatedMethod(this, "UseOfDOM3LoadMethodWarning");

  NS_ENSURE_ARG_POINTER(aReturn);
  *aReturn = false;

  nsCOMPtr<nsIDocument> callingDoc =
    do_QueryInterface(nsContentUtils::GetDocumentFromContext());

  nsIURI *baseURI = mDocumentURI;
  nsCAutoString charset;

  if (callingDoc) {
    baseURI = callingDoc->GetDocBaseURI();
    charset = callingDoc->GetDocumentCharacterSet();
  }

  // Create a new URI
  nsCOMPtr<nsIURI> uri;
  nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Check to see whether the current document is allowed to load this URI.
  // It's important to use the current document's principal for this check so
  // that we don't end up in a case where code with elevated privileges is
  // calling us and changing the principal of this document.

  // Enforce same-origin even for chrome loaders to avoid someone accidentally
  // using a document that content has a reference to and turn that into a
  // chrome document.
  nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
  if (!nsContentUtils::IsSystemPrincipal(principal)) {
    rv = principal->CheckMayLoad(uri, false);
    NS_ENSURE_SUCCESS(rv, rv);

    PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XMLHTTPREQUEST,
                                   uri,
                                   principal,
                                   callingDoc ? callingDoc.get() :
                                     static_cast<nsIDocument*>(this),
                                   NS_LITERAL_CSTRING("application/xml"),
                                   nullptr,
                                   &shouldLoad,
                                   nsContentUtils::GetContentPolicy(),
                                   nsContentUtils::GetSecurityManager());
    NS_ENSURE_SUCCESS(rv, rv);
    if (NS_CP_REJECTED(shouldLoad)) {
      return NS_ERROR_CONTENT_BLOCKED;
    }
  } else {
    // We're called from chrome, check to make sure the URI we're
    // about to load is also chrome.

    bool isChrome = false;
    if (NS_FAILED(uri->SchemeIs("chrome", &isChrome)) || !isChrome) {
      nsCAutoString spec;
      if (mDocumentURI)
        mDocumentURI->GetSpec(spec);

      nsAutoString error;
      error.AssignLiteral("Cross site loading using document.load is no "
                          "longer supported. Use XMLHttpRequest instead.");
      nsCOMPtr<nsIScriptError> errorObject =
          do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
      NS_ENSURE_SUCCESS(rv, rv);

      rv = errorObject->InitWithWindowID(error.get(), NS_ConvertUTF8toUTF16(spec).get(),
                                         nullptr, 0, 0, nsIScriptError::warningFlag,
                                         "DOM",
                                         callingDoc ?
                                           callingDoc->InnerWindowID() :
                                           this->InnerWindowID());

      NS_ENSURE_SUCCESS(rv, rv);

      nsCOMPtr<nsIConsoleService> consoleService =
        do_GetService(NS_CONSOLESERVICE_CONTRACTID);
      if (consoleService) {
        consoleService->LogMessage(errorObject);
      }

      return NS_ERROR_DOM_SECURITY_ERR;
    }
  }

  // Partial Reset, need to restore principal for security reasons and
  // event listener manager so that load listeners etc. will
  // remain. This should be done before the security check is done to
  // ensure that the document is reset even if the new document can't
  // be loaded.  Note that we need to hold a strong ref to |principal|
  // here, because ResetToURI will null out our node principal before
  // setting the new one.
  nsRefPtr<nsEventListenerManager> elm(mListenerManager);
  mListenerManager = nullptr;

  // When we are called from JS we can find the load group for the page,
  // and add ourselves to it. This way any pending requests
  // will be automatically aborted if the user leaves the page.

  nsCOMPtr<nsILoadGroup> loadGroup;
  if (callingDoc) {
    loadGroup = callingDoc->GetDocumentLoadGroup();
  }

  ResetToURI(uri, loadGroup, principal);

  mListenerManager = elm;

  // Create a channel
  nsCOMPtr<nsIInterfaceRequestor> req = nsContentUtils::GetSameOriginChecker();
  NS_ENSURE_TRUE(req, NS_ERROR_OUT_OF_MEMORY);  

  nsCOMPtr<nsIChannel> channel;
  // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active,
  // which in turn keeps STOP button from becoming active  
  rv = NS_NewChannel(getter_AddRefs(channel), uri, nullptr, loadGroup, req, 
                     nsIRequest::LOAD_BACKGROUND);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // StartDocumentLoad asserts that readyState is uninitialized, so
  // uninitialize it. SetReadyStateInternal make this transition invisible to
  // Web content. But before doing that, assert that the current readyState
  // is complete as it should be after the call to ResetToURI() above.
  MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE,
             "Bad readyState");
  SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED);

  // Prepare for loading the XML document "into oneself"
  nsCOMPtr<nsIStreamListener> listener;
  if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel, 
                                       loadGroup, nullptr, 
                                       getter_AddRefs(listener),
                                       false))) {
    NS_ERROR("nsXMLDocument::Load: Failed to start the document load.");
    return rv;
  }

  // After this point, if we error out of this method we should clear
  // mChannelIsPending.

  // Start an asynchronous read of the XML document
  rv = channel->AsyncOpen(listener, nullptr);
  if (NS_FAILED(rv)) {
    mChannelIsPending = false;
    return rv;
  }

  if (!mAsync) {
    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();

    nsAutoSyncOperation sync(this);
    mLoopingForSyncLoad = true;
    while (mLoopingForSyncLoad) {
      if (!NS_ProcessNextEvent(thread))
        break;
    }

    // We set return to true unless there was a parsing error
    nsCOMPtr<nsIDOMNode> node = do_QueryInterface(GetRootElement());
    if (node) {
      nsAutoString name, ns;      
      if (NS_SUCCEEDED(node->GetLocalName(name)) &&
          name.EqualsLiteral("parsererror") &&
          NS_SUCCEEDED(node->GetNamespaceURI(ns)) &&
          ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) {
        //return is already false
      } else {
        *aReturn = true;
      }
    }
  } else {
    *aReturn = true;
  }

  return NS_OK;
}
예제 #28
0
nsresult
nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
                     void* aKey,
                     const nsACString& aContentType,
                     bool aLastCall,
                     nsDTDMode aMode) // ignored
{
  nsresult rv;
  if (NS_FAILED(rv = mExecutor->IsBroken())) {
    return rv;
  }
  if (aSourceBuffer.Length() > INT32_MAX) {
    return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
  }

  // Maintain a reference to ourselves so we don't go away
  // till we're completely done. The old parser grips itself in this method.
  nsCOMPtr<nsIParser> kungFuDeathGrip(this);
  
  // Gripping the other objects just in case, since the other old grip
  // required grips to these, too.
  RefPtr<nsHtml5StreamParser> streamKungFuDeathGrip(GetStreamParser());
  mozilla::Unused << streamKungFuDeathGrip;
  RefPtr<nsHtml5TreeOpExecutor> treeOpKungFuDeathGrip(mExecutor);

  if (!treeOpKungFuDeathGrip->HasStarted()) {
    NS_ASSERTION(!GetStreamParser(),
                 "Had stream parser but document.write started life cycle.");
    // This is the first document.write() on a document.open()ed document
    treeOpKungFuDeathGrip->SetParser(this);
    mTreeBuilder->setScriptingEnabled(treeOpKungFuDeathGrip->IsScriptEnabled());

    bool isSrcdoc = false;
    nsCOMPtr<nsIChannel> channel;
    rv = GetChannel(getter_AddRefs(channel));
    if (NS_SUCCEEDED(rv)) {
      isSrcdoc = NS_IsSrcdocChannel(channel);
    }
    mTreeBuilder->setIsSrcdocDocument(isSrcdoc);

    mTokenizer->start();
    treeOpKungFuDeathGrip->Start();
    if (!aContentType.EqualsLiteral("text/html")) {
      mTreeBuilder->StartPlainText();
      mTokenizer->StartPlainText();
    }
    /*
     * If you move the following line, be very careful not to cause 
     * WillBuildModel to be called before the document has had its 
     * script global object set.
     */
    rv = treeOpKungFuDeathGrip->WillBuildModel(eDTDMode_unknown);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Return early if the parser has processed EOF
  if (treeOpKungFuDeathGrip->IsComplete()) {
    return NS_OK;
  }

  if (aLastCall && aSourceBuffer.IsEmpty() && !aKey) {
    // document.close()
    NS_ASSERTION(!GetStreamParser(),
                 "Had stream parser but got document.close().");
    if (mDocumentClosed) {
      // already closed
      return NS_OK;
    }
    mDocumentClosed = true;
    if (!mBlocked && !mInDocumentWrite) {
      return ParseUntilBlocked();
    }
    return NS_OK;
  }

  // If we got this far, we are dealing with a document.write or
  // document.writeln call--not document.close().

  NS_ASSERTION(IsInsertionPointDefined(),
               "Doc.write reached parser with undefined insertion point.");

  NS_ASSERTION(!(GetStreamParser() && !aKey),
               "Got a null key in a non-script-created parser");

  // XXX is this optimization bogus?
  if (aSourceBuffer.IsEmpty()) {
    return NS_OK;
  }

  // This guard is here to prevent document.close from tokenizing synchronously
  // while a document.write (that wrote the script that called document.close!)
  // is still on the call stack.
  mozilla::AutoRestore<bool> guard(mInDocumentWrite);
  mInDocumentWrite = true;

  // The script is identified by aKey. If there's nothing in the buffer
  // chain for that key, we'll insert at the head of the queue.
  // When the script leaves something in the queue, a zero-length
  // key-holder "buffer" is inserted in the queue. If the same script
  // leaves something in the chain again, it will be inserted immediately
  // before the old key holder belonging to the same script.
  //
  // We don't do the actual data insertion yet in the hope that the data gets
  // tokenized and there no data or less data to copy to the heap after
  // tokenization. Also, this way, we avoid inserting one empty data buffer
  // per document.write, which matters for performance when the parser isn't
  // blocked and a badly-authored script calls document.write() once per
  // input character. (As seen in a benchmark!)
  //
  // The insertion into the input stream happens conceptually before anything
  // gets tokenized. To make sure multi-level document.write works right,
  // it's necessary to establish the location of our parser key up front
  // in case this is the first write with this key.
  //
  // In a document.open() case, the first write level has a null key, so that
  // case is handled separately, because normal buffers containing data
  // have null keys.

  // These don't need to be owning references, because they always point to
  // the buffer queue and buffers can't be removed from the buffer queue
  // before document.write() returns. The buffer queue clean-up happens the
  // next time ParseUntilBlocked() is called.
  // However, they are made owning just in case the reasoning above is flawed
  // and a flaw would lead to worse problems with plain pointers. If this
  // turns out to be a perf problem, it's worthwhile to consider making
  // prevSearchbuf a plain pointer again.
  RefPtr<nsHtml5OwningUTF16Buffer> prevSearchBuf;
  RefPtr<nsHtml5OwningUTF16Buffer> firstLevelMarker;

  if (aKey) {
    if (mFirstBuffer == mLastBuffer) {
      nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey);
      keyHolder->next = mLastBuffer;
      mFirstBuffer = keyHolder;
    } else if (mFirstBuffer->key != aKey) {
      prevSearchBuf = mFirstBuffer;
      for (;;) {
        if (prevSearchBuf->next == mLastBuffer) {
          // key was not found
          nsHtml5OwningUTF16Buffer* keyHolder =
            new nsHtml5OwningUTF16Buffer(aKey);
          keyHolder->next = mFirstBuffer;
          mFirstBuffer = keyHolder;
          prevSearchBuf = nullptr;
          break;
        }
        if (prevSearchBuf->next->key == aKey) {
          // found a key holder
          break;
        }
        prevSearchBuf = prevSearchBuf->next;
      }
    } // else mFirstBuffer is the keyholder

    // prevSearchBuf is the previous buffer before the keyholder or null if
    // there isn't one.
  } else {
    // We have a first-level write in the document.open() case. We insert before
    // mLastBuffer, effectively, by making mLastBuffer be a new sentinel object
    // and redesignating the previous mLastBuffer as our firstLevelMarker.  We
    // need to put a marker there, because otherwise additional document.writes
    // from nested event loops would insert in the wrong place. Sigh.
    mLastBuffer->next = new nsHtml5OwningUTF16Buffer((void*)nullptr);
    firstLevelMarker = mLastBuffer;
    mLastBuffer = mLastBuffer->next;
  }

  nsHtml5DependentUTF16Buffer stackBuffer(aSourceBuffer);

  while (!mBlocked && stackBuffer.hasMore()) {
    stackBuffer.adjust(mLastWasCR);
    mLastWasCR = false;
    if (stackBuffer.hasMore()) {
      int32_t lineNumberSave;
      bool inRootContext = (!GetStreamParser() && !aKey);
      if (inRootContext) {
        mTokenizer->setLineNumber(mRootContextLineNumber);
      } else {
        // we aren't the root context, so save the line number on the
        // *stack* so that we can restore it.
        lineNumberSave = mTokenizer->getLineNumber();
      }

      if (!mTokenizer->EnsureBufferSpace(stackBuffer.getLength())) {
        return treeOpKungFuDeathGrip->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
      }
      mLastWasCR = mTokenizer->tokenizeBuffer(&stackBuffer);
      if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
        return treeOpKungFuDeathGrip->MarkAsBroken(rv);
      }

      if (inRootContext) {
        mRootContextLineNumber = mTokenizer->getLineNumber();
      } else {
        mTokenizer->setLineNumber(lineNumberSave);
      }

      if (mTreeBuilder->HasScript()) {
        mTreeBuilder->Flush(); // Move ops to the executor
        rv = treeOpKungFuDeathGrip->FlushDocumentWrite(); // run the ops
        NS_ENSURE_SUCCESS(rv, rv);
        // Flushing tree ops can cause all sorts of things.
        // Return early if the parser got terminated.
        if (treeOpKungFuDeathGrip->IsComplete()) {
          return NS_OK;
        }
      }
      // Ignore suspension requests
    }
  }

  RefPtr<nsHtml5OwningUTF16Buffer> heapBuffer;
  if (stackBuffer.hasMore()) {
    // The buffer wasn't tokenized to completion. Create a copy of the tail
    // on the heap.
    heapBuffer = stackBuffer.FalliblyCopyAsOwningBuffer();
    if (!heapBuffer) {
      // Allocation failed. The parser is now broken.
      return treeOpKungFuDeathGrip->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
    }
  }

  if (heapBuffer) {
    // We have something to insert before the keyholder holding in the non-null
    // aKey case and we have something to swap into firstLevelMarker in the
    // null aKey case.
    if (aKey) {
      NS_ASSERTION(mFirstBuffer != mLastBuffer,
        "Where's the keyholder?");
      // the key holder is still somewhere further down the list from
      // prevSearchBuf (which may be null)
      if (mFirstBuffer->key == aKey) {
        NS_ASSERTION(!prevSearchBuf,
          "Non-null prevSearchBuf when mFirstBuffer is the key holder?");
        heapBuffer->next = mFirstBuffer;
        mFirstBuffer = heapBuffer;
      } else {
        if (!prevSearchBuf) {
          prevSearchBuf = mFirstBuffer;
        }
        // We created a key holder earlier, so we will find it without walking
        // past the end of the list.
        while (prevSearchBuf->next->key != aKey) {
          prevSearchBuf = prevSearchBuf->next;
        }
        heapBuffer->next = prevSearchBuf->next;
        prevSearchBuf->next = heapBuffer;
      }
    } else {
      NS_ASSERTION(firstLevelMarker, "How come we don't have a marker.");
      firstLevelMarker->Swap(heapBuffer);
    }
  }

  if (!mBlocked) { // buffer was tokenized to completion
    NS_ASSERTION(!stackBuffer.hasMore(),
      "Buffer wasn't tokenized to completion?");
    // Scripting semantics require a forced tree builder flush here
    mTreeBuilder->Flush(); // Move ops to the executor
    rv = treeOpKungFuDeathGrip->FlushDocumentWrite(); // run the ops
    NS_ENSURE_SUCCESS(rv, rv);
  } else if (stackBuffer.hasMore()) {
    // The buffer wasn't tokenized to completion. Tokenize the untokenized
    // content in order to preload stuff. This content will be retokenized
    // later for normal parsing.
    if (!mDocWriteSpeculatorActive) {
      mDocWriteSpeculatorActive = true;
      if (!mDocWriteSpeculativeTreeBuilder) {
        // Lazily initialize if uninitialized
        mDocWriteSpeculativeTreeBuilder =
            new nsHtml5TreeBuilder(nullptr, treeOpKungFuDeathGrip->GetStage());
        mDocWriteSpeculativeTreeBuilder->setScriptingEnabled(
            mTreeBuilder->isScriptingEnabled());
        mDocWriteSpeculativeTokenizer =
            new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder, false);
        mDocWriteSpeculativeTokenizer->setInterner(&mAtomTable);
        mDocWriteSpeculativeTokenizer->start();
      }
      mDocWriteSpeculativeTokenizer->resetToDataState();
      mDocWriteSpeculativeTreeBuilder->loadState(mTreeBuilder, &mAtomTable);
      mDocWriteSpeculativeLastWasCR = false;
    }

    // Note that with multilevel document.write if we didn't just activate the
    // speculator, it's possible that the speculator is now in the wrong state.
    // That's OK for the sake of simplicity. The worst that can happen is
    // that the speculative loads aren't exactly right. The content will be
    // reparsed anyway for non-preload purposes.

    // The buffer position for subsequent non-speculative parsing now lives
    // in heapBuffer, so it's ok to let the buffer position of stackBuffer
    // to be overwritten and not restored below.
    while (stackBuffer.hasMore()) {
      stackBuffer.adjust(mDocWriteSpeculativeLastWasCR);
      if (stackBuffer.hasMore()) {
        if (!mDocWriteSpeculativeTokenizer->EnsureBufferSpace(
            stackBuffer.getLength())) {
          return treeOpKungFuDeathGrip->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
        }
        mDocWriteSpeculativeLastWasCR =
            mDocWriteSpeculativeTokenizer->tokenizeBuffer(&stackBuffer);
        nsresult rv;
        if (NS_FAILED((rv = mDocWriteSpeculativeTreeBuilder->IsBroken()))) {
          return treeOpKungFuDeathGrip->MarkAsBroken(rv);
        }
      }
    }

    mDocWriteSpeculativeTreeBuilder->Flush();
    mDocWriteSpeculativeTreeBuilder->DropHandles();
    treeOpKungFuDeathGrip->FlushSpeculativeLoads();
  }

  return NS_OK;
}
예제 #29
0
nsresult
nsDirIndexParser::ParseData(nsIDirIndex *aIdx, char* aDataStr) {
  // Parse a "201" data line, using the field ordering specified in
  // mFormat.

  if (!mFormat) {
    // Ignore if we haven't seen a format yet.
    return NS_OK;
  }

  nsresult rv = NS_OK;

  nsCAutoString filename;

  for (PRInt32 i = 0; mFormat[i] != -1; ++i) {
    // If we've exhausted the data before we run out of fields, just
    // bail.
    if (! *aDataStr)
      break;

    while (*aDataStr && nsCRT::IsAsciiSpace(*aDataStr))
      ++aDataStr;

    char    *value = aDataStr;

    if (*aDataStr == '"' || *aDataStr == '\'') {
      // it's a quoted string. snarf everything up to the next quote character
      const char quotechar = *(aDataStr++);
      ++value;
      while (*aDataStr && *aDataStr != quotechar)
        ++aDataStr;
      *aDataStr++ = '\0';

      if (! aDataStr) {
        NS_WARNING("quoted value not terminated");
      }
    } else {
      // it's unquoted. snarf until we see whitespace.
      value = aDataStr;
      while (*aDataStr && (!nsCRT::IsAsciiSpace(*aDataStr)))
        ++aDataStr;
      *aDataStr++ = '\0';
    }

    fieldType t = fieldType(mFormat[i]);
    switch (t) {
    case FIELD_FILENAME: {
      // don't unescape at this point, so that UnEscapeAndConvert() can
      filename = value;
      
      PRBool  success = PR_FALSE;
      
      nsAutoString entryuri;
      
      if (gTextToSubURI) {
        PRUnichar   *result = nsnull;
        if (NS_SUCCEEDED(rv = gTextToSubURI->UnEscapeAndConvert(mEncoding.get(), filename.get(),
                                                                &result)) && (result)) {
          if (*result) {
            aIdx->SetLocation(filename.get());
            if (!mHasDescription)
              aIdx->SetDescription(result);
            success = PR_TRUE;
          }
          NS_Free(result);
        } else {
          NS_WARNING("UnEscapeAndConvert error");
        }
      }
      
      if (!success) {
        // if unsuccessfully at charset conversion, then
        // just fallback to unescape'ing in-place
        // XXX - this shouldn't be using UTF8, should it?
        // when can we fail to get the service, anyway? - bbaetz
        aIdx->SetLocation(filename.get());
        if (!mHasDescription) {
          aIdx->SetDescription(NS_ConvertUTF8toUTF16(value).get());
        }
      }
    }
      break;
    case FIELD_DESCRIPTION:
      nsUnescape(value);
      aIdx->SetDescription(NS_ConvertUTF8toUTF16(value).get());
      break;
    case FIELD_CONTENTLENGTH:
      {
        PRInt64 len;
        PRInt32 status = PR_sscanf(value, "%lld", &len);
        if (status == 1)
          aIdx->SetSize(len);
        else
          aIdx->SetSize(LL_MAXUINT); // LL_MAXUINT means unknown
      }
      break;
    case FIELD_LASTMODIFIED:
      {
        PRTime tm;
        nsUnescape(value);
        if (PR_ParseTimeString(value, PR_FALSE, &tm) == PR_SUCCESS) {
          aIdx->SetLastModified(tm);
        }
      }
      break;
    case FIELD_CONTENTTYPE:
      aIdx->SetContentType(value);
      break;
    case FIELD_FILETYPE:
      // unescape in-place
      nsUnescape(value);
      if (!nsCRT::strcasecmp(value, "directory")) {
        aIdx->SetType(nsIDirIndex::TYPE_DIRECTORY);
      } else if (!nsCRT::strcasecmp(value, "file")) {
        aIdx->SetType(nsIDirIndex::TYPE_FILE);
      } else if (!nsCRT::strcasecmp(value, "symbolic-link")) {
        aIdx->SetType(nsIDirIndex::TYPE_SYMLINK);
      } else {
        aIdx->SetType(nsIDirIndex::TYPE_UNKNOWN);
      }
      break;
    case FIELD_UNKNOWN:
      // ignore
      break;
    }
  }

  return NS_OK;
}
예제 #30
0
int
MimeHeaders_write_all_headers (MimeHeaders *hdrs, MimeDisplayOptions *opt, bool attachment)
{
  int status = 0;
  int i;
  bool wrote_any_p = false;

  NS_ASSERTION(hdrs, "1.1 <*****@*****.**> 19 Mar 1999 12:00");
  if (!hdrs)
    return -1;

  /* One shouldn't be trying to read headers when one hasn't finished
     parsing them yet... but this can happen if the message ended
     prematurely, and has no body at all (as opposed to a null body,
     which is more normal.)   So, if we try to read from the headers,
     let's assume that the headers are now finished.  If they aren't
     in fact finished, then a later attempt to write to them will assert.
   */
  if (!hdrs->done_p)
  {
    hdrs->done_p = true;
    status = MimeHeaders_build_heads_list(hdrs);
    if (status < 0) return 0;
  }

  char *charset = nsnull;
  if (opt->format_out == nsMimeOutput::nsMimeMessageSaveAs)
  {
    if (opt->override_charset)
      charset = PL_strdup(opt->default_charset);
    else
    {
      char *contentType = MimeHeaders_get(hdrs, HEADER_CONTENT_TYPE, false, false);
      if (contentType)
        charset = MimeHeaders_get_parameter(contentType, HEADER_PARM_CHARSET, nsnull, nsnull);
      PR_FREEIF(contentType);
    }
  }

  for (i = 0; i < hdrs->heads_size; i++)
  {
    char *head = hdrs->heads[i];
    char *end = (i == hdrs->heads_size-1
                      ? hdrs->all_headers + hdrs->all_headers_fp
                      : hdrs->heads[i+1]);
    char *colon, *ocolon;
    char *contents = end;

    /* Hack for BSD Mailbox delimiter. */
    if (i == 0 && head[0] == 'F' && !strncmp(head, "From ", 5))
    {
      /* For now, we don't really want this header to be output so
         we are going to just continue */
      continue;
      /* colon = head + 4; contents = colon + 1; */
    }
    else
    {
      /* Find the colon. */
      for (colon = head; colon < end && *colon != ':'; colon++)
        ;

        /* Back up over whitespace before the colon. */
        ocolon = colon;
        for (; colon > head && IS_SPACE(colon[-1]); colon--)
          ;

        contents = ocolon + 1;
    }

    /* Skip over whitespace after colon. */
    while (contents < end && IS_SPACE(*contents))
      contents++;

    /* Take off trailing whitespace... */
    while (end > contents && IS_SPACE(end[-1]))
      end--;

    nsCAutoString name(Substring(head, colon));
    nsCAutoString hdr_value;

    if ( (end - contents) > 0 )
    {
      hdr_value = Substring(contents, end);
    }

    // MW Fixme: more?
    bool convert_charset_only =
          MsgLowerCaseEqualsLiteral(name, "to") || MsgLowerCaseEqualsLiteral(name, "from") ||
          MsgLowerCaseEqualsLiteral(name, "cc") || MsgLowerCaseEqualsLiteral(name, "bcc") ||
          MsgLowerCaseEqualsLiteral(name, "reply-to") || MsgLowerCaseEqualsLiteral(name, "sender");
    MimeHeaders_convert_header_value(opt, hdr_value, convert_charset_only);
    // if we're saving as html, we need to convert headers from utf8 to message charset, if any
    if (opt->format_out == nsMimeOutput::nsMimeMessageSaveAs && charset)
    {
      nsCAutoString convertedStr;
      if (NS_SUCCEEDED(ConvertFromUnicode(charset, NS_ConvertUTF8toUTF16(hdr_value),
                       convertedStr)))
      {
        hdr_value = convertedStr;
      }
    }

    if (attachment)
      status = mimeEmitterAddAttachmentField(opt, name.get(), hdr_value.get());
    else
      status = mimeEmitterAddHeaderField(opt, name.get(), hdr_value.get());

    if (status < 0) return status;
    if (!wrote_any_p)
      wrote_any_p = (status > 0);
  }
  mimeEmitterAddAllHeaders(opt, hdrs->all_headers, hdrs->all_headers_fp);
  PR_FREEIF(charset);

  return 1;
}