Skip to content

Commit 2c973be

Browse files
committed
bug fix
1 parent 5e36641 commit 2c973be

8 files changed

Lines changed: 117 additions & 20 deletions

File tree

_site/admin/panel.html

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,21 +1552,26 @@
15521552
const newKey = newEntries[0]?.key || editingBibKey;
15531553
const singleBib = newBib.trim() + '\n';
15541554
if (newKey === editingBibKey) {
1555-
// Same key — update in place; fetch fresh SHA from branch
1556-
const oldPath = `${cat.dir}/${editingBibKey}.bib`;
1555+
// Same key — update in place; use stored path or derive safe filename
1556+
const oldFileObj = s.files.find(f => (f.entry?.key || f.name.replace(/\.bib$/, '')) === editingBibKey);
1557+
const oldPath = oldFileObj ? oldFileObj.path : `${cat.dir}/${safeKey(editingBibKey)}.bib`;
15571558
const shaRes = await fetch(`${GH}/contents/${oldPath}?ref=${encodeURIComponent(branch)}`, { headers: ghH() });
15581559
if (!shaRes.ok) await parseGhError(shaRes, 'Failed to read file SHA from branch');
15591560
const oldSha = (await shaRes.json()).sha;
15601561
const upRes = await fetch(`${GH}/contents/${oldPath}`, { method: 'PUT', headers: ghH(),
15611562
body: JSON.stringify({ message: `Edit ${editingBibKey} in ${cat.dir}`, content: b64e(singleBib), sha: oldSha, branch }) });
15621563
if (!upRes.ok) await parseGhError(upRes, 'Failed to update file');
15631564
} else {
1564-
// Key changed — create new file, delete old file
1565-
const newPath = `${cat.dir}/${newKey}.bib`;
1565+
// Key changed — create new file with safe unique name, delete old file
1566+
const oldFileObj2 = s.files.find(f => (f.entry?.key || f.name.replace(/\.bib$/, '')) === editingBibKey);
1567+
const oldPath = oldFileObj2 ? oldFileObj2.path : `${cat.dir}/${safeKey(editingBibKey)}.bib`;
1568+
const existingNamesForRename = new Set(s.files.filter(f => f.path !== oldPath).map(f => f.name.replace(/\.bib$/, '')));
1569+
let newBaseName = safeKey(newKey), newName = newBaseName, newSuffix = 2;
1570+
while (existingNamesForRename.has(newName)) { newName = `${newBaseName}_${newSuffix++}`; }
1571+
const newPath = `${cat.dir}/${newName}.bib`;
15661572
const crRes = await fetch(`${GH}/contents/${newPath}`, { method: 'PUT', headers: ghH(),
1567-
body: JSON.stringify({ message: `Rename ${editingBibKey} ${newKey} in ${cat.dir}`, content: b64e(singleBib), branch }) });
1573+
body: JSON.stringify({ message: `Rename ${editingBibKey} -> ${newKey} in ${cat.dir}`, content: b64e(singleBib), branch }) });
15681574
if (!crRes.ok) await parseGhError(crRes, 'Failed to create new file');
1569-
const oldPath = `${cat.dir}/${editingBibKey}.bib`;
15701575
const shaRes = await fetch(`${GH}/contents/${oldPath}?ref=${encodeURIComponent(branch)}`, { headers: ghH() });
15711576
if (!shaRes.ok) await parseGhError(shaRes, 'Failed to read old file SHA');
15721577
const oldSha = (await shaRes.json()).sha;
@@ -1575,9 +1580,14 @@
15751580
if (!delRes.ok) await parseGhError(delRes, 'Failed to delete old file');
15761581
}
15771582
} else {
1578-
// New entries — create one file per entry
1583+
// New entries — create one file per entry, using safe unique filenames
1584+
const existingNames = new Set(s.files.map(f => f.name.replace(/\.bib$/, '')));
1585+
const usedNames = new Set(existingNames);
15791586
for (const entry of newEntries) {
1580-
const filePath = `${cat.dir}/${entry.key}.bib`;
1587+
let baseName = safeKey(entry.key), name = baseName, suffix = 2;
1588+
while (usedNames.has(name)) { name = `${baseName}_${suffix++}`; }
1589+
usedNames.add(name);
1590+
const filePath = `${cat.dir}/${name}.bib`;
15811591
const singleBib = (extractRawBibEntry(newBib, entry.key) || newBib).trim() + '\n';
15821592
const crRes = await fetch(`${GH}/contents/${filePath}`, { method: 'PUT', headers: ghH(),
15831593
body: JSON.stringify({ message: `Add ${entry.key} to ${cat.dir}`, content: b64e(singleBib), branch }) });
@@ -1799,7 +1809,7 @@
17991809
body: JSON.stringify({ ref: `refs/heads/${branch}`, sha: baseSha }) });
18001810
if (!branchRes.ok) await parseGhError(branchRes, 'Failed to create branch');
18011811
// Fetch fresh SHA of the file from the new branch
1802-
const filePath = fileObj ? fileObj.path : `${cat.dir}/${key}.bib`;
1812+
const filePath = fileObj ? fileObj.path : `${cat.dir}/${safeKey(key)}.bib`;
18031813
const shaRes = await fetch(`${GH}/contents/${filePath}?ref=${encodeURIComponent(branch)}`, { headers: ghH() });
18041814
if (!shaRes.ok) await parseGhError(shaRes, 'Failed to read file SHA from branch');
18051815
const fileSha = (await shaRes.json()).sha;
@@ -1908,12 +1918,19 @@
19081918
validateInput();
19091919
}
19101920

1921+
function safeKey(key) { return key.replace(/[^\w\-]/g, '_'); }
1922+
19111923
function parseBib(raw) {
19121924
const out = [];
19131925
const re = /@(\w+)\s*\{\s*([^,\s]+)\s*,([^@]*)/gs;
19141926
let m;
1915-
while ((m = re.exec(raw)) !== null)
1927+
while ((m = re.exec(raw)) !== null) {
1928+
// Validate brace balance: body should have exactly one more } than {
1929+
let depth = 0;
1930+
for (const c of m[3]) { if (c === '{') depth++; else if (c === '}') depth--; }
1931+
if (depth !== -1) continue; // unbalanced — missing closing brace, skip
19161932
out.push({ type: m[1].toLowerCase(), key: m[2].trim(), fields: parseFields(m[3]) });
1933+
}
19171934
return out;
19181935
}
19191936
function parseFields(body) {
File renamed without changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@INPROCEEDINGS{Dellapenna2025CTI-HAL,
2+
author={Della Penna, Sofia and Natella, Roberto and Orbinato, Vittorio and Parracino, Lorenzo and Pianese, Luciano},
3+
booktitle={2025 IEEE European Symposium on Security and Privacy Workshops (EuroS&PW)},
4+
title={CTI-HAL: A Human-Annotated Dataset for Cyber Threat Intelligence Analysis},
5+
year={2025},
6+
volume={},
7+
number={},
8+
pages={69-78},
9+
keywords={Performance evaluation;Accuracy;Large language models;Natural languages;Blogs;Organizations;Cyber threat intelligence;Reliability;Data mining;Computer security;Cyber Threat Intelligence;MITRE ATT&CK;Advanced Persistent Threats;Large Language Models;Cybersecurity},
10+
doi={10.1109/EuroSPW67616.2025.00014}}

_site/bib/conference/cti-hal.bib

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@inproceedings{cti-hal,
2+
author={Della Penna, Sofia and Natella, Roberto and Orbinato, Vittorio and Parracino, Lorenzo and Pianese, Luciano},
3+
booktitle={2025 IEEE European Symposium on Security and Privacy Workshops (EuroS&PW)},
4+
title={CTI-HAL: A Human-Annotated Dataset for Cyber Threat Intelligence Analysis},
5+
year={2025},
6+
volume={},
7+
number={},
8+
pages={69-78},
9+
keywords={Performance evaluation;Accuracy;Large language models;Natural languages;Blogs;Organizations;Cyber threat intelligence;Reliability;Data mining;Computer security;Cyber Threat Intelligence;MITRE ATT&CK;Advanced Persistent Threats;Large Language Models;Cybersecurity},
10+
doi={10.1109/EuroSPW67616.2025.00014}}

_site/bib/journal/11091601.bib

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@ARTICLE{11091601,
2+
author={Feng, Ruijun and Pearce, Hammond and Liguori, Pietro and Sui, Yulei},
3+
journal={ IEEE Transactions on Software Engineering },
4+
title={{ CGP-Tuning: Structure-Aware Soft Prompt Tuning for Code Vulnerability Detection }},
5+
year={2025},
6+
volume={51},
7+
number={09},
8+
ISSN={1939-3520},
9+
pages={2533-2548},
10+
abstract={ Large language models (LLMs) have been proposed as powerful tools for detecting software vulnerabilities, where task-specific fine-tuning is typically employed to provide vulnerability-specific knowledge to the LLMs. However, existing fine-tuning techniques often treat source code as plain text, losing the graph-based structural information inherent in code. Graph-enhanced soft prompt tuning addresses this by translating the structural information into contextual cues that the LLM can understand. However, current methods are primarily designed for general graph-related tasks and focus more on adjacency information, they fall short in preserving the rich semantic information (e.g., control/data flow) within code graphs. They also fail to ensure computational efficiency while capturing graph-text interactions in their cross-modal alignment module. This paper presents CGP-Tuning, a new code graph-enhanced, structure-aware soft prompt tuning method for vulnerability detection. CGP-Tuning introduces type-aware embeddings to capture the rich semantic information within code graphs, along with an efficient cross-modal alignment module that achieves linear computational costs while incorporating graph-text interactions. It is evaluated on the latest DiverseVul dataset and three advanced open-source code LLMs, CodeLlama, CodeGemma, and Qwen2.5-Coder. Experimental results show that CGP-Tuning delivers model-agnostic improvements and maintains practical inference speed, surpassing the best graph-enhanced soft prompt tuning baseline by an average of four percentage points and outperforming non-tuned zero-shot prompting by 15 percentage points. },
11+
keywords={Codes;Tuning;Source coding;Semantics;Computational efficiency;Graph neural networks;Large language models;Computational modeling;Training;Static analysis},
12+
doi={10.1109/TSE.2025.3591934},
13+
url = {https://doi.ieeecomputersociety.org/10.1109/TSE.2025.3591934},
14+
publisher={IEEE Computer Society},
15+
address={Los Alamitos, CA, USA},
16+
month=sep}}

_site/bib/journal/11121437.bib

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@ARTICLE{11121437,
2+
author={Cinque, Marcello and Cotroneo, Domenico and De Rosa, Giuseppe and De Simone, Luigi and Farina, Giorgio},
3+
journal={IEEE Transactions on Dependable and Secure Computing},
4+
title={COSMOS: A Fault Injection Framework to Assess Hardware-Assisted Hypervisors},
5+
year={2025},
6+
volume={22},
7+
number={6},
8+
pages={7448-7462},
9+
keywords={Virtual machine monitors;Virtual machines;Hardware;Software;Transient analysis;Robustness;Switches;Fault tolerant systems;Fault tolerance;Training;Cloud computing;virtualization;software fault injection;robustness;intel VT-x},
10+
doi={10.1109/TDSC.2025.3597103}}

admin/panel.html

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,21 +1552,26 @@
15521552
const newKey = newEntries[0]?.key || editingBibKey;
15531553
const singleBib = newBib.trim() + '\n';
15541554
if (newKey === editingBibKey) {
1555-
// Same key — update in place; fetch fresh SHA from branch
1556-
const oldPath = `${cat.dir}/${editingBibKey}.bib`;
1555+
// Same key — update in place; use stored path or derive safe filename
1556+
const oldFileObj = s.files.find(f => (f.entry?.key || f.name.replace(/\.bib$/, '')) === editingBibKey);
1557+
const oldPath = oldFileObj ? oldFileObj.path : `${cat.dir}/${safeKey(editingBibKey)}.bib`;
15571558
const shaRes = await fetch(`${GH}/contents/${oldPath}?ref=${encodeURIComponent(branch)}`, { headers: ghH() });
15581559
if (!shaRes.ok) await parseGhError(shaRes, 'Failed to read file SHA from branch');
15591560
const oldSha = (await shaRes.json()).sha;
15601561
const upRes = await fetch(`${GH}/contents/${oldPath}`, { method: 'PUT', headers: ghH(),
15611562
body: JSON.stringify({ message: `Edit ${editingBibKey} in ${cat.dir}`, content: b64e(singleBib), sha: oldSha, branch }) });
15621563
if (!upRes.ok) await parseGhError(upRes, 'Failed to update file');
15631564
} else {
1564-
// Key changed — create new file, delete old file
1565-
const newPath = `${cat.dir}/${newKey}.bib`;
1565+
// Key changed — create new file with safe unique name, delete old file
1566+
const oldFileObj2 = s.files.find(f => (f.entry?.key || f.name.replace(/\.bib$/, '')) === editingBibKey);
1567+
const oldPath = oldFileObj2 ? oldFileObj2.path : `${cat.dir}/${safeKey(editingBibKey)}.bib`;
1568+
const existingNamesForRename = new Set(s.files.filter(f => f.path !== oldPath).map(f => f.name.replace(/\.bib$/, '')));
1569+
let newBaseName = safeKey(newKey), newName = newBaseName, newSuffix = 2;
1570+
while (existingNamesForRename.has(newName)) { newName = `${newBaseName}_${newSuffix++}`; }
1571+
const newPath = `${cat.dir}/${newName}.bib`;
15661572
const crRes = await fetch(`${GH}/contents/${newPath}`, { method: 'PUT', headers: ghH(),
1567-
body: JSON.stringify({ message: `Rename ${editingBibKey} ${newKey} in ${cat.dir}`, content: b64e(singleBib), branch }) });
1573+
body: JSON.stringify({ message: `Rename ${editingBibKey} -> ${newKey} in ${cat.dir}`, content: b64e(singleBib), branch }) });
15681574
if (!crRes.ok) await parseGhError(crRes, 'Failed to create new file');
1569-
const oldPath = `${cat.dir}/${editingBibKey}.bib`;
15701575
const shaRes = await fetch(`${GH}/contents/${oldPath}?ref=${encodeURIComponent(branch)}`, { headers: ghH() });
15711576
if (!shaRes.ok) await parseGhError(shaRes, 'Failed to read old file SHA');
15721577
const oldSha = (await shaRes.json()).sha;
@@ -1575,9 +1580,14 @@
15751580
if (!delRes.ok) await parseGhError(delRes, 'Failed to delete old file');
15761581
}
15771582
} else {
1578-
// New entries — create one file per entry
1583+
// New entries — create one file per entry, using safe unique filenames
1584+
const existingNames = new Set(s.files.map(f => f.name.replace(/\.bib$/, '')));
1585+
const usedNames = new Set(existingNames);
15791586
for (const entry of newEntries) {
1580-
const filePath = `${cat.dir}/${entry.key}.bib`;
1587+
let baseName = safeKey(entry.key), name = baseName, suffix = 2;
1588+
while (usedNames.has(name)) { name = `${baseName}_${suffix++}`; }
1589+
usedNames.add(name);
1590+
const filePath = `${cat.dir}/${name}.bib`;
15811591
const singleBib = (extractRawBibEntry(newBib, entry.key) || newBib).trim() + '\n';
15821592
const crRes = await fetch(`${GH}/contents/${filePath}`, { method: 'PUT', headers: ghH(),
15831593
body: JSON.stringify({ message: `Add ${entry.key} to ${cat.dir}`, content: b64e(singleBib), branch }) });
@@ -1799,7 +1809,7 @@
17991809
body: JSON.stringify({ ref: `refs/heads/${branch}`, sha: baseSha }) });
18001810
if (!branchRes.ok) await parseGhError(branchRes, 'Failed to create branch');
18011811
// Fetch fresh SHA of the file from the new branch
1802-
const filePath = fileObj ? fileObj.path : `${cat.dir}/${key}.bib`;
1812+
const filePath = fileObj ? fileObj.path : `${cat.dir}/${safeKey(key)}.bib`;
18031813
const shaRes = await fetch(`${GH}/contents/${filePath}?ref=${encodeURIComponent(branch)}`, { headers: ghH() });
18041814
if (!shaRes.ok) await parseGhError(shaRes, 'Failed to read file SHA from branch');
18051815
const fileSha = (await shaRes.json()).sha;
@@ -1908,12 +1918,19 @@
19081918
validateInput();
19091919
}
19101920

1921+
function safeKey(key) { return key.replace(/[^\w\-]/g, '_'); }
1922+
19111923
function parseBib(raw) {
19121924
const out = [];
19131925
const re = /@(\w+)\s*\{\s*([^,\s]+)\s*,([^@]*)/gs;
19141926
let m;
1915-
while ((m = re.exec(raw)) !== null)
1927+
while ((m = re.exec(raw)) !== null) {
1928+
// Validate brace balance: body should have exactly one more } than {
1929+
let depth = 0;
1930+
for (const c of m[3]) { if (c === '{') depth++; else if (c === '}') depth--; }
1931+
if (depth !== -1) continue; // unbalanced — missing closing brace, skip
19161932
out.push({ type: m[1].toLowerCase(), key: m[2].trim(), fields: parseFields(m[3]) });
1933+
}
19171934
return out;
19181935
}
19191936
function parseFields(body) {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@inproceedings{10.1145/3722041.3723097,
2+
author = {Cotroneo, Domenico and Grasso, Francesco C. and Natella, Roberto and Orbinato, Vittorio},
3+
title = {Can Neural Decompilation Assist Vulnerability Prediction on Binary Code?},
4+
year = {2025},
5+
isbn = {9798400715631},
6+
publisher = {Association for Computing Machinery},
7+
address = {New York, NY, USA},
8+
url = {https://doi.org/10.1145/3722041.3723097},
9+
doi = {10.1145/3722041.3723097},
10+
abstract = {Vulnerability prediction is valuable in identifying security issues efficiently, even though it requires the source code of the target software system, which is a restrictive hypothesis. This paper presents an experimental study to predict vulnerabilities in binary code without source code or complex representations of the binary, leveraging the pivotal idea of decompiling the binary file through neural decompilation and predicting vulnerabilities through deep learning on the decompiled source code. The results outperform the state-of-the-art in both neural decompilation and vulnerability prediction, showing that it is possible to identify vulnerable programs with this approach concerning bi-class (vulnerable/non-vulnerable) and multi-class (type of vulnerability) analysis.},
11+
booktitle = {Proceedings of the 18th European Workshop on Systems Security},
12+
pages = {26–32},
13+
numpages = {7},
14+
keywords = {Binary Analysis, Deep Learning, Neural Decompilation, Security, Vulnerability Prediction},
15+
location = {Rotterdam, Netherlands},
16+
series = {EuroSec'25}
17+
}

0 commit comments

Comments
 (0)