1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.harmony.unpack200;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import org.apache.commons.compress.harmony.pack200.Pack200Exception;
27 import org.apache.commons.compress.harmony.unpack200.bytecode.CPFieldRef;
28 import org.apache.commons.compress.harmony.unpack200.bytecode.CPMethodRef;
29 import org.apache.commons.compress.harmony.unpack200.bytecode.CPString;
30 import org.apache.commons.compress.harmony.unpack200.bytecode.CPUTF8;
31 import org.apache.commons.compress.harmony.unpack200.bytecode.CodeAttribute;
32 import org.apache.commons.compress.harmony.unpack200.bytecode.ExceptionTableEntry;
33 import org.apache.commons.compress.harmony.unpack200.bytecode.LocalVariableTableAttribute;
34 import org.apache.commons.compress.harmony.unpack200.bytecode.OperandManager;
35 import org.junit.jupiter.api.Test;
36
37
38
39
40 class CodeAttributeTest {
41
42 public class MockCodeAttribute extends CodeAttribute {
43
44 MockCodeAttribute(final int maxStack, final int maxLocals, final byte[] codePacked, final Segment segment, final OperandManager operandManager,
45 final List<ExceptionTableEntry> exceptionTable) throws Pack200Exception {
46 super(maxStack, maxLocals, codePacked, segment, operandManager, exceptionTable);
47 }
48
49 @Override
50 public int getLength() {
51 return super.getLength();
52 }
53 }
54
55 public class MockCpBands extends CpBands {
56
57 MockCpBands(final Segment segment) {
58 super(segment);
59 }
60
61 @Override
62 public CPFieldRef cpFieldValue(final int index) {
63 return null;
64 }
65
66 @Override
67 public CPMethodRef cpMethodValue(final int index) {
68 return null;
69 }
70
71 @Override
72 public CPString cpStringValue(final int index) {
73 return new CPString(new CPUTF8("Hello"), -1);
74 }
75
76 }
77
78 public class MockOperandManager extends OperandManager {
79
80 MockOperandManager() {
81 super(new int[] {},
82 new int[] {},
83 new int[] {},
84 new int[] {},
85 new int[] {},
86 new int[] {},
87 new int[] {},
88 new int[] {},
89 new int[] {},
90 new int[] {},
91 new int[] { 0, 1, 2, 3, 4 },
92 new int[] {},
93 new int[] {},
94 new int[] {},
95 new int[] {},
96 new int[] { 0, 0, 0, 0, 0, 0 },
97 new int[] {},
98 new int[] { 0 },
99 new int[] {},
100 new int[] {}
101 , null);
102 }
103 }
104
105 public class MockSegment extends Segment {
106
107 @Override
108 public SegmentConstantPool getConstantPool() {
109 return new MockSegmentConstantPool(cpBands);
110 }
111 }
112
113 public class MockSegmentConstantPool extends SegmentConstantPool {
114
115 MockSegmentConstantPool(final CpBands bands) {
116 super(bands);
117 }
118
119 @Override
120 protected int matchSpecificPoolEntryIndex(final String[] nameArray, final String compareString, final int desiredIndex) {
121 return 1;
122 }
123 }
124
125 Segment segment = new MockSegment();
126 CpBands cpBands = new MockCpBands(segment);
127
128 public byte[] mixedByteArray = { -47,
129 -46,
130 1,
131 -45,
132
133
134 -44,
135 };
136
137 public byte[] singleByteArray = { 42,
138 1,
139 18,
140 -49,
141 };
142
143 @Test
144 void testLength() throws Pack200Exception {
145 final OperandManager operandManager = new MockOperandManager();
146 operandManager.setSegment(segment);
147 operandManager.setCurrentClass("java/lang/Foo");
148
149 final MockCodeAttribute attribute = new MockCodeAttribute(3,
150 2,
151 mixedByteArray,
152 segment,
153 operandManager,
154 new ArrayList<>());
155 assertEquals(29, attribute.getLength());
156
157 attribute.attributes.add(new LocalVariableTableAttribute(0, null, null, null, null, null));
158 assertEquals(37, attribute.getLength());
159 }
160
161 @Test
162 void testMixedByteCodes() throws Pack200Exception {
163 final OperandManager operandManager = new MockOperandManager();
164 operandManager.setSegment(segment);
165 operandManager.setCurrentClass("java/lang/Foo");
166
167 final CodeAttribute attribute = new CodeAttribute(3,
168 2,
169 mixedByteArray,
170 segment,
171 operandManager,
172 new ArrayList<>());
173 assertEquals(2, attribute.maxLocals);
174 assertEquals(3, attribute.maxStack);
175 assertEquals("aload_0_putfield_this", attribute.byteCodes.get(4).toString());
176
177 final int[] expectedLabels = { 0, 1, 4, 5, 8, 9, 10, 13, 14 };
178 for (int index = 0; index < expectedLabels.length; index++) {
179 assertEquals(expectedLabels[index], attribute.byteCodeOffsets.get(index).intValue());
180 }
181 }
182
183 @Test
184 void testSingleByteCodes() throws Pack200Exception {
185 final OperandManager operandManager = new MockOperandManager();
186 operandManager.setSegment(segment);
187 operandManager.setCurrentClass("java/lang/Foo");
188
189 final CodeAttribute attribute = new CodeAttribute(4,
190 3,
191 singleByteArray,
192 segment,
193 operandManager,
194 new ArrayList<>());
195 assertEquals(3, attribute.maxLocals);
196 assertEquals(4, attribute.maxStack);
197 assertEquals("invokespecial_this", attribute.byteCodes.get(3).toString());
198
199 final int[] expectedLabels = { 0, 1, 2, 4 };
200 for (int index = 0; index < expectedLabels.length; index++) {
201 assertEquals(expectedLabels[index], attribute.byteCodeOffsets.get(index).intValue());
202 }
203 }
204
205 }