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 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 const byteStreams = require("sdk/io/byte-streams");
6 const file = require("sdk/io/file");
7 const { pathFor } = require("sdk/system");
8 const { Loader } = require("sdk/test/loader");
10 const STREAM_CLOSED_ERROR = new RegExp("The stream is closed and cannot be used.");
12 // This should match the constant of the same name in byte-streams.js.
13 const BUFFER_BYTE_LEN = 0x8000;
15 exports.testWriteRead = function (assert) {
16 let fname = dataFileFilename();
18 // Write a small string less than the stream's buffer size...
19 let str = "exports.testWriteRead data!";
20 let stream = open(assert, fname, true);
21 assert.ok(!stream.closed, "stream.closed after open should be false");
22 stream.write(str);
23 stream.close();
24 assert.ok(stream.closed, "Stream should be closed after stream.close");
25 assert.throws(function () stream.write("This shouldn't be written!"),
26 STREAM_CLOSED_ERROR,
27 "stream.write after close should raise error");
29 // ... and read it.
30 stream = open(assert, fname);
31 assert.equal(stream.read(), str,
32 "stream.read should return string written");
33 assert.equal(stream.read(), "",
34 "stream.read at EOS should return empty string");
35 stream.close();
36 assert.ok(stream.closed, "Stream should be closed after stream.close");
37 assert.throws(function () stream.read(),
38 STREAM_CLOSED_ERROR,
39 "stream.read after close should raise error");
41 file.remove(fname);
42 };
44 // Write a big string many times the size of the stream's buffer and read it.
45 exports.testWriteReadBig = function (assert) {
46 let str = "";
47 let bufLen = BUFFER_BYTE_LEN;
48 let fileSize = bufLen * 10;
49 for (let i = 0; i < fileSize; i++)
50 str += i % 10;
51 let fname = dataFileFilename();
52 let stream = open(assert, fname, true);
53 stream.write(str);
54 stream.close();
55 stream = open(assert, fname);
56 assert.equal(stream.read(), str,
57 "stream.read should return string written");
58 stream.close();
59 file.remove(fname);
60 };
62 // The same, but write and read in chunks.
63 exports.testWriteReadChunks = function (assert) {
64 let str = "";
65 let bufLen = BUFFER_BYTE_LEN;
66 let fileSize = bufLen * 10;
67 for (let i = 0; i < fileSize; i++)
68 str += i % 10;
69 let fname = dataFileFilename();
70 let stream = open(assert, fname, true);
71 let i = 0;
72 while (i < str.length) {
73 // Use a chunk length that spans buffers.
74 let chunk = str.substr(i, bufLen + 1);
75 stream.write(chunk);
76 i += bufLen + 1;
77 }
78 stream.close();
79 stream = open(assert, fname);
80 let readStr = "";
81 bufLen = BUFFER_BYTE_LEN;
82 let readLen = bufLen + 1;
83 do {
84 var frag = stream.read(readLen);
85 readStr += frag;
86 } while (frag);
87 stream.close();
88 assert.equal(readStr, str,
89 "stream.write and read in chunks should work as expected");
90 file.remove(fname);
91 };
93 exports.testReadLengths = function (assert) {
94 let fname = dataFileFilename();
95 let str = "exports.testReadLengths data!";
96 let stream = open(assert, fname, true);
97 stream.write(str);
98 stream.close();
100 stream = open(assert, fname);
101 assert.equal(stream.read(str.length * 1000), str,
102 "stream.read with big byte length should return string " +
103 "written");
104 stream.close();
106 stream = open(assert, fname);
107 assert.equal(stream.read(0), "",
108 "string.read with zero byte length should return empty " +
109 "string");
110 stream.close();
112 stream = open(assert, fname);
113 assert.equal(stream.read(-1), "",
114 "string.read with negative byte length should return " +
115 "empty string");
116 stream.close();
118 file.remove(fname);
119 };
121 exports.testTruncate = function (assert) {
122 let fname = dataFileFilename();
123 let str = "exports.testReadLengths data!";
124 let stream = open(assert, fname, true);
125 stream.write(str);
126 stream.close();
128 stream = open(assert, fname);
129 assert.equal(stream.read(), str,
130 "stream.read should return string written");
131 stream.close();
133 stream = open(assert, fname, true);
134 stream.close();
136 stream = open(assert, fname);
137 assert.equal(stream.read(), "",
138 "stream.read after truncate should be empty");
139 stream.close();
141 file.remove(fname);
142 };
144 exports.testUnload = function (assert) {
145 let loader = Loader(module);
146 let file = loader.require("sdk/io/file");
148 let filename = dataFileFilename("temp-b");
149 let stream = file.open(filename, "wb");
151 loader.unload();
152 assert.ok(stream.closed, "Stream should be closed after module unload");
153 };
155 // Returns the name of a file that should be used to test writing and reading.
156 function dataFileFilename() {
157 return file.join(pathFor("ProfD"), "test-byte-streams-data");
158 }
160 // Opens and returns the given file and ensures it's of the correct class.
161 function open(assert, filename, forWriting) {
162 let stream = file.open(filename, forWriting ? "wb" : "b");
163 let klass = forWriting ? "ByteWriter" : "ByteReader";
164 assert.ok(stream instanceof byteStreams[klass],
165 "Opened stream should be a " + klass);
166 return stream;
167 }
169 require('sdk/test').run(exports);