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