juice-shop
153 строки · 5.0 Кб
1import { retrieveCodeSnippet } from '../routes/vulnCodeSnippet'
2import colors from 'colors/safe'
3const Diff = require('diff')
4const fs = require('fs')
5const fixesPath = 'data/static/codefixes'
6const cacheFile = 'rsn/cache.json'
7
8type CacheData = Record<string, {
9added: number[]
10removed: number[]
11}>
12
13function readFiles () {
14const files = fs.readdirSync(fixesPath)
15const keys = files.filter((file: string) => !file.endsWith('.info.yml') && !file.endsWith('.editorconfig'))
16return keys
17}
18
19function writeToFile (json: CacheData) {
20fs.writeFileSync(cacheFile, JSON.stringify(json, null, '\t'))
21}
22
23function getDataFromFile () {
24const data = fs.readFileSync(cacheFile).toString()
25return JSON.parse(data)
26}
27
28function filterString (text: string) {
29text = text.replace(/\r/g, '')
30return text
31}
32
33const checkDiffs = async (keys: string[]) => {
34const data: CacheData = keys.reduce((prev, curr) => {
35return {
36...prev,
37[curr]: {
38added: [],
39removed: []
40}
41}
42}, {})
43for (const val of keys) {
44await retrieveCodeSnippet(val.split('_')[0])
45.then(snippet => {
46if (snippet == null) return
47process.stdout.write(val + ': ')
48const fileData = fs.readFileSync(fixesPath + '/' + val).toString()
49const diff = Diff.diffLines(filterString(fileData), filterString(snippet.snippet))
50let line = 0
51for (const part of diff) {
52if (part.removed) continue
53const prev = line
54line += part.count
55if (!(part.added)) continue
56for (let i = 0; i < part.count; i++) {
57if (!snippet.vulnLines.includes(prev + i + 1) && !snippet.neutralLines.includes(prev + i + 1)) {
58process.stdout.write(colors.red(colors.inverse(prev + i + 1 + '')))
59process.stdout.write(' ')
60data[val].added.push(prev + i + 1)
61} else if (snippet.vulnLines.includes(prev + i + 1)) {
62process.stdout.write(colors.red(colors.bold(prev + i + 1 + ' ')))
63} else if (snippet.neutralLines.includes(prev + i + 1)) {
64process.stdout.write(colors.red(prev + i + 1 + ' '))
65}
66}
67}
68line = 0
69let norm = 0
70for (const part of diff) {
71if (part.added) {
72norm--
73continue
74}
75const prev = line
76line += part.count
77if (!(part.removed)) continue
78let temp = norm
79for (let i = 0; i < part.count; i++) {
80if (!snippet.vulnLines.includes(prev + i + 1 - norm) && !snippet.neutralLines.includes(prev + i + 1 - norm)) {
81process.stdout.write(colors.green(colors.inverse((prev + i + 1 - norm + ''))))
82process.stdout.write(' ')
83data[val].removed.push(prev + i + 1 - norm)
84} else if (snippet.vulnLines.includes(prev + i + 1 - norm)) {
85process.stdout.write(colors.green(colors.bold(prev + i + 1 - norm + ' ')))
86} else if (snippet.neutralLines.includes(prev + i + 1 - norm)) {
87process.stdout.write(colors.green(prev + i + 1 - norm + ' '))
88}
89temp++
90}
91norm = temp
92}
93process.stdout.write('\n')
94})
95.catch(err => {
96console.log(err)
97})
98}
99return data
100}
101
102async function seePatch (file: string) {
103const fileData = fs.readFileSync(fixesPath + '/' + file).toString()
104const snippet = await retrieveCodeSnippet(file.split('_')[0])
105if (snippet == null) return
106const patch = Diff.structuredPatch(file, file, filterString(snippet.snippet), filterString(fileData))
107console.log(colors.bold(file + '\n'))
108for (const hunk of patch.hunks) {
109for (const line of hunk.lines) {
110if (line[0] === '-') {
111console.log(colors.red(line))
112} else if (line[0] === '+') {
113console.log(colors.green(line))
114} else {
115console.log(line)
116}
117}
118}
119console.log('---------------------------------------')
120}
121
122function checkData (data: CacheData, fileData: CacheData) {
123const filesWithDiff = []
124for (const key in data) {
125const fileDataValueAdded = fileData[key].added.sort((a, b) => a - b)
126const dataValueAdded = data[key].added.sort((a, b) => a - b)
127const fileDataValueRemoved = fileData[key].added.sort((a, b) => a - b)
128const dataValueAddedRemoved = data[key].added.sort((a, b) => a - b)
129if (fileDataValueAdded.length === dataValueAdded.length && fileDataValueRemoved.length === dataValueAddedRemoved.length) {
130if (!dataValueAdded.every((val: number, ind: number) => fileDataValueAdded[ind] === val)) {
131console.log(colors.red(key))
132filesWithDiff.push(key)
133}
134if (!dataValueAddedRemoved.every((val: number, ind: number) => fileDataValueRemoved[ind] === val)) {
135console.log(colors.red(key))
136filesWithDiff.push(key)
137}
138} else {
139console.log(colors.red(key))
140filesWithDiff.push(key)
141}
142}
143return filesWithDiff
144}
145
146export {
147checkDiffs,
148writeToFile,
149getDataFromFile,
150readFiles,
151seePatch,
152checkData
153}
154