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