1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specic language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "RedactionInfoTest"
18 
19 #include <gtest/gtest.h>
20 
21 #include <memory>
22 #include <ostream>
23 #include <vector>
24 
25 #include "libfuse_jni/RedactionInfo.h"
26 
27 namespace mediaprovider::fuse {
28 
29 using std::vector;
30 
operator <<(std::ostream & os,const ReadRange & rr)31 std::ostream& operator<<(std::ostream& os, const ReadRange& rr) {
32     os << "{ " << rr.start << ", " << rr.size << ", " << rr.is_redaction << " }";
33     return os;
34 }
35 
TEST(RedactionInfoTest,testNoRedactionRanges)36 TEST(RedactionInfoTest, testNoRedactionRanges) {
37     RedactionInfo info(0, nullptr);
38     EXPECT_EQ(0, info.size());
39     EXPECT_EQ(false, info.isRedactionNeeded());
40 
41     std::vector<ReadRange> out;
42     info.getReadRanges(0, std::numeric_limits<size_t>::max(), &out);
43     EXPECT_EQ(0, out.size());
44 }
45 
46 // Test the case where there is 1 redaction range.
TEST(RedactionInfoTest,testSingleRedactionRange)47 TEST(RedactionInfoTest, testSingleRedactionRange) {
48     off64_t ranges[2] = {
49             1,
50             10,
51     };
52 
53     RedactionInfo info(1, ranges);
54     EXPECT_EQ(1, info.size());
55     EXPECT_EQ(true, info.isRedactionNeeded());
56 
57     // Overlapping ranges
58     std::vector<ReadRange> out;
59     info.getReadRanges(0, 1000, &out);  // read offsets [0, 1000)
60     EXPECT_EQ(3, out.size());
61     EXPECT_EQ(ReadRange(0, 1, false), out[0]);
62     EXPECT_EQ(ReadRange(1, 9, true), out[1]);
63     EXPECT_EQ(ReadRange(10, 990, false), out[2]);
64 
65     out.clear();
66     info.getReadRanges(0, 5, &out);  // read offsets [0, 5)
67     EXPECT_EQ(2, out.size());
68     EXPECT_EQ(ReadRange(0, 1, false), out[0]);  // offsets: [0, 1) len = 1
69     EXPECT_EQ(ReadRange(1, 4, true), out[1]);   // offsets: [1, 5) len = 4
70 
71     out.clear();
72     info.getReadRanges(1, 10, &out);  // read offsets [1, 11)
73     EXPECT_EQ(2, out.size());
74     EXPECT_EQ(ReadRange(1, 9, true), out[0]);    // offsets: [1, 10) len = 9
75     EXPECT_EQ(ReadRange(10, 1, false), out[1]);  // offsets: [10, 11) len = 1
76 
77     // Read ranges that start or end with the boundary of the redacted area.
78     out.clear();
79     info.getReadRanges(5, 5, &out);  // read offsets [5, 10)
80     EXPECT_EQ(1, out.size());
81     EXPECT_EQ(ReadRange(5, 5, true), out[0]);  // offsets: [5, 10) len = 5
82 
83     out.clear();
84     info.getReadRanges(1, 5, &out);  // read offsets [1, 6)
85     EXPECT_EQ(1, out.size());
86     EXPECT_EQ(ReadRange(1, 5, true), out[0]);  // offsets: [1, 6) len = 5
87 
88     // Read ranges adjoining the redacted area.
89     out.clear();
90     info.getReadRanges(10, 10, &out);  // read offsets [10, 20)
91     EXPECT_EQ(0, out.size());
92 
93     out.clear();
94     info.getReadRanges(0, 1, &out);  // read offsets [0, 1)
95     EXPECT_EQ(0, out.size());
96 
97     // Read Range outside the redacted area.
98     out.clear();
99     info.getReadRanges(200, 10, &out);  // read offsets [200, 210)
100     EXPECT_EQ(0, out.size());
101 }
102 
103 // Multiple redaction ranges within a given area.
TEST(RedactionInfoTest,testSortedAndNonOverlappingRedactionRanges)104 TEST(RedactionInfoTest, testSortedAndNonOverlappingRedactionRanges) {
105     // [10, 20), [30, 40), [40, 50)
106     off64_t ranges[4] = {10, 20, 30, 40};
107 
108     RedactionInfo info = RedactionInfo(2, ranges);
109     EXPECT_EQ(2, info.size());
110     EXPECT_EQ(true, info.isRedactionNeeded());
111 
112     std::vector<ReadRange> out;
113     info.getReadRanges(0, 40, &out);  // read offsets [0, 40)
114     EXPECT_EQ(4, out.size());
115     EXPECT_EQ(ReadRange(0, 10, false), out[0]);   // offsets: [0, 10) len = 10
116     EXPECT_EQ(ReadRange(10, 10, true), out[1]);   // offsets: [10, 20) len = 10
117     EXPECT_EQ(ReadRange(20, 10, false), out[2]);  // offsets: [20, 30) len = 10
118     EXPECT_EQ(ReadRange(30, 10, true), out[3]);   // offsets [30, 40) len = 10
119 
120     // Read request straddling two ranges.
121     out.clear();
122     info.getReadRanges(5, 30, &out);  // read offsets [5, 35)
123     EXPECT_EQ(4, out.size());
124     EXPECT_EQ(ReadRange(5, 5, false), out[0]);    // offsets: [5, 10) len = 5
125     EXPECT_EQ(ReadRange(10, 10, true), out[1]);   // offsets: [10, 20) len = 10
126     EXPECT_EQ(ReadRange(20, 10, false), out[2]);  // offsets: [20, 30) len = 10
127     EXPECT_EQ(ReadRange(30, 5, true), out[3]);    // offsets [30, 35) len = 5
128 
129     // Read request overlapping first range only.
130     out.clear();
131     info.getReadRanges(5, 10, &out);  // read offsets [5, 15)
132     EXPECT_EQ(2, out.size());
133     EXPECT_EQ(ReadRange(5, 5, false), out[0]);  // offsets: [5, 10) len = 5
134     EXPECT_EQ(ReadRange(10, 5, true), out[1]);  // offsets: [10, 15) len = 5
135 
136     // Read request overlapping last range only.
137     out.clear();
138     info.getReadRanges(35, 10, &out);  // read offsets [35, 45)
139     EXPECT_EQ(2, out.size());
140     EXPECT_EQ(ReadRange(35, 5, true), out[0]);   // offsets: [35, 40) len = 5
141     EXPECT_EQ(ReadRange(40, 5, false), out[1]);  // offsets: [40, 45) len = 5
142 
143     // Read request overlapping no ranges.
144     out.clear();
145     info.getReadRanges(0, 10, &out);  // read offsets [0, 10)
146     EXPECT_EQ(0, out.size());
147     out.clear();
148     info.getReadRanges(21, 5, &out);  // read offsets [21, 26)
149     EXPECT_EQ(0, out.size());
150     out.clear();
151     info.getReadRanges(40, 10, &out);  // read offsets [40, 50)
152     EXPECT_EQ(0, out.size());
153 }
154 
155 // Multiple redaction ranges overlapping with read range.
TEST(RedactionInfoTest,testReadRangeOverlappingWithRedactionRanges)156 TEST(RedactionInfoTest, testReadRangeOverlappingWithRedactionRanges) {
157     // [10, 20), [30, 40)
158     off64_t ranges[4] = {10, 20, 30, 40};
159 
160     RedactionInfo info = RedactionInfo(2, ranges);
161     EXPECT_EQ(2, info.size());
162     EXPECT_EQ(true, info.isRedactionNeeded());
163 
164     std::vector<ReadRange> out;
165     // Read request overlaps with end of the ranges.
166     info.getReadRanges(20, 20, &out);  // read offsets [20, 40)
167     EXPECT_EQ(2, out.size());
168     EXPECT_EQ(ReadRange(20, 10, false), out[0]);  // offsets: [20, 30) len = 10
169     EXPECT_EQ(ReadRange(30, 10, true), out[1]);   // offsets: [30, 40) len = 10
170 
171     // Read request overlapping with start of the ranges
172     out.clear();
173     info.getReadRanges(10, 20, &out);  // read offsets [10, 30)
174     EXPECT_EQ(2, out.size());
175     EXPECT_EQ(ReadRange(10, 10, true), out[0]);   // offsets: [10, 20) len = 10
176     EXPECT_EQ(ReadRange(20, 10, false), out[1]);  // offsets: [20, 30) len = 10
177 
178     // Read request overlaps with start of one and end of other range.
179     out.clear();
180     info.getReadRanges(10, 30, &out);  // read offsets [10, 40)
181     EXPECT_EQ(3, out.size());
182     EXPECT_EQ(ReadRange(10, 10, true), out[0]);   // offsets: [10, 20) len = 10
183     EXPECT_EQ(ReadRange(20, 10, false), out[1]);  // offsets: [20, 30) len = 10
184     EXPECT_EQ(ReadRange(30, 10, true), out[2]);   // offsets: [30, 40) len = 10
185 
186     // Read request overlaps with end of one and start of other range.
187     out.clear();
188     info.getReadRanges(20, 10, &out);  // read offsets [20, 30)
189     EXPECT_EQ(0, out.size());
190 }
191 
TEST(RedactionInfoTest,testRedactionRangesSorted)192 TEST(RedactionInfoTest, testRedactionRangesSorted) {
193     off64_t ranges[6] = {30, 40, 50, 60, 10, 20};
194 
195     RedactionInfo info = RedactionInfo(3, ranges);
196     EXPECT_EQ(3, info.size());
197     EXPECT_EQ(true, info.isRedactionNeeded());
198 
199     std::vector<ReadRange> out;
200     info.getReadRanges(0, 60, &out);  // read offsets [0, 60)
201     EXPECT_EQ(6, out.size());
202     EXPECT_EQ(ReadRange(0, 10, false), out[0]);   // offsets: [0, 10) len = 10
203     EXPECT_EQ(ReadRange(10, 10, true), out[1]);   // offsets: [10, 20) len = 10
204     EXPECT_EQ(ReadRange(20, 10, false), out[2]);  // offsets: [20, 30) len = 10
205     EXPECT_EQ(ReadRange(30, 10, true), out[3]);   // offsets [30, 40) len = 10
206     EXPECT_EQ(ReadRange(40, 10, false), out[4]);  // offsets [40, 50) len = 10
207     EXPECT_EQ(ReadRange(50, 10, true), out[5]);   // offsets [50, 60) len = 10
208 
209     // Read request overlapping first range only.
210     out.clear();
211     info.getReadRanges(5, 10, &out);  // read offsets [5, 15)
212     EXPECT_EQ(2, out.size());
213     EXPECT_EQ(ReadRange(5, 5, false), out[0]);  // offsets: [5, 10) len = 5
214     EXPECT_EQ(ReadRange(10, 5, true), out[1]);  // offsets: [10, 15) len = 5
215 
216     // Read request overlapping last range only.
217     out.clear();
218     info.getReadRanges(55, 10, &out);  // read offsets [55, 65)
219     EXPECT_EQ(2, out.size());
220     EXPECT_EQ(ReadRange(55, 5, true), out[0]);   // offsets: [55, 60) len = 5
221     EXPECT_EQ(ReadRange(60, 5, false), out[1]);  // offsets: [60, 65) len = 5
222 
223     // Read request overlapping no ranges.
224     out.clear();
225     info.getReadRanges(0, 10, &out);  // read offsets [0, 10)
226     EXPECT_EQ(0, out.size());
227     out.clear();
228     info.getReadRanges(60, 10, &out);  // read offsets [60, 70)
229     EXPECT_EQ(0, out.size());
230 }
231 
232 // Test that the ranges are both sorted and merged
TEST(RedactionInfoTest,testSortAndMergeRedactionRanges)233 TEST(RedactionInfoTest, testSortAndMergeRedactionRanges) {
234     // Ranges are: [10, 20), [25, 40), [50, 60)
235     off64_t ranges[8] = {30, 40, 10, 20, 25, 30, 50, 60};
236 
237     RedactionInfo info = RedactionInfo(4, ranges);
238     EXPECT_EQ(3, info.size());
239     EXPECT_EQ(true, info.isRedactionNeeded());
240 
241     std::vector<ReadRange> out;
242     info.getReadRanges(0, 60, &out);  // read offsets [0, 60)
243     EXPECT_EQ(6, out.size());
244     EXPECT_EQ(ReadRange(0, 10, false), out[0]);   // offsets: [0, 10) len = 10
245     EXPECT_EQ(ReadRange(10, 10, true), out[1]);   // offsets: [10, 20) len = 10
246     EXPECT_EQ(ReadRange(20, 5, false), out[2]);   // offsets: [20, 25) len = 5
247     EXPECT_EQ(ReadRange(25, 15, true), out[3]);   // offsets [25, 40) len = 15
248     EXPECT_EQ(ReadRange(40, 10, false), out[4]);  // offsets [40, 50) len = 10
249     EXPECT_EQ(ReadRange(50, 10, true), out[5]);   // offsets [50, 60) len = 10
250 }
251 
252 // Test that the ranges are both sorted and merged when there's an overlap.
253 //
254 // TODO: Can this ever happen ? Will we ever be in a state where we need to
255 // redact exif attributes that have overlapping ranges ?
TEST(RedactionInfoTest,testSortAndMergeRedactionRanges_overlap)256 TEST(RedactionInfoTest, testSortAndMergeRedactionRanges_overlap) {
257     // Ranges are: [10, 20), [25, 40), [50, 60)
258     off64_t ranges[8] = {30, 40, 10, 20, 25, 34, 50, 60};
259 
260     RedactionInfo info = RedactionInfo(4, ranges);
261     EXPECT_EQ(3, info.size());
262     EXPECT_EQ(true, info.isRedactionNeeded());
263 
264     std::vector<ReadRange> out;
265     info.getReadRanges(0, 60, &out);  // read offsets [0, 60)
266     EXPECT_EQ(6, out.size());
267     EXPECT_EQ(ReadRange(0, 10, false), out[0]);   // offsets: [0, 10) len = 10
268     EXPECT_EQ(ReadRange(10, 10, true), out[1]);   // offsets: [10, 20) len = 10
269     EXPECT_EQ(ReadRange(20, 5, false), out[2]);   // offsets: [20, 25) len = 5
270     EXPECT_EQ(ReadRange(25, 15, true), out[3]);   // offsets [25, 40) len = 15
271     EXPECT_EQ(ReadRange(40, 10, false), out[4]);  // offsets [40, 50) len = 10
272     EXPECT_EQ(ReadRange(50, 10, true), out[5]);   // offsets [50, 60) len = 10
273 }
274 
275 // WARNING: The tests below assume that merging of ranges happen during
276 // object construction (which is asserted by the check on |info.size()|.
277 // Therefore, we don't write redundant tests for boundary conditions that
278 // we've covered above. If this ever changes, these tests need to be expanded.
TEST(RedactionInfoTest,testMergeAllRangesIntoSingleRange)279 TEST(RedactionInfoTest, testMergeAllRangesIntoSingleRange) {
280     // Ranges are: [8, 24)
281     off64_t ranges[8] = {10, 20, 8, 14, 14, 24, 12, 16};
282 
283     RedactionInfo info = RedactionInfo(4, ranges);
284     EXPECT_EQ(1, info.size());
285     EXPECT_EQ(true, info.isRedactionNeeded());
286 
287     std::vector<ReadRange> out;
288     info.getReadRanges(0, 30, &out);  // read offsets [0, 30)
289     EXPECT_EQ(3, out.size());
290     EXPECT_EQ(ReadRange(0, 8, false), out[0]);   // offsets: [0, 8) len = 8
291     EXPECT_EQ(ReadRange(8, 16, true), out[1]);   // offsets: [8, 24) len = 16
292     EXPECT_EQ(ReadRange(24, 6, false), out[2]);  // offsets: [24, 30) len = 6
293 
294     // Ranges are: [85, 100)
295     off64_t ranges2[10] = {90, 95, 95, 100, 85, 91, 92, 94, 99, 100};
296     info = RedactionInfo(5, ranges2);
297     EXPECT_EQ(1, info.size());
298     EXPECT_EQ(true, info.isRedactionNeeded());
299 
300     out.clear();
301     info.getReadRanges(80, 30, &out);  // read offsets [80, 110)
302     EXPECT_EQ(3, out.size());
303     EXPECT_EQ(ReadRange(80, 5, false), out[0]);    // offsets: [80, 85) len = 5
304     EXPECT_EQ(ReadRange(85, 15, true), out[1]);    // offsets: [85, 100) len = 15
305     EXPECT_EQ(ReadRange(100, 10, false), out[2]);  // offsets: [100, 110) len = 10
306 }
307 
TEST(RedactionInfoTest,testMergeMultipleRanges)308 TEST(RedactionInfoTest, testMergeMultipleRanges) {
309     // Ranges are: [10, 30), [60, 80)
310     off64_t ranges[8] = {20, 30, 10, 20, 70, 80, 60, 70};
311 
312     RedactionInfo info = RedactionInfo(4, ranges);
313     EXPECT_EQ(2, info.size());
314     EXPECT_EQ(true, info.isRedactionNeeded());
315 
316     std::vector<ReadRange> out;
317     info.getReadRanges(0, 100, &out);  // read offsets [0, 100)
318     EXPECT_EQ(5, out.size());
319     EXPECT_EQ(ReadRange(0, 10, false), out[0]);   // offsets: [0, 10) len = 10
320     EXPECT_EQ(ReadRange(10, 20, true), out[1]);   // offsets: [10, 30) len = 20
321     EXPECT_EQ(ReadRange(30, 30, false), out[2]);  // offsets: [30, 60) len = 30
322     EXPECT_EQ(ReadRange(60, 20, true), out[3]);   // offsets [60, 80) len = 20
323     EXPECT_EQ(ReadRange(80, 20, false), out[4]);  // offsets [80, 100) len = 20
324 }
325 
326 // Redaction ranges of size zero.
TEST(RedactionInfoTest,testRedactionRangesZeroSize)327 TEST(RedactionInfoTest, testRedactionRangesZeroSize) {
328     // [10, 20), [30, 40)
329     off64_t ranges[6] = {10, 20, 30, 40, 25, 25};
330 
331     RedactionInfo info = RedactionInfo(3, ranges);
332     EXPECT_EQ(2, info.size());
333     EXPECT_EQ(true, info.isRedactionNeeded());
334 
335     // Normal read request, should skip range with zero size
336     std::vector<ReadRange> out;
337     info.getReadRanges(0, 40, &out);  // read offsets [0, 40)
338     EXPECT_EQ(4, out.size());
339     EXPECT_EQ(ReadRange(0, 10, false), out[0]);   // offsets: [0, 10) len = 10
340     EXPECT_EQ(ReadRange(10, 10, true), out[1]);   // offsets: [10, 20) len = 10
341     EXPECT_EQ(ReadRange(20, 10, false), out[2]);  // offsets: [20, 30) len = 10
342     EXPECT_EQ(ReadRange(30, 10, true), out[3]);   // offsets [30, 40) len = 10
343 
344     // Read request starting at offset overlapping with zero size range.
345     out.clear();
346     info.getReadRanges(25, 10, &out);  // read offsets [25, 35)
347     EXPECT_EQ(2, out.size());
348     EXPECT_EQ(ReadRange(25, 5, false), out[0]);  // offsets: [25, 30) len = 5
349     EXPECT_EQ(ReadRange(30, 5, true), out[1]);   // offsets [30, 35) len = 5
350 
351     // 1 byte read request starting at offset overlapping with zero size range.
352     out.clear();
353     info.getReadRanges(25, 1, &out);  // read offsets [25, 26)
354     EXPECT_EQ(0, out.size());
355 
356     // Read request ending at offset overlapping with zero size range.
357     out.clear();
358     info.getReadRanges(0, 25, &out);  // read offsets [0, 25)
359     EXPECT_EQ(3, out.size());
360     EXPECT_EQ(ReadRange(0, 10, false), out[0]);  // offsets: [0, 10) len = 10
361     EXPECT_EQ(ReadRange(10, 10, true), out[1]);  // offsets: [10, 20) len = 10
362     EXPECT_EQ(ReadRange(20, 5, false), out[2]);  // offsets: [20, 25) len = 10
363 
364     // Read request that includes only zero size range
365     out.clear();
366     info.getReadRanges(20, 10, &out);  // read offsets [20, 27)
367     EXPECT_EQ(0, out.size());
368 }
369 
370 // Single redaction range with zero size
TEST(RedactionInfoTest,testSingleRedactionRangesZeroSize)371 TEST(RedactionInfoTest, testSingleRedactionRangesZeroSize) {
372     off64_t ranges[2] = {10, 10};
373 
374     RedactionInfo info = RedactionInfo(1, ranges);
375     EXPECT_EQ(0, info.size());
376     EXPECT_EQ(false, info.isRedactionNeeded());
377 
378     // Normal read request, should skip range with zero size
379     std::vector<ReadRange> out;
380     info.getReadRanges(0, 40, &out);  // read offsets [0, 40)
381     EXPECT_EQ(0, out.size());
382 }
383 
384 }  // namespace mediaprovider::fuse
385