coverme-security-scanner 3.7.3 → 3.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/coverme.js +0 -0
- package/bin/install-command.js +0 -0
- package/bin/merge-reports.js +0 -0
- package/dist/pdf/generator.js +56 -29
- package/package.json +1 -1
package/bin/coverme.js
CHANGED
|
File without changes
|
package/bin/install-command.js
CHANGED
|
File without changes
|
package/bin/merge-reports.js
CHANGED
|
File without changes
|
package/dist/pdf/generator.js
CHANGED
|
@@ -402,6 +402,9 @@ export class PDFGenerator {
|
|
|
402
402
|
this.y = this.doc.y + spacing.paragraph;
|
|
403
403
|
}
|
|
404
404
|
if (report.architecture?.components?.length) {
|
|
405
|
+
// Start components table on new page to keep it together
|
|
406
|
+
this.newPage();
|
|
407
|
+
this.y = spacing.page.top;
|
|
405
408
|
this.subTitle('Components');
|
|
406
409
|
this.renderSimpleTable(['Component', 'Technology', 'Description'], report.architecture.components.map(c => [c.name, c.technology, c.description]), [100, 150, 245]);
|
|
407
410
|
}
|
|
@@ -434,7 +437,6 @@ export class PDFGenerator {
|
|
|
434
437
|
this.y += 18;
|
|
435
438
|
});
|
|
436
439
|
}
|
|
437
|
-
this.checkPageBreak();
|
|
438
440
|
}
|
|
439
441
|
// ─────────────────────────────────────────────────────────────────
|
|
440
442
|
// Network
|
|
@@ -614,15 +616,20 @@ export class PDFGenerator {
|
|
|
614
616
|
const boxPadding = 12;
|
|
615
617
|
const boxInnerWidth = layout.content.width - (boxPadding * 2);
|
|
616
618
|
const style = colors.severity[finding.severity];
|
|
617
|
-
// ID in severity color, title in black
|
|
619
|
+
// ID in severity color, title in black - allow wrapping for long titles
|
|
620
|
+
const titleText = `[${finding.id}] ${finding.title}`;
|
|
621
|
+
const titleHeight = this.doc
|
|
622
|
+
.font(fonts.weights.bold)
|
|
623
|
+
.fontSize(fonts.sizes.body)
|
|
624
|
+
.heightOfString(titleText, { width: layout.content.width });
|
|
618
625
|
this.doc
|
|
619
626
|
.font(fonts.weights.bold)
|
|
620
627
|
.fontSize(fonts.sizes.body)
|
|
621
628
|
.fillColor(style.text)
|
|
622
629
|
.text(`[${finding.id}]`, spacing.page.margin, this.y, { continued: true })
|
|
623
630
|
.fillColor(colors.text.primary)
|
|
624
|
-
.text(` ${finding.title}
|
|
625
|
-
this.y
|
|
631
|
+
.text(` ${finding.title}`, { width: layout.content.width - 60 });
|
|
632
|
+
this.y = this.doc.y + 4;
|
|
626
633
|
// Cross-references and DREAD score line
|
|
627
634
|
const hasRefs = finding.relatedFindings?.length || finding.dreadScore || finding.cwe;
|
|
628
635
|
if (hasRefs) {
|
|
@@ -1141,53 +1148,73 @@ export class PDFGenerator {
|
|
|
1141
1148
|
this.y += 20;
|
|
1142
1149
|
}
|
|
1143
1150
|
renderSimpleTable(headers, rows, colWidths) {
|
|
1144
|
-
const
|
|
1151
|
+
const minRowHeight = 24;
|
|
1145
1152
|
const x = spacing.page.margin;
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
.fill(colors.table.header);
|
|
1150
|
-
let colX = x;
|
|
1151
|
-
headers.forEach((header, i) => {
|
|
1153
|
+
const cellPadding = 8;
|
|
1154
|
+
// Helper to render table header
|
|
1155
|
+
const renderHeader = () => {
|
|
1152
1156
|
this.doc
|
|
1153
|
-
.
|
|
1154
|
-
.
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1157
|
+
.rect(x, this.y, layout.content.width, minRowHeight)
|
|
1158
|
+
.fill(colors.table.header);
|
|
1159
|
+
let colX = x;
|
|
1160
|
+
headers.forEach((header, i) => {
|
|
1161
|
+
this.doc
|
|
1162
|
+
.font(fonts.weights.bold)
|
|
1163
|
+
.fontSize(fonts.sizes.small)
|
|
1164
|
+
.fillColor(colors.table.headerText)
|
|
1165
|
+
.text(header, colX + cellPadding, this.y + 7, {
|
|
1166
|
+
width: colWidths[i] - (cellPadding * 2),
|
|
1167
|
+
});
|
|
1168
|
+
colX += colWidths[i];
|
|
1158
1169
|
});
|
|
1159
|
-
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
|
|
1170
|
+
this.y += minRowHeight;
|
|
1171
|
+
};
|
|
1172
|
+
// Initial header
|
|
1173
|
+
renderHeader();
|
|
1174
|
+
// Rows - calculate dynamic height based on content
|
|
1163
1175
|
rows.forEach((row, rowIndex) => {
|
|
1164
|
-
this
|
|
1176
|
+
// Calculate the height needed for this row based on longest cell
|
|
1177
|
+
let maxCellHeight = minRowHeight;
|
|
1178
|
+
row.forEach((cell, i) => {
|
|
1179
|
+
const cellWidth = colWidths[i] - (cellPadding * 2);
|
|
1180
|
+
const textHeight = this.doc
|
|
1181
|
+
.font(fonts.weights.normal)
|
|
1182
|
+
.fontSize(fonts.sizes.small)
|
|
1183
|
+
.heightOfString(cell, { width: cellWidth });
|
|
1184
|
+
const cellHeight = Math.max(minRowHeight, textHeight + (cellPadding * 2));
|
|
1185
|
+
maxCellHeight = Math.max(maxCellHeight, cellHeight);
|
|
1186
|
+
});
|
|
1187
|
+
// Check if we need a page break - if so, re-render header on new page
|
|
1188
|
+
const needsPageBreak = this.y > layout.page.height - spacing.page.bottom - maxCellHeight - 20;
|
|
1189
|
+
if (needsPageBreak) {
|
|
1190
|
+
this.newPage();
|
|
1191
|
+
renderHeader();
|
|
1192
|
+
}
|
|
1165
1193
|
// Alternating background
|
|
1166
1194
|
if (rowIndex % 2 === 1) {
|
|
1167
1195
|
this.doc
|
|
1168
|
-
.rect(x, this.y, layout.content.width,
|
|
1196
|
+
.rect(x, this.y, layout.content.width, maxCellHeight)
|
|
1169
1197
|
.fill(colors.table.altRow);
|
|
1170
1198
|
}
|
|
1171
1199
|
// Border
|
|
1172
1200
|
this.doc
|
|
1173
|
-
.moveTo(x, this.y +
|
|
1174
|
-
.lineTo(x + layout.content.width, this.y +
|
|
1201
|
+
.moveTo(x, this.y + maxCellHeight)
|
|
1202
|
+
.lineTo(x + layout.content.width, this.y + maxCellHeight)
|
|
1175
1203
|
.strokeColor(colors.table.border)
|
|
1176
1204
|
.lineWidth(0.5)
|
|
1177
1205
|
.stroke();
|
|
1178
|
-
colX = x;
|
|
1206
|
+
let colX = x;
|
|
1179
1207
|
row.forEach((cell, i) => {
|
|
1180
1208
|
this.doc
|
|
1181
1209
|
.font(fonts.weights.normal)
|
|
1182
1210
|
.fontSize(fonts.sizes.small)
|
|
1183
1211
|
.fillColor(colors.text.primary)
|
|
1184
|
-
.text(cell, colX +
|
|
1185
|
-
width: colWidths[i] -
|
|
1186
|
-
ellipsis: true,
|
|
1212
|
+
.text(cell, colX + cellPadding, this.y + 7, {
|
|
1213
|
+
width: colWidths[i] - (cellPadding * 2),
|
|
1187
1214
|
});
|
|
1188
1215
|
colX += colWidths[i];
|
|
1189
1216
|
});
|
|
1190
|
-
this.y +=
|
|
1217
|
+
this.y += maxCellHeight;
|
|
1191
1218
|
});
|
|
1192
1219
|
this.y += spacing.paragraph;
|
|
1193
1220
|
}
|