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; } }
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); }
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; }
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; }
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; }
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; }