Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* vim:set ts=2 sw=2 sts=2 cin et: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include <QIcon>
8 #include <stdlib.h>
9 #include <unistd.h>
11 #include "mozilla/Endian.h"
13 #include "nsMimeTypes.h"
14 #include "nsIMIMEService.h"
16 #include "nsIStringBundle.h"
18 #include "nsNetUtil.h"
19 #include "nsIURL.h"
21 #include "nsIconChannel.h"
22 #include "nsGtkQtIconsConverter.h"
24 NS_IMPL_ISUPPORTS(nsIconChannel,
25 nsIRequest,
26 nsIChannel)
28 static nsresult
29 moz_qicon_to_channel(QImage *image, nsIURI *aURI,
30 nsIChannel **aChannel)
31 {
32 NS_ENSURE_ARG_POINTER(image);
34 int width = image->width();
35 int height = image->height();
37 NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0,
38 NS_ERROR_UNEXPECTED);
40 const int n_channels = 4;
41 long int buf_size = 2 + n_channels * height * width;
42 uint8_t * const buf = (uint8_t*)NS_Alloc(buf_size);
43 NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
44 uint8_t *out = buf;
46 *(out++) = width;
47 *(out++) = height;
49 const uchar * const pixels = image->bits();
50 int rowextra = image->bytesPerLine() - width * n_channels;
52 // encode the RGB data and the A data
53 const uchar * in = pixels;
54 for (int y = 0; y < height; ++y, in += rowextra) {
55 for (int x = 0; x < width; ++x) {
56 uint8_t r = *(in++);
57 uint8_t g = *(in++);
58 uint8_t b = *(in++);
59 uint8_t a = *(in++);
60 #define DO_PREMULTIPLY(c_) uint8_t(uint16_t(c_) * uint16_t(a) / uint16_t(255))
61 #if MOZ_LITTLE_ENDIAN
62 *(out++) = DO_PREMULTIPLY(b);
63 *(out++) = DO_PREMULTIPLY(g);
64 *(out++) = DO_PREMULTIPLY(r);
65 *(out++) = a;
66 #else
67 *(out++) = a;
68 *(out++) = DO_PREMULTIPLY(r);
69 *(out++) = DO_PREMULTIPLY(g);
70 *(out++) = DO_PREMULTIPLY(b);
71 #endif
72 #undef DO_PREMULTIPLY
73 }
74 }
76 NS_ASSERTION(out == buf + buf_size, "size miscalculation");
78 nsresult rv;
79 nsCOMPtr<nsIStringInputStream> stream =
80 do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
81 NS_ENSURE_SUCCESS(rv, rv);
83 rv = stream->AdoptData((char*)buf, buf_size);
84 NS_ENSURE_SUCCESS(rv, rv);
86 return NS_NewInputStreamChannel(aChannel, aURI, stream,
87 NS_LITERAL_CSTRING(IMAGE_ICON_MS));
88 }
90 nsresult
91 nsIconChannel::Init(nsIURI* aURI)
92 {
94 nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
95 NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
97 nsAutoCString stockIcon;
98 iconURI->GetStockIcon(stockIcon);
100 nsAutoCString iconSizeString;
101 iconURI->GetIconSize(iconSizeString);
103 uint32_t desiredImageSize;
104 iconURI->GetImageSize(&desiredImageSize);
106 nsAutoCString iconStateString;
107 iconURI->GetIconState(iconStateString);
108 bool disabled = iconStateString.EqualsLiteral("disabled");
110 // This is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=662299
111 // Try to find corresponding freedesktop icon and fallback to empty QIcon if failed.
112 QIcon icon = QIcon::fromTheme(QString(stockIcon.get()).replace("gtk-", "edit-"));
113 QPixmap pixmap = icon.pixmap(desiredImageSize, desiredImageSize, disabled ? QIcon::Disabled : QIcon::Normal);
115 QImage image = pixmap.toImage();
117 return moz_qicon_to_channel(&image, iconURI,
118 getter_AddRefs(mRealChannel));
119 }