"Fossies" - the Fresh Open Source Software Archive 
Member "cli-1.1259.0/packages/snyk-protect/src/lib/patch.ts" (30 Nov 2023, 3292 Bytes) of package /linux/misc/snyk-cli-1.1259.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TypeScript source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 import * as path from 'path';
2 import * as fs from 'fs';
3
4 export function createOldStylePatchAppliedFlagFilename(vulnId: string) {
5 const fileSafeVulnId = vulnId.replace(/:/g, '-'); // replace colon with dash for windows compatibility
6 return `.snyk-${fileSafeVulnId}.flag`;
7 }
8
9 export function applyPatchToFile(
10 patchContents: string,
11 baseFolder: string,
12 vulnId: string,
13 ) {
14 const targetFilePath = path.join(
15 baseFolder,
16 extractTargetFilePathFromPatch(patchContents),
17 );
18
19 const flagPath = `${targetFilePath}.snyk-protect.flag`;
20 const origPatchFlagPath = `${targetFilePath}.orig`;
21 if (fs.existsSync(flagPath) || fs.existsSync(origPatchFlagPath)) {
22 return targetFilePath;
23 }
24
25 const contentsToPatch = fs.readFileSync(targetFilePath, 'utf-8');
26 const patchedContents = patchString(patchContents, contentsToPatch);
27 fs.writeFileSync(targetFilePath, patchedContents);
28 fs.writeFileSync(flagPath, '');
29
30 const oldStyleFlagFilenamePath = path.resolve(
31 baseFolder,
32 createOldStylePatchAppliedFlagFilename(vulnId),
33 );
34 const now = new Date().toISOString();
35 fs.writeFileSync(oldStyleFlagFilenamePath, now);
36
37 return targetFilePath;
38 }
39
40 export function extractTargetFilePathFromPatch(patchContents: string): string {
41 const patchContentLines = patchContents
42 .slice(patchContents.search(/^--- a\//m))
43 .split('\n');
44 const filename = patchContentLines[0].replace('--- a/', '');
45 return filename;
46 }
47
48 const getNextLine = (currentLine: string, patchLine: string): string => {
49 const maybeCarriageReturn =
50 currentLine.endsWith('\r') && !patchLine.endsWith('\r') ? '\r' : '';
51 return patchLine.substring(1) + maybeCarriageReturn;
52 };
53
54 const getPatchType = (patchLine: string): string => patchLine.charAt(0);
55
56 export function patchString(
57 patchContents: string,
58 contentsToPatch: string,
59 ): string {
60 const patchContentLines = patchContents
61 .slice(patchContents.search(/^--- a\//m))
62 .split('\n');
63
64 const contentsToPatchLines = contentsToPatch.split('\n');
65
66 if (!patchContentLines[2]) {
67 throw new Error('Invalid patch.');
68 }
69 const unparsedLineToPatch = /^@@ -(\d*),.*@@/.exec(patchContentLines[2]);
70 if (!unparsedLineToPatch || !unparsedLineToPatch[1]) {
71 throw new Error('Invalid patch.');
72 }
73 let lineToPatch = parseInt(unparsedLineToPatch[1], 10) - 2;
74
75 const patchLines = patchContentLines.slice(3, patchContentLines.length - 2);
76
77 for (const patchLine of patchLines) {
78 lineToPatch += 1;
79 const currentLine = contentsToPatchLines[lineToPatch];
80 const nextLine = getNextLine(currentLine, patchLine);
81 switch (getPatchType(patchLine)) {
82 case '-': {
83 contentsToPatchLines.splice(lineToPatch, 1);
84 break;
85 }
86 case '+': {
87 contentsToPatchLines.splice(lineToPatch, 0, nextLine);
88 break;
89 }
90 case ' ': {
91 if (currentLine !== nextLine) {
92 throw new Error(
93 'File does not match patch contents.' +
94 ' Expected\n' +
95 ' line from local file\n' +
96 ` ${JSON.stringify(currentLine)}\n` +
97 ' to match patch line\n' +
98 ` ${JSON.stringify(nextLine)}\n`,
99 );
100 }
101 break;
102 }
103 }
104 }
105
106 return contentsToPatchLines.join('\n');
107 }