"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 }