fix(codeql): address security and quality alerts

- arity-metadata.ts, interpret.ts: replace single-pass template strip
  regex (/<[^>]*>/g) with a while-loop to fully handle nested templates
  like Map<List<int>> — resolves 'Incomplete multi-character sanitization'
- cpp.test.ts: remove unused vitest 'it' import since the file defines
  its own 'it' via createResolverParityIt — resolves 'Assignment to constant'
- include-extractor.test.ts: use fs.mkdtempSync() instead of predictable
  os.tmpdir()+Date.now() paths — resolves 'Insecure temporary file'
- interpret.ts: remove redundant 'name !== undefined' check (already
  guaranteed by early return) — resolves 'Comparison between inconvertible types'
This commit is contained in:
HuangWenjie 2026-05-12 15:42:25 +08:00
parent 39428ee3c9
commit 8ad962f460
4 changed files with 19 additions and 12 deletions

View file

@ -127,8 +127,13 @@ function normalizeCppParamType(raw: string): string {
t = t.replace(/\b(const|volatile|restrict|mutable|constexpr)\b/g, '').trim();
// Strip reference/pointer markers
t = t.replace(/[&*]+\s*$/, '').trim();
// Strip template parameters
t = t.replace(/<[^>]*>/g, '').trim();
// Strip template parameters (loop handles nested: Map<List<int>> → Map)
while (t.includes('<')) {
const stripped = t.replace(/<[^<>]*>/g, '');
if (stripped === t) break; // avoid infinite loop on malformed input
t = stripped;
}
t = t.trim();
// Map std:: types to canonical short forms
const STD_MAP: Record<string, string> = {
'std::string': 'string',

View file

@ -64,7 +64,7 @@ export function interpretCppTypeBinding(captures: CaptureMatch): ParsedTypeBindi
// Synthesize a dotted rawName ("receiver.field") so compound-receiver
// can resolve the chain: look up receiver's class, then field's type.
const receiver = captures['@type-binding.member-access-receiver']?.text;
if (receiver !== undefined && name !== undefined) {
if (receiver !== undefined) {
return { boundName: name, rawTypeName: `${receiver}.${type}`, source: 'assignment-inferred' };
}
source = 'assignment-inferred';
@ -90,8 +90,13 @@ export function normalizeCppTypeName(text: string): string {
t = t
.replace(/\b(const|volatile|restrict|static|extern|inline|mutable|constexpr|consteval)\b/g, '')
.trim();
// Strip template parameters: List<User> → List
t = t.replace(/<[^>]*>/g, '').trim();
// Strip template parameters (loop handles nested: Map<List<int>> → Map)
while (t.includes('<')) {
const stripped = t.replace(/<[^<>]*>/g, '');
if (stripped === t) break; // avoid infinite loop on malformed input
t = stripped;
}
t = t.trim();
// Strip pointer stars
while (t.endsWith('*')) t = t.slice(0, -1).trim();
while (t.startsWith('*')) t = t.slice(1).trim();

View file

@ -1,7 +1,7 @@
/**
* C++: diamond inheritance + include-based imports + ambiguous #include disambiguation
*/
import { describe, it, expect, beforeAll } from 'vitest';
import { describe, expect, beforeAll } from 'vitest';
import path from 'path';
import {
FIXTURES,

View file

@ -11,8 +11,7 @@ describe('IncludeExtractor', () => {
let extractor: IncludeExtractor;
beforeEach(() => {
tmpDir = path.join(os.tmpdir(), `gitnexus-include-${Date.now()}`);
fs.mkdirSync(tmpDir, { recursive: true });
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gitnexus-include-'));
extractor = new IncludeExtractor();
});
@ -164,15 +163,13 @@ int main() { return 0; }`,
describe('cross-repo matching', () => {
it('provider and consumer produce matching contractIds', async () => {
// Simulate provider repo (header-only)
const providerDir = path.join(os.tmpdir(), `gitnexus-include-provider-${Date.now()}`);
fs.mkdirSync(providerDir, { recursive: true });
const providerDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gitnexus-include-provider-'));
const providerFile = path.join(providerDir, 'map/base/dice_map_view.h');
fs.mkdirSync(path.dirname(providerFile), { recursive: true });
fs.writeFileSync(providerFile, '#pragma once\nclass DiceMapView {};');
// Simulate consumer repo
const consumerDir = path.join(os.tmpdir(), `gitnexus-include-consumer-${Date.now()}`);
fs.mkdirSync(consumerDir, { recursive: true });
const consumerDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gitnexus-include-consumer-'));
const consumerFile = path.join(consumerDir, 'src/controller.cpp');
fs.mkdirSync(path.dirname(consumerFile), { recursive: true });
fs.writeFileSync(consumerFile, '#include "map/base/dice_map_view.h"\nvoid init() {}');