Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/security/util/ManifestDigester/FindSection.java
41152 views
1
/*
2
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
import java.lang.reflect.Constructor;
25
import java.lang.reflect.Field;
26
import java.lang.reflect.Method;
27
import java.util.Arrays;
28
import java.util.concurrent.Callable;
29
import java.util.function.Consumer;
30
31
import sun.security.util.ManifestDigester;
32
33
import org.testng.annotations.Test;
34
import org.testng.annotations.BeforeClass;
35
import org.testng.annotations.BeforeMethod;
36
import org.testng.annotations.DataProvider;
37
import org.testng.annotations.Factory;
38
39
import static java.nio.charset.StandardCharsets.UTF_8;
40
import static org.testng.Assert.*;
41
42
/**
43
* @test
44
* @bug 8217375
45
* @modules java.base/sun.security.util:+open
46
* @compile ../../tools/jarsigner/Utils.java
47
* @run testng/othervm FindSection
48
* @summary Check {@link ManifestDigester#findSection}.
49
*/
50
public class FindSection {
51
52
/*
53
* TODO:
54
* FIXED_8217375 is not intended to keep. it is intended to show what
55
* exactly has changed with respect to the previous version for which no
56
* such test existed.
57
*/
58
static final boolean FIXED_8217375 = true;
59
60
/**
61
* {@link ManifestDigester.Entry#digestWorkaround} should not feed the
62
* trailing blank line into the digester. Before resolution of 8217375 it
63
* fed the trailing blank line into the digest if the second line break
64
* was at the end of the file due to <pre>
65
* if (allBlank || (i == len-1)) {
66
* if (i == len-1)
67
* pos.endOfSection = i;
68
* else
69
* pos.endOfSection = last;
70
* </pre> in {@link ManifestDigester#findSection}. In that case at the end
71
* of the manifest file, {@link ManifestDigester.Entry#digestWorkaround}
72
* would have produced the same digest as
73
* {@link ManifestDigester.Entry#digest} which was wrong and without effect
74
* at best.
75
* <p>
76
* Once this fix is accepted, this flag can be removed along with
77
* {@link #actualEndOfSection8217375}.
78
*/
79
static final boolean FIXED_8217375_EOF_ENDOFSECTION = FIXED_8217375;
80
81
/**
82
* {@link ManifestDigester.Position.endOfSection} usually points to the
83
* start position of the blank line trailing a section minus one.
84
* If a {@link ManifestDigester.Position} returned by
85
* {@link ManifestDigester#findSection} is based on a portion that starts
86
* with a blank line, above statement is (or was) not true, because of the
87
* initialization of {@code last} in {@link ManifestDigester#findSection}
88
* <pre>
89
* int last = offset;
90
* </pre>
91
* which would point after incrementing it in {@code pos.endOfSection + 1}
92
* on line 128 (line number before this change) or {@code int sectionLen =
93
* pos.endOfSection-start+1;} on line 133 (line number before this change)
94
* at one byte after the first line break character of usually two and
95
* possibly (assuming "{@code \r\n}" default line break normally) in between
96
* the two characters of a line break. After subtracting again the index of
97
* the section start position on former line 133, the last byte would be
98
* missed to be digested by {@link ManifestDigester.Entry#digestWorkaround}.
99
* <p>
100
* All this, however could possibly matter (or have mattered) only when
101
* {@link ManifestDigester#findSection} was invoked with an offset position
102
* pointing straight to a line break which happens if a manifest starts
103
* with an empty line or if there are superfluous blank lines between
104
* sections in both cases no useful manifest portion is identified.
105
* Superfluous blank lines are not identified as sections (because they
106
* don't have a name and specifically don't meet {@code if (len > 6) {} on
107
* former line 136. Manifests starting with a line break are not any more
108
* useful either.
109
* <p>
110
* Once this fix is accepted, this flag can be removed along with
111
* {@link #actualEndOfSection8217375}.
112
*/
113
static final boolean FIXED_8217375_STARTWITHBLANKLINE_ENDOFSECTION =
114
FIXED_8217375;
115
116
static Constructor<?> PositionConstructor;
117
static Method findSection;
118
static Field rawBytes;
119
static Field endOfFirstLine;
120
static Field endOfSection;
121
static Field startOfNext;
122
123
@BeforeClass
124
public static void setFindSectionAccessible() throws Exception {
125
Class<?> Position = Arrays.stream(ManifestDigester.class.
126
getDeclaredClasses()).filter(c -> c.getSimpleName().
127
equals("Position")).findFirst().get();
128
PositionConstructor = Position.getDeclaredConstructor();
129
PositionConstructor.setAccessible(true);
130
findSection = ManifestDigester.class.getDeclaredMethod("findSection",
131
int.class, Position);
132
findSection.setAccessible(true);
133
rawBytes = ManifestDigester.class.getDeclaredField("rawBytes");
134
rawBytes.setAccessible(true);
135
endOfFirstLine = Position.getDeclaredField("endOfFirstLine");
136
endOfFirstLine.setAccessible(true);
137
endOfSection = Position.getDeclaredField("endOfSection");
138
endOfSection.setAccessible(true);
139
startOfNext = Position.getDeclaredField("startOfNext");
140
startOfNext.setAccessible(true);
141
}
142
143
static class Position {
144
final int endOfFirstLine; // not including newline character
145
146
final int endOfSection; // end of section, not including the blank line
147
// between sections
148
final int startOfNext; // the start of the next section
149
150
Position(Object pos) throws ReflectiveOperationException {
151
endOfFirstLine = FindSection.endOfFirstLine.getInt(pos);
152
endOfSection = FindSection.endOfSection.getInt(pos);
153
startOfNext = FindSection.startOfNext.getInt(pos);
154
}
155
}
156
157
Position findSection(byte[] manifestBytes)
158
throws ReflectiveOperationException {
159
ManifestDigester manDig = new ManifestDigester("\n\n".getBytes(UTF_8));
160
FindSection.rawBytes.set(manDig, manifestBytes);
161
Object pos = PositionConstructor.newInstance();
162
Object result = findSection.invoke(manDig, offset, pos);
163
if (Boolean.FALSE.equals(result)) {
164
return null; // indicates findSection having returned false
165
} else {
166
return new Position(pos);
167
}
168
}
169
170
@DataProvider(name = "parameters")
171
public static Object[][] parameters() {
172
return new Object[][] { { 0 }, { 42 } };
173
}
174
175
@Factory(dataProvider = "parameters")
176
public static Object[] createTests(int offset) {
177
return new Object[]{ new FindSection(offset) };
178
}
179
180
final int offset;
181
182
FindSection(int offset) {
183
this.offset = offset;
184
}
185
186
@BeforeMethod
187
public void verbose() {
188
System.out.println("offset = " + offset);
189
}
190
191
Position findSection(String manifestString)
192
throws ReflectiveOperationException {
193
byte[] manifestBytes = manifestString.getBytes(UTF_8);
194
byte[] manifestWithOffset = new byte[manifestBytes.length + offset];
195
System.arraycopy(manifestBytes, 0, manifestWithOffset, offset,
196
manifestBytes.length);
197
return findSection(manifestWithOffset);
198
}
199
200
/**
201
* Surprising, but the offset actually makes a difference in
202
* {@link ManifestDigester#findSection} return value.
203
*/
204
@SuppressWarnings("unused")
205
int actualEndOfFirstLine8217375(int correctPosition) {
206
// if the parsed portion of the manifest starts with a blank line,
207
// and offset is 0, "pos.endOfFirstLine = -1;" probably denoting a
208
// yet uninitialized value coincides with the assignment by
209
// "pos.endOfFirstLine = i-1;" if i == 0 and
210
// "if (pos.endOfFirstLine == -1)" after "case '\n':" happens to
211
// become true even though already assigned.
212
if (offset == 0 && correctPosition == -1 && !FIXED_8217375) return 0;
213
return correctPosition;
214
}
215
216
@SuppressWarnings("unused")
217
int actualEndOfSection8217375(int correctPosition, boolean eof, int lbl) {
218
// if the parsed portion of the manifest ends with a blank line and
219
// just before eof, the blank line is included in Position.endOfSection/
220
// Section.length (the one usually without blank line as well as in
221
// Position.startOfNext/Section.lengthWithBlankLine) which is used
222
// in digestWorkaround (independent of the digest without workaround)
223
if (eof && !FIXED_8217375_EOF_ENDOFSECTION) {
224
return correctPosition + lbl;
225
} else if (correctPosition == -1
226
&& !FIXED_8217375_STARTWITHBLANKLINE_ENDOFSECTION) {
227
return 0;
228
} else {
229
return correctPosition;
230
}
231
}
232
233
AssertionError collectErrors(AssertionError a, Runnable run) {
234
try {
235
run.run();
236
} catch (AssertionError e) {
237
if (a == null) a = new AssertionError();
238
a.addSuppressed(e);
239
}
240
return a;
241
}
242
243
void assertPosition(Position pos,
244
int endOfFirstLine, int endOfSection, int startOfNext) {
245
AssertionError a = null;
246
a = collectErrors(a, () -> assertEquals(
247
pos.endOfFirstLine, endOfFirstLine + offset, "endOfFirstLine"));
248
a = collectErrors(a, () -> assertEquals(
249
pos.endOfSection, endOfSection + offset, "endOfSection"));
250
a = collectErrors(a, () -> assertEquals(
251
pos.startOfNext, startOfNext + offset, "startOfNext"));
252
if (a != null) throw a;
253
}
254
255
void catchCrCausesIndexOutOfBoundsException(
256
Callable<Position> test, Consumer<Position> asserts) {
257
try {
258
Position x = test.call();
259
if (!FIXED_8217375) fail();
260
asserts.accept(x);
261
} catch (Exception e) {
262
if (e instanceof IndexOutOfBoundsException ||
263
e.getCause() instanceof IndexOutOfBoundsException) {
264
if (FIXED_8217375) throw new AssertionError(e);
265
} else {
266
throw new AssertionError(e);
267
}
268
}
269
}
270
271
@Test
272
public void testEmpty() throws Exception {
273
assertNull(findSection(""));
274
}
275
276
@Test
277
public void testOneLineBreakCr() throws Exception {
278
catchCrCausesIndexOutOfBoundsException(
279
() -> findSection("\r"),
280
p -> assertPosition(p,
281
-1, actualEndOfSection8217375(-1, false, 1), 1)
282
);
283
}
284
285
@Test
286
public void testOneLineBreakLf() throws Exception {
287
assertPosition(findSection("\n"),
288
-1, actualEndOfSection8217375(-1, false, 1), 1);
289
}
290
291
@Test
292
public void testOneLineBreakCrLf() throws Exception {
293
assertPosition(findSection("\r\n"),
294
actualEndOfFirstLine8217375(-1),
295
actualEndOfSection8217375(-1, true, 2),
296
2);
297
}
298
299
@Test
300
public void testSpaceAndLineBreakCr() throws Exception {
301
catchCrCausesIndexOutOfBoundsException(
302
() -> findSection(" \r"),
303
p -> assertPosition(p, 2, 3, 4)
304
);
305
}
306
307
@Test
308
public void testSpaceAndOneLineBreakLf() throws Exception {
309
assertPosition(findSection(" \n"), 2, 3, 4);
310
}
311
312
@Test
313
public void testSpaceAndOneLineBreakCrLf() throws Exception {
314
assertPosition(findSection(" \r\n"), 2, 4, 5);
315
}
316
317
@Test
318
public void testOneLineBreakCrAndSpace() throws Exception {
319
assertPosition(findSection("\r "),
320
-1, actualEndOfSection8217375(-1, false, 1), 1);
321
}
322
323
@Test
324
public void testOneLineBreakLfAndSpace() throws Exception {
325
assertPosition(findSection("\n "),
326
-1, actualEndOfSection8217375(-1, false, 1), 1);
327
}
328
329
@Test
330
public void testOneLineBreakCrLfAndSpace() throws Exception {
331
assertPosition(findSection("\r\n "),
332
actualEndOfFirstLine8217375(-1),
333
actualEndOfSection8217375(-1, false, 1),
334
2);
335
}
336
337
@Test
338
public void testCrEof() throws Exception {
339
catchCrCausesIndexOutOfBoundsException(
340
() -> findSection("abc\r"),
341
p -> assertPosition(p, 2, 3, 4)
342
);
343
}
344
345
@Test
346
public void testLfEof() throws Exception {
347
assertPosition(findSection("abc\n"), 2, 3, 4);
348
}
349
350
@Test
351
public void testCrLfEof() throws Exception {
352
assertPosition(findSection("abc\r\n"), 2, 4, 5);
353
}
354
355
@Test
356
public void testCrContinued() throws Exception {
357
assertPosition(findSection("abc\rxyz\r\n\r\n "), 2, 8, 11);
358
}
359
360
@Test
361
public void testLfContinued() throws Exception {
362
assertPosition(findSection("abc\nxyz\r\n\r\n "), 2, 8, 11);
363
}
364
365
@Test
366
public void testCrLfContinued() throws Exception {
367
assertPosition(findSection("abc\r\nxyz\r\n\r\n "), 2, 9, 12);
368
}
369
370
@Test
371
public void testCrCrEof() throws Exception {
372
catchCrCausesIndexOutOfBoundsException(
373
() -> findSection("abc\r\nxyz\r\r"),
374
p -> assertPosition(p,
375
2, actualEndOfSection8217375(8, true, 1), 10)
376
);
377
}
378
379
@Test
380
public void testCrCrContinued() throws Exception {
381
assertPosition(findSection("abc\r\nxyz\r\r "), 2, 8, 10);
382
}
383
384
@Test
385
public void testLfLfEof() throws Exception {
386
assertPosition(findSection("abc\r\nxyz\n\n"),
387
2, actualEndOfSection8217375(8, true, 1), 10);
388
}
389
390
@Test
391
public void testLfLfContinued() throws Exception {
392
assertPosition(findSection("abc\r\nxyz\n\n "), 2, 8, 10);
393
}
394
395
@Test
396
public void testCrLfEof2() throws Exception {
397
assertPosition(findSection("abc\r\nxyz\r\n"), 2, 9, 10);
398
}
399
400
@Test
401
public void testMainSectionNotTerminatedWithLineBreak() throws Exception {
402
assertNull(findSection("abc\r\nxyz\r\n "));
403
}
404
405
@Test
406
public void testLfCrEof() throws Exception {
407
catchCrCausesIndexOutOfBoundsException(
408
() -> findSection("abc\r\nxyz\n\r"),
409
p -> assertPosition(p,
410
2, actualEndOfSection8217375(8, true, 1), 10)
411
);
412
}
413
414
@Test
415
public void testLfCrContinued() throws Exception {
416
assertPosition(findSection("abc\r\nxyz\n\r "), 2, 8, 10);
417
}
418
419
@Test
420
public void testCrLfCrEof() throws Exception {
421
catchCrCausesIndexOutOfBoundsException(
422
() -> findSection("abc\r\nxyz\r\n\r"),
423
p -> assertPosition(p,
424
2, actualEndOfSection8217375(9, true, 2), 11)
425
);
426
}
427
428
@Test
429
public void testCrLfCrContinued() throws Exception {
430
assertPosition(findSection("abc\r\nxyz\r\n\r "), 2, 9, 11);
431
}
432
433
@Test
434
public void testCrLfLfEof() throws Exception {
435
assertPosition(findSection("abc\r\nxyz\r\n\n"),
436
2, actualEndOfSection8217375(9, true, 1), 11);
437
}
438
439
@Test
440
public void testCrLfLfContinued() throws Exception {
441
assertPosition(findSection("abc\r\nxyz\r\n\n "), 2, 9, 11);
442
}
443
444
@Test
445
public void testCrLfCrLfEof() throws Exception {
446
assertPosition(findSection("abc\r\nxyz\r\n\r\n"),
447
2, actualEndOfSection8217375(9, true, 2), 12);
448
}
449
450
@Test
451
public void testCrLfCfLfContinued() throws Exception {
452
assertPosition(findSection("abc\r\nxyz\r\n\r\n "), 2, 9, 12);
453
}
454
455
@Test
456
public void testCrLfCrCrEof() throws Exception {
457
assertPosition(findSection("abc\r\nxyz\r\n\r\r"), 2, 9, 11);
458
}
459
460
@Test
461
public void testCrLfCrCrContinued() throws Exception {
462
assertPosition(findSection("abc\r\nxyz\r\n\r\r "), 2, 9, 11);
463
}
464
465
@Test
466
public void testCrLfLfCrEof() throws Exception {
467
assertPosition(findSection("abc\r\nxyz\r\n\n\r"), 2, 9, 11);
468
}
469
470
@Test
471
public void testCrLfLfCrContinued() throws Exception {
472
assertPosition(findSection("abc\r\nxyz\r\n\n\r "), 2, 9, 11);
473
}
474
475
@Test
476
public void testCrLfCrLfCrEof() throws Exception {
477
assertPosition(findSection("abc\r\nxyz\r\n\r\n\r"), 2, 9, 12);
478
}
479
480
@Test
481
public void testCrLfCfLfCrContinued() throws Exception {
482
assertPosition(findSection("abc\r\nxyz\r\n\r\n\r "), 2, 9, 12);
483
}
484
485
@Test
486
public void testCrLfCrLfContinued() throws Exception {
487
assertPosition(findSection("abc\r\nxyz\r\n\r\n "), 2, 9, 12);
488
}
489
490
@Test
491
public void testCrLfLfLfEof() throws Exception {
492
assertPosition(findSection("abc\r\nxyz\r\n\n\n"), 2, 9, 11);
493
}
494
495
@Test
496
public void testCrLfLfLfContinued() throws Exception {
497
assertPosition(findSection("abc\r\nxyz\r\n\n\n "), 2, 9, 11);
498
}
499
500
@Test
501
public void testCrLfCrLfLfContinued() throws Exception {
502
assertPosition(findSection("abc\r\nxyz\r\n\r\n\n "), 2, 9, 12);
503
}
504
505
@Test
506
public void testCrLfCrCrLfEof() throws Exception {
507
assertPosition(findSection("abc\r\nxyz\r\n\r\r\n"), 2, 9, 11);
508
}
509
510
@Test
511
public void testCrLfCrCrLfContinued() throws Exception {
512
assertPosition(findSection("abc\r\nxyz\r\n\r\r\n "), 2, 9, 11);
513
}
514
515
@Test
516
public void testCrLfLfCrLfEof() throws Exception {
517
assertPosition(findSection("abc\r\nxyz\r\n\n\r\n"), 2, 9, 11);
518
}
519
520
@Test
521
public void testCrLfLfCrLfContinued() throws Exception {
522
assertPosition(findSection("abc\r\nxyz\r\n\n\r\n "), 2, 9, 11);
523
}
524
525
@Test
526
public void testCrLfCrLfCrLfEof() throws Exception {
527
assertPosition(findSection("abc\r\nxyz\r\n\r\n\r\n"), 2, 9, 12);
528
}
529
530
@Test
531
public void testCrLfCfLfCrLfContinued() throws Exception {
532
assertPosition(findSection("abc\r\nxyz\r\n\r\n\r\n "), 2, 9, 12);
533
}
534
535
@Test
536
public void testCrLfLfCrCrEof() throws Exception {
537
assertPosition(findSection("abc\r\nxyz\r\n\n\r\r"), 2, 9, 11);
538
}
539
540
@Test
541
public void testCrLfCrLfCrCrEof() throws Exception {
542
assertPosition(findSection("abc\r\nxyz\r\n\r\n\r\r"), 2, 9, 12);
543
}
544
545
@Test
546
public void testCrLfCrLfCrContinued() throws Exception {
547
assertPosition(findSection("abc\r\nxyz\r\n\r\n\r "), 2, 9, 12);
548
}
549
550
@Test
551
public void testCrLfLfLfCrEof() throws Exception {
552
assertPosition(findSection("abc\r\nxyz\r\n\n\n\r"), 2, 9, 11);
553
}
554
555
@Test
556
public void testCrLfLfCrLfCrEof() throws Exception {
557
assertPosition(findSection("abc\r\nxyz\r\n\n\r\n\r"), 2, 9, 11);
558
}
559
560
@Test
561
public void testCrLfLfLfLfEof() throws Exception {
562
assertPosition(findSection("abc\r\nxyz\r\n\n\n\n"), 2, 9, 11);
563
}
564
565
@Test
566
public void testCrLfLfCrLfLfEof() throws Exception {
567
assertPosition(findSection("abc\r\nxyz\r\n\n\r\n\n"), 2, 9, 11);
568
}
569
570
@Test
571
public void testCrLfLfCrCrLfEof() throws Exception {
572
assertPosition(findSection("abc\r\nxyz\r\n\n\r\r\n"), 2, 9, 11);
573
}
574
575
@Test
576
public void testCrLfCrLfCrCrLfEof() throws Exception {
577
assertPosition(findSection("abc\r\nxyz\r\n\r\n\r\r\n"), 2, 9, 12);
578
}
579
580
@Test
581
public void testCrLfCrLfCrLfContinued() throws Exception {
582
assertPosition(findSection("abc\r\nxyz\r\n\r\n\r\n "), 2, 9, 12);
583
}
584
585
@Test
586
public void testCrLfLfLfCrLfEof() throws Exception {
587
assertPosition(findSection("abc\r\nxyz\r\n\n\n\r\n"), 2, 9, 11);
588
}
589
590
@Test
591
public void testCrLfLfCrLfCrLfEof() throws Exception {
592
assertPosition(findSection("abc\r\nxyz\r\n\n\r\n\r\n"), 2, 9, 11);
593
}
594
595
@Test
596
public void testCrLfCrCrLfCrCrEof() throws Exception {
597
assertPosition(findSection("abc\r\nxyz\r\n\r\r\n\r"), 2, 9, 11);
598
}
599
600
@Test
601
public void testCrLfCrCrCrCrEof() throws Exception {
602
assertPosition(findSection("abc\r\nxyz\r\n\r\r\r"), 2, 9, 11);
603
}
604
605
@Test
606
public void testCrLfCrCrLfLfEof() throws Exception {
607
assertPosition(findSection("abc\r\nxyz\r\n\r\r\n\n"), 2, 9, 11);
608
}
609
610
@Test
611
public void testCrLfCrCrLfCrLfEof() throws Exception {
612
assertPosition(findSection("abc\r\nxyz\r\n\r\r\n\r\n"), 2, 9, 11);
613
}
614
615
@Test
616
public void testCrLfCrCrCrLfEof() throws Exception {
617
assertPosition(findSection("abc\r\nxyz\r\n\r\r\r\n"), 2, 9, 11);
618
}
619
620
/*
621
* endOfFirstLine is the same regardless of the line break delimiter
622
*/
623
@Test
624
public void testEndOfFirstLineVsLineBreak() throws Exception {
625
for (String lb : new String[] { "\r", "\n", "\r\n" }) {
626
Position p = findSection("abc" + lb + "xyz" + lb + lb + " ");
627
628
// main assertion showing endOfFirstLine independent of line break
629
assertEquals(p.endOfFirstLine, 2 + offset);
630
631
// assert remaining positions as well just for completeness
632
assertPosition(p, 2, 5 + 2 * lb.length(), 6 + 3 * lb.length());
633
}
634
}
635
636
/*
637
* '\r' at the end of the bytes causes index out of bounds exception
638
*/
639
@Test
640
public void testCrLastCausesIndexOutOfBounds() throws Exception {
641
catchCrCausesIndexOutOfBoundsException(
642
() -> findSection("\r"),
643
p -> assertPosition(p,
644
-1, actualEndOfSection8217375(-1, true, 1), 1)
645
);
646
}
647
648
/*
649
* endOfSection includes second line break if at end of bytes only
650
*/
651
@Test
652
public void testEndOfSectionWithLineBreakVsEof() throws Exception {
653
AssertionError errors = new AssertionError("offset = " + offset);
654
for (String lb : new String[] { "\r", "\n", "\r\n" }) {
655
for (boolean eof : new boolean[] { false, true }) {
656
Position p;
657
try {
658
p = findSection("abc" + lb + lb + (eof ? "" : "xyz"));
659
} catch (RuntimeException | ReflectiveOperationException e) {
660
if ((e instanceof IndexOutOfBoundsException ||
661
e.getCause() instanceof IndexOutOfBoundsException)
662
&& eof && "\r".equals(lb) && !FIXED_8217375) continue;
663
throw e;
664
}
665
666
AssertionError a = new AssertionError("offset = " + offset
667
+ ", lb = " + Utils.escapeStringWithNumbers(lb) + ", "
668
+ "eof = " + eof);
669
670
// main assertion showing endOfSection including second line
671
// break when at end of file
672
a = collectErrors(a, () -> assertEquals(
673
p.endOfSection,
674
actualEndOfSection8217375(
675
2 + lb.length() + offset, eof, lb.length()) ));
676
677
// assert remaining positions as well just for completeness
678
a = collectErrors(a, () -> assertPosition(p,
679
2,
680
actualEndOfSection8217375(
681
2 + lb.length(), eof, lb.length()),
682
3 + lb.length() * 2));
683
684
if (a.getSuppressed().length > 0) errors.addSuppressed(a);
685
}
686
}
687
if (errors.getSuppressed().length > 0) throw errors;
688
}
689
690
/*
691
* returns position even if only one line break before end of bytes.
692
* because no name will be found the result will be skipped and no entry
693
* will be created.
694
*/
695
@Test
696
public void testReturnPosVsEof() throws Exception {
697
for (String lb : new String[] { "\r", "\n", "\r\n" }) {
698
for (boolean eof : new boolean[] { false, true }) {
699
try {
700
Position p = findSection("abc" + lb + (eof ? "" : "xyz"));
701
assertTrue(p != null == eof);
702
} catch (RuntimeException | ReflectiveOperationException e) {
703
if ((e instanceof IndexOutOfBoundsException ||
704
e.getCause() instanceof IndexOutOfBoundsException)
705
&& eof && "\r".equals(lb) && !FIXED_8217375) continue;
706
throw e;
707
}
708
}
709
}
710
}
711
712
/*
713
* it could be normally be expected that startOfNext would point to the
714
* start of the next section after a blank line but that is not the case
715
* if a section ends with only one line break and no blank line immediately
716
* before eof of the manifest.
717
* such an entry will be digested without the trailing blank line which is
718
* only fine until another section should be added afterwards.
719
*/
720
@Test
721
public void testStartOfNextPointsToEofWithNoBlankLine() throws Exception {
722
for (String lb : new String[] { "\r", "\n", "\r\n" }) {
723
for (boolean blank : new boolean[] { false, true }) {
724
String manifest = "abc" + lb + "xyz" + lb + (blank ? lb : "");
725
try {
726
Position p = findSection(manifest);
727
728
// assert that startOfNext points to eof in all cases
729
// whether with or without a blank line before eof
730
assertEquals(p.startOfNext, manifest.length() + offset);
731
732
// assert remaining positions as well just for completeness
733
assertPosition(p,
734
2,
735
actualEndOfSection8217375(
736
5 + lb.length() * 2,
737
true,
738
blank ? lb.length() : 0),
739
manifest.length());
740
} catch (RuntimeException | ReflectiveOperationException e) {
741
if ((e instanceof IndexOutOfBoundsException ||
742
e.getCause() instanceof IndexOutOfBoundsException)
743
&& "\r".equals(lb) && !FIXED_8217375) continue;
744
throw e;
745
}
746
}
747
}
748
}
749
750
}
751
752