Skip to content

Commit a651756

Browse files
authored
chore: tests for pclntab (#701)
Added some tests to improve the test coverage for snyk-docker-plugin. go-parser specifically for this PR. Since our test coverage isn't great at this time
1 parent 127293f commit a651756

1 file changed

Lines changed: 212 additions & 0 deletions

File tree

test/unit/pclntab.spec.ts

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
import { LineTable } from "../../lib/go-parser/pclntab";
2+
3+
describe("LineTable", () => {
4+
describe("constructor", () => {
5+
it("rejects buffer that is too small", () => {
6+
const buffer = Buffer.alloc(15);
7+
expect(() => new LineTable(buffer)).toThrow("unknown header format");
8+
});
9+
10+
it("rejects non-zero reserved bytes", () => {
11+
const buffer = Buffer.from([0, 0, 0, 0, 1, 0, 1, 4]);
12+
expect(() => new LineTable(buffer)).toThrow("unknown header format");
13+
});
14+
15+
it("rejects invalid pc quantum", () => {
16+
const buffer = Buffer.from([0, 0, 0, 0, 0, 0, 3, 4]);
17+
expect(() => new LineTable(buffer)).toThrow("unknown header format");
18+
});
19+
20+
it("rejects invalid pointer size", () => {
21+
const buffer = Buffer.from([0, 0, 0, 0, 0, 0, 1, 6]);
22+
expect(() => new LineTable(buffer)).toThrow("unknown header format");
23+
});
24+
25+
it("rejects unknown magic number", () => {
26+
const buffer = Buffer.alloc(16);
27+
buffer.writeUInt32BE(0xdeadbeef, 0);
28+
buffer[4] = 0;
29+
buffer[5] = 0;
30+
buffer[6] = 1;
31+
buffer[7] = 8;
32+
33+
expect(() => new LineTable(buffer)).toThrow(
34+
"unknown / unsupported Go version",
35+
);
36+
});
37+
38+
it("accepts Go 1.2 with big-endian encoding", () => {
39+
const buffer = Buffer.alloc(200);
40+
buffer.writeUInt32BE(0xfffffffb, 0);
41+
buffer[4] = 0;
42+
buffer[5] = 0;
43+
buffer[6] = 1;
44+
buffer[7] = 8;
45+
46+
// Write nfunctab at offset 8
47+
buffer.writeBigUInt64BE(0n, 8);
48+
49+
// Write minimal fileoff data
50+
const functabOffset = 16;
51+
buffer.writeUInt32BE(100, functabOffset); // fileoff points to offset 100
52+
buffer.writeUInt32BE(0, 100); // nfiletab = 0
53+
54+
expect(() => new LineTable(buffer)).not.toThrow();
55+
});
56+
57+
it("accepts Go 1.16 with big-endian encoding", () => {
58+
const buffer = Buffer.alloc(200);
59+
buffer.writeUInt32BE(0xfffffffa, 0);
60+
buffer[4] = 0;
61+
buffer[5] = 0;
62+
buffer[6] = 1;
63+
buffer[7] = 8;
64+
65+
// offset(1) at position 16
66+
buffer.writeBigUInt64BE(0n, 16); // nfiletab
67+
68+
// offset(4) at position 40
69+
buffer.writeBigUInt64BE(100n, 40); // filetab offset
70+
71+
// offset(6) at position 56
72+
buffer.writeBigUInt64BE(120n, 56); // funcdata offset
73+
74+
// Write empty data at those offsets
75+
buffer.writeUInt32BE(0, 100);
76+
77+
expect(() => new LineTable(buffer)).not.toThrow();
78+
});
79+
80+
it("accepts Go 1.18 with big-endian encoding", () => {
81+
const buffer = Buffer.alloc(200);
82+
buffer.writeUInt32BE(0xfffffff0, 0);
83+
buffer[4] = 0;
84+
buffer[5] = 0;
85+
buffer[6] = 1;
86+
buffer[7] = 8;
87+
88+
// offset(1) at position 16
89+
buffer.writeBigUInt64BE(0n, 16); // nfiletab
90+
91+
// offset(5) at position 48
92+
buffer.writeBigUInt64BE(100n, 48); // filetab offset
93+
94+
// offset(7) at position 64
95+
buffer.writeBigUInt64BE(120n, 64); // funcdata offset
96+
97+
// Write empty data at those offsets
98+
buffer.writeUInt32BE(0, 100);
99+
100+
expect(() => new LineTable(buffer)).not.toThrow();
101+
});
102+
103+
it("accepts Go 1.20 with big-endian encoding", () => {
104+
const buffer = Buffer.alloc(200);
105+
buffer.writeUInt32BE(0xfffffff1, 0);
106+
buffer[4] = 0;
107+
buffer[5] = 0;
108+
buffer[6] = 1;
109+
buffer[7] = 8;
110+
111+
// offset(1) at position 16
112+
buffer.writeBigUInt64BE(0n, 16); // nfiletab
113+
114+
// offset(5) at position 48
115+
buffer.writeBigUInt64BE(100n, 48); // filetab offset
116+
117+
// offset(7) at position 64
118+
buffer.writeBigUInt64BE(120n, 64); // funcdata offset
119+
120+
// Write empty data at those offsets
121+
buffer.writeUInt32BE(0, 100);
122+
123+
expect(() => new LineTable(buffer)).not.toThrow();
124+
});
125+
});
126+
127+
describe("go12MapFiles", () => {
128+
it("caches file map after first call", () => {
129+
const buffer = Buffer.alloc(300);
130+
buffer.writeUInt32LE(0xfffffffb, 0); // Go 1.2 magic
131+
buffer[4] = 0;
132+
buffer[5] = 0;
133+
buffer[6] = 1;
134+
buffer[7] = 8;
135+
136+
// Write nfunctab at offset 8
137+
buffer.writeBigUInt64LE(1n, 8);
138+
139+
// Functab starts at offset 16
140+
const functabOffset = 16;
141+
const functabSize = 24; // (1 * 2 + 1) * 8
142+
143+
// Write fileoff after functab
144+
buffer.writeUInt32LE(100, functabOffset + functabSize);
145+
146+
// Write filetab at offset 100
147+
buffer.writeUInt32LE(2, 100); // nfiletab = 2
148+
buffer.writeUInt32LE(108, 104); // offset to filename
149+
buffer.write("test.go\0", 108);
150+
151+
const lt = new LineTable(buffer);
152+
const files1 = lt.go12MapFiles();
153+
const files2 = lt.go12MapFiles();
154+
155+
expect(files1).toContain("test.go");
156+
expect(files2).toEqual(files1);
157+
});
158+
});
159+
160+
describe("32-bit pointer handling", () => {
161+
it("handles 32-bit pointers in Go 1.2", () => {
162+
const buffer = Buffer.alloc(200);
163+
buffer.writeUInt32LE(0xfffffffb, 0); // Go 1.2 magic
164+
buffer[4] = 0;
165+
buffer[5] = 0;
166+
buffer[6] = 1;
167+
buffer[7] = 4; // 32-bit pointer size
168+
169+
// Write nfunctab at offset 8 (32-bit)
170+
buffer.writeUInt32LE(0, 8);
171+
172+
// Functab starts at offset 12 (8 + 4)
173+
const functabOffset = 12;
174+
const functabSize = 4; // (0 * 2 + 1) * 4
175+
176+
// Write fileoff
177+
buffer.writeUInt32LE(50, functabOffset + functabSize);
178+
179+
// Write nfiletab at offset 50
180+
buffer.writeUInt32LE(0, 50);
181+
182+
const lt = new LineTable(buffer);
183+
expect(() => lt.go12MapFiles()).not.toThrow();
184+
});
185+
});
186+
187+
describe("Go 1.18+ format", () => {
188+
it("handles Go 1.18 format with different offsets", () => {
189+
const buffer = Buffer.alloc(200);
190+
buffer.writeUInt32LE(0xfffffff0, 0); // Go 1.18 magic
191+
buffer[4] = 0;
192+
buffer[5] = 0;
193+
buffer[6] = 1;
194+
buffer[7] = 8;
195+
196+
// offset(1) at position 16
197+
buffer.writeBigUInt64LE(0n, 16); // nfiletab
198+
199+
// offset(5) at position 48
200+
buffer.writeBigUInt64LE(100n, 48); // filetab offset
201+
202+
// offset(7) at position 64
203+
buffer.writeBigUInt64LE(120n, 64); // funcdata offset
204+
205+
// Write empty data at filetab offset
206+
buffer.writeUInt32LE(0, 100);
207+
208+
const lt = new LineTable(buffer);
209+
expect(() => lt.go12MapFiles()).not.toThrow();
210+
});
211+
});
212+
});

0 commit comments

Comments
 (0)