static void
MorkUnescape(const nsCSubstring &aString, nsCString &aResult)
{
    PRUint32 len = aString.Length();

    // We optimize for speed over space here -- size the result buffer to
    // the size of the source, which is an upper bound on the size of the
    // unescaped string.
    // FIXME: Mork assume there will never be errors
    if (!EnsureStringLength(aResult, len)) {
        aResult.Truncate();
        return; // out of memory.
    }

    char *result = aResult.BeginWriting();
    const char *source = aString.BeginReading();
    const char *sourceEnd = source + len;

    const char *startPos = nsnull;
    PRUint32 bytes;
    for (; source < sourceEnd; ++source) {
        char c = *source;
        if (c == '\\') {
            if (startPos) {
                bytes = source - startPos;
                memcpy(result, startPos, bytes);
                result += bytes;
                startPos = nsnull;
            }
            if (source < sourceEnd - 1) {
                *(result++) = *(++source);
            }
        } else if (c == '$') {
            if (startPos) {
                bytes = source - startPos;
                memcpy(result, startPos, bytes);
                result += bytes;
                startPos = nsnull;
            }
            if (source < sourceEnd - 2) {
                // Would be nice to use ToInteger() here, but it currently
                // requires a null-terminated string.
                char c2 = *(++source);
                char c3 = *(++source);
                if (ConvertChar(&c2) && ConvertChar(&c3)) {
                    *(result++) = ((c2 << 4) | c3);
                }
            }
        } else if (!startPos) {
            startPos = source;
        }
    }
    if (startPos) {
        bytes = source - startPos;
        memcpy(result, startPos, bytes);
        result += bytes;
    }
    aResult.SetLength(result - aResult.BeginReading());
}
bool
DocumentRendererChild::RenderDocument(nsPIDOMWindowOuter* window,
                                      const nsRect& documentRect,
                                      const mozilla::gfx::Matrix& transform,
                                      const nsString& aBGColor,
                                      uint32_t renderFlags,
                                      bool flushLayout,
                                      const nsIntSize& renderSize,
                                      nsCString& data)
{
    if (flushLayout)
        nsContentUtils::FlushLayoutForTree(window);

    RefPtr<nsPresContext> presContext;
    if (window) {
        nsIDocShell* docshell = window->GetDocShell();
        if (docshell) {
            docshell->GetPresContext(getter_AddRefs(presContext));
        }
    }
    if (!presContext)
        return false;

    nsCSSParser parser;
    nsCSSValue bgColorValue;
    if (!parser.ParseColorString(aBGColor, nullptr, 0, bgColorValue)) {
        return false;
    }

    nscolor bgColor;
    if (!nsRuleNode::ComputeColor(bgColorValue, presContext, nullptr, bgColor)) {
        return false;
    }

    // Draw directly into the output array.
    data.SetLength(renderSize.width * renderSize.height * 4);

    RefPtr<DrawTarget> dt =
        Factory::CreateDrawTargetForData(BackendType::CAIRO,
                                         reinterpret_cast<uint8_t*>(data.BeginWriting()),
                                         IntSize(renderSize.width, renderSize.height),
                                         4 * renderSize.width,
                                         SurfaceFormat::B8G8R8A8);
    if (!dt || !dt->IsValid()) {
        gfxWarning() << "DocumentRendererChild::RenderDocument failed to Factory::CreateDrawTargetForData";
        return false;
    }
    RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(dt);
    MOZ_ASSERT(ctx); // already checked the draw target above
    ctx->SetMatrix(mozilla::gfx::ThebesMatrix(transform));

    nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
    shell->RenderDocument(documentRect, renderFlags, bgColor, ctx);

    return true;
}
// Does an in place rotation of the line
static void
Rot13Line(nsCString &line)
{
  nsCString::iterator start, end;
  line.BeginWriting(start);
  line.EndWriting(end);
  while (start != end) {
    *start = kRot13Table[NS_STATIC_CAST(PRInt32, *start)];
    ++start;
  }
}
Example #4
0
static void ColorToCString(uint32_t aColor, nsCString &aResult) {
  // The #rrrrggggbbbb format is used to match gdk_color_to_string()
  aResult.SetLength(13);
  char *buf = aResult.BeginWriting();
  if (!buf) return;

  uint16_t red = COLOR_8_TO_16_BIT((aColor >> 16) & 0xff);
  uint16_t green = COLOR_8_TO_16_BIT((aColor >> 8) & 0xff);
  uint16_t blue = COLOR_8_TO_16_BIT(aColor & 0xff);

  snprintf(buf, 14, "#%04x%04x%04x", red, green, blue);
}
bool
DocumentRendererChild::RenderDocument(nsIDOMWindow *window,
                                      const nsRect& documentRect,
                                      const gfxMatrix& transform,
                                      const nsString& aBGColor,
                                      uint32_t renderFlags,
                                      bool flushLayout, 
                                      const nsIntSize& renderSize,
                                      nsCString& data)
{
    if (flushLayout)
        nsContentUtils::FlushLayoutForTree(window);

    nsCOMPtr<nsPresContext> presContext;
    nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
    if (win) {
        nsIDocShell* docshell = win->GetDocShell();
        if (docshell) {
            docshell->GetPresContext(getter_AddRefs(presContext));
        }
    }
    if (!presContext)
        return false;

    nsCSSParser parser;
    nsCSSValue bgColorValue;
    if (!parser.ParseColorString(aBGColor, nullptr, 0, bgColorValue)) {
        return false;
    }

    nscolor bgColor;
    if (!nsRuleNode::ComputeColor(bgColorValue, presContext, nullptr, bgColor)) {
        return false;
    }

    // Draw directly into the output array.
    data.SetLength(renderSize.width * renderSize.height * 4);

    nsRefPtr<gfxImageSurface> surf =
        new gfxImageSurface(reinterpret_cast<uint8_t*>(data.BeginWriting()),
                            gfxIntSize(renderSize.width, renderSize.height),
                            4 * renderSize.width,
                            gfxImageFormatARGB32);
    nsRefPtr<gfxContext> ctx = new gfxContext(surf);
    ctx->SetMatrix(transform);

    nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
    shell->RenderDocument(documentRect, renderFlags, bgColor, ctx);

    return true;
}
// Helper function for creating a testing::AsyncStringStream
already_AddRefed<nsBufferedInputStream>
CreateStream(uint32_t aSize, nsCString& aBuffer)
{
  aBuffer.SetLength(aSize);
  for (uint32_t i = 0; i < aSize; ++i) {
    aBuffer.BeginWriting()[i] = i % 10;
  }

  nsCOMPtr<nsIInputStream> stream = new testing::AsyncStringStream(aBuffer);

  RefPtr<nsBufferedInputStream> bis = new nsBufferedInputStream();
  bis->Init(stream, aSize);
  return bis.forget();
}
static void
ColorToCString(PRUint32 aColor, nsCString& aResult)
{
  // The #rrrrggggbbbb format is used to match gdk_color_to_string()
  char *buf = aResult.BeginWriting(13);
  if (!buf)
    return;

  PRUint16 red = COLOR_8_TO_16_BIT((aColor >> 16) & 0xff);
  PRUint16 green = COLOR_8_TO_16_BIT((aColor >> 8) & 0xff);
  PRUint16 blue = COLOR_8_TO_16_BIT(aColor & 0xff);

  PR_snprintf(buf, 14, "#%04x%04x%04x", red, green, blue);
}
Example #8
0
nsresult
nsWebSocket::ConvertTextToUTF8(const nsString& aMessage, nsCString& buf)
{
  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
  nsresult rv;

  nsCOMPtr<nsICharsetConverterManager> ccm =
    do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
  SUCCESS_OR_FAIL_WEBSOCKET(rv, rv);

  nsCOMPtr<nsIUnicodeEncoder> converter;
  rv = ccm->GetUnicodeEncoder("UTF-8", getter_AddRefs(converter));
  SUCCESS_OR_FAIL_WEBSOCKET(rv, rv);

  rv = converter->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace,
                                         nsnull, UTF_8_REPLACEMENT_CHAR);
  SUCCESS_OR_FAIL_WEBSOCKET(rv, rv);

  PRInt32 inLen = aMessage.Length();
  PRInt32 maxLen;
  rv = converter->GetMaxLength(aMessage.BeginReading(), inLen, &maxLen);
  SUCCESS_OR_FAIL_WEBSOCKET(rv, rv);

  buf.SetLength(maxLen);
  TRUE_OR_FAIL_WEBSOCKET(buf.Length() == static_cast<PRUint32>(maxLen),
                         NS_ERROR_OUT_OF_MEMORY);

  char* start = buf.BeginWriting();

  PRInt32 outLen = maxLen;
  rv = converter->Convert(aMessage.BeginReading(), &inLen, start, &outLen);
  if (NS_SUCCEEDED(rv)) {
    PRInt32 outLen2 = maxLen - outLen;
    rv = converter->Finish(start + outLen, &outLen2);
    outLen += outLen2;
  }
  if (NS_FAILED(rv) || rv == NS_ERROR_UENC_NOMAPPING) {
    // Yes, NS_ERROR_UENC_NOMAPPING is a success code
    return NS_ERROR_DOM_SYNTAX_ERR;
  }

  buf.SetLength(outLen);
  TRUE_OR_FAIL_WEBSOCKET(buf.Length() == static_cast<PRUint32>(outLen),
                         NS_ERROR_UNEXPECTED);

  return NS_OK;
}
Example #9
0
static
nsresult
Base64urlEncode(const PRUint8* aBytes,
                PRUint32 aNumBytes,
                nsCString& _result)
{
  // SetLength does not set aside space for NULL termination.  PL_Base64Encode
  // will not NULL terminate, however, nsCStrings must be NULL terminated.  As a
  // result, we set the capacity to be one greater than what we need, and the
  // length to our desired length.
  PRUint32 length = (aNumBytes + 2) / 3 * 4; // +2 due to integer math.
  NS_ENSURE_TRUE(_result.SetCapacity(length + 1), NS_ERROR_OUT_OF_MEMORY);
  _result.SetLength(length);
  (void)PL_Base64Encode(reinterpret_cast<const char*>(aBytes), aNumBytes,
                        _result.BeginWriting());

  // base64url encoding is defined in RFC 4648.  It replaces the last two
  // alphabet characters of base64 encoding with '-' and '_' respectively.
  _result.ReplaceChar('+', '-');
  _result.ReplaceChar('/', '_');
  return NS_OK;
}
Example #10
0
nsresult
nsDataHandler::ParseURI(nsCString& spec,
                        nsCString& contentType,
                        nsCString& contentCharset,
                        bool&    isBase64,
                        nsCString& dataBuffer,
                        nsCString& hashRef) {
    isBase64 = false;

    // move past "data:"
    char *buffer = (char *) PL_strcasestr(spec.BeginWriting(), "data:");
    if (!buffer) {
        // malformed uri
        return NS_ERROR_MALFORMED_URI;
    }
    buffer += 5;

    // First, find the start of the data
    char *comma = strchr(buffer, ',');
    if (!comma)
        return NS_ERROR_MALFORMED_URI;

    *comma = '\0';

    // determine if the data is base64 encoded.
    char *base64 = PL_strcasestr(buffer, ";base64");
    if (base64) {
        isBase64 = true;
        *base64 = '\0';
    }

    if (comma == buffer) {
        // nothing but data
        contentType.AssignLiteral("text/plain");
        contentCharset.AssignLiteral("US-ASCII");
    } else {
        // everything else is content type
        char *semiColon = (char *) strchr(buffer, ';');
        if (semiColon)
            *semiColon = '\0';
        
        if (semiColon == buffer || base64 == buffer) {
            // there is no content type, but there are other parameters
            contentType.AssignLiteral("text/plain");
        } else {
            contentType = buffer;
            ToLowerCase(contentType);
        }

        if (semiColon) {
            char *charset = PL_strcasestr(semiColon + 1, "charset=");
            if (charset)
                contentCharset = charset + sizeof("charset=") - 1;

            *semiColon = ';';
        }
    }

    *comma = ',';
    if (isBase64)
        *base64 = ';';

    contentType.StripWhitespace();
    contentCharset.StripWhitespace();

    // Split encoded data from terminal "#ref" (if present)
    char *data = comma + 1;
    char *hash = strchr(data, '#');
    if (!hash) {
        dataBuffer.Assign(data);
        hashRef.Truncate();
    } else {
        dataBuffer.Assign(data, hash - data);
        hashRef.Assign(hash);
    }

    return NS_OK;
}
Example #11
0
nsresult
nsDataHandler::ParseURI(nsCString& spec,
                        nsCString& contentType,
                        nsCString& contentCharset,
                        bool&    isBase64,
                        nsCString& dataBuffer,
                        nsCString& hashRef) {
    isBase64 = false;

    // move past "data:"
    char *buffer = (char *) PL_strcasestr(spec.BeginWriting(), "data:");
    if (!buffer) {
        // malformed uri
        return NS_ERROR_MALFORMED_URI;
    }
    buffer += 5;

    // First, find the start of the data
    char *comma = strchr(buffer, ',');
    char *hash = strchr(buffer, '#');
    if (!comma || (hash && hash < comma))
        return NS_ERROR_MALFORMED_URI;

    *comma = '\0';

    // determine if the data is base64 encoded.
    char *base64 = PL_strcasestr(buffer, BASE64_EXTENSION);
    if (base64) {
        char *beyond = base64 + strlen(BASE64_EXTENSION);
        // per the RFC 2397 grammar, "base64" MUST be followed by a comma
        // previously substituted by '\0', but we also allow it in between
        // parameters so a subsequent ";" is ok as well (this deals with
        // *broken* data URIs, see bug 781693 for an example)
        if (*beyond == '\0' || *beyond == ';') {
            isBase64 = true;
            *base64 = '\0';
        }
    }

    if (comma == buffer) {
        // nothing but data
        contentType.AssignLiteral("text/plain");
        contentCharset.AssignLiteral("US-ASCII");
    } else {
        // everything else is content type
        char *semiColon = (char *) strchr(buffer, ';');
        if (semiColon)
            *semiColon = '\0';
        
        if (semiColon == buffer || base64 == buffer) {
            // there is no content type, but there are other parameters
            contentType.AssignLiteral("text/plain");
        } else {
            contentType = buffer;
            ToLowerCase(contentType);
        }

        if (semiColon) {
            char *charset = PL_strcasestr(semiColon + 1, "charset=");
            if (charset)
                contentCharset = charset + sizeof("charset=") - 1;

            *semiColon = ';';
        }
    }

    *comma = ',';
    if (isBase64)
        *base64 = ';';

    contentType.StripWhitespace();
    contentCharset.StripWhitespace();

    // Split encoded data from terminal "#ref" (if present)
    char *data = comma + 1;
    if (!hash) {
        dataBuffer.Assign(data);
        hashRef.Truncate();
    } else {
        dataBuffer.Assign(data, hash - data);
        hashRef.Assign(hash);
    }

    return NS_OK;
}
bool
DocumentRendererChild::RenderDocument(nsPIDOMWindowOuter* window,
                                      const nsRect& documentRect,
                                      const mozilla::gfx::Matrix& transform,
                                      const nsString& aBGColor,
                                      uint32_t renderFlags,
                                      bool flushLayout,
                                      const nsIntSize& renderSize,
                                      nsCString& data)
{
    if (flushLayout)
        nsContentUtils::FlushLayoutForTree(window);

    RefPtr<nsPresContext> presContext;
    if (window) {
        nsIDocShell* docshell = window->GetDocShell();
        if (docshell) {
            docshell->GetPresContext(getter_AddRefs(presContext));
        }
    }
    if (!presContext)
        return false;

    nscolor bgColor;

    ServoStyleSet* servoStyleSet = presContext->StyleSet()
      ? presContext->StyleSet()->GetAsServo()
      : nullptr;

    if (servoStyleSet) {
      if (!ServoCSSParser::ComputeColor(servoStyleSet, NS_RGB(0, 0, 0),
                                        aBGColor, &bgColor)) {
        return false;
      }
    } else {
#ifdef MOZ_OLD_STYLE
      nsCSSParser parser;
      nsCSSValue bgColorValue;
      if (!parser.ParseColorString(aBGColor, nullptr, 0, bgColorValue) ||
          !nsRuleNode::ComputeColor(bgColorValue, presContext, nullptr, bgColor)) {
        return false;
      }
#else
      MOZ_CRASH("old style system disabled");
#endif
    }

    // Draw directly into the output array.
    data.SetLength(renderSize.width * renderSize.height * 4);

    RefPtr<DrawTarget> dt =
        Factory::CreateDrawTargetForData(gfxPlatform::GetPlatform()->GetSoftwareBackend(),
                                         reinterpret_cast<uint8_t*>(data.BeginWriting()),
                                         IntSize(renderSize.width, renderSize.height),
                                         4 * renderSize.width,
                                         SurfaceFormat::B8G8R8A8);
    if (!dt || !dt->IsValid()) {
        gfxWarning() << "DocumentRendererChild::RenderDocument failed to Factory::CreateDrawTargetForData";
        return false;
    }
    RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(dt);
    MOZ_ASSERT(ctx); // already checked the draw target above
    ctx->SetMatrix(transform);

    nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
    shell->RenderDocument(documentRect, renderFlags, bgColor, ctx);

    return true;
}