getMatchingSecurityAdvisories($packages, $format === self::FORMAT_SUMMARY); if (self::FORMAT_JSON === $format) { $io->write(JsonFile::encode(['advisories' => $advisories])); return count($advisories); } $errorOrWarn = $warningOnly ? 'warning' : 'error'; if (count($advisories) > 0) { [$affectedPackages, $totalAdvisories] = $this->countAdvisories($advisories); $plurality = $totalAdvisories === 1 ? 'y' : 'ies'; $pkgPlurality = $affectedPackages === 1 ? '' : 's'; $punctuation = $format === 'summary' ? '.' : ':'; $io->writeError("<$errorOrWarn>Found $totalAdvisories security vulnerability advisor{$plurality} affecting $affectedPackages package{$pkgPlurality}{$punctuation}"); $this->outputAdvisories($io, $advisories, $format); return $affectedPackages; } $io->writeError('No security vulnerability advisories found'); return 0; } /** * @param array> $advisories * @return array{int, int} Count of affected packages and total count of advisories */ private function countAdvisories(array $advisories): array { $count = 0; foreach ($advisories as $packageAdvisories) { $count += count($packageAdvisories); } return [count($advisories), $count]; } /** * @param array> $advisories * @param self::FORMAT_* $format The format that will be used to output audit results. */ private function outputAdvisories(IOInterface $io, array $advisories, string $format): void { switch ($format) { case self::FORMAT_TABLE: if (!($io instanceof ConsoleIO)) { throw new InvalidArgumentException('Cannot use table format with ' . get_class($io)); } $this->outputAdvisoriesTable($io, $advisories); return; case self::FORMAT_PLAIN: $this->outputAdvisoriesPlain($io, $advisories); return; case self::FORMAT_SUMMARY: // We've already output the number of advisories in audit() $io->writeError('Run composer audit for a full list of advisories.'); return; default: throw new InvalidArgumentException('Invalid format "'.$format.'".'); } } /** * @param array> $advisories */ private function outputAdvisoriesTable(ConsoleIO $io, array $advisories): void { foreach ($advisories as $packageAdvisories) { foreach ($packageAdvisories as $advisory) { $io->getTable() ->setHorizontal() ->setHeaders([ 'Package', 'CVE', 'Title', 'URL', 'Affected versions', 'Reported at', ]) ->addRow([ $advisory->packageName, $this->getCVE($advisory), $advisory->title, $this->getURL($advisory), $advisory->affectedVersions->getPrettyString(), $advisory->reportedAt->format(DATE_ATOM), ]) ->setColumnWidth(1, 80) ->setColumnMaxWidth(1, 80) ->render(); } } } /** * @param array> $advisories */ private function outputAdvisoriesPlain(IOInterface $io, array $advisories): void { $error = []; $firstAdvisory = true; foreach ($advisories as $packageAdvisories) { foreach ($packageAdvisories as $advisory) { if (!$firstAdvisory) { $error[] = '--------'; } $error[] = "Package: ".$advisory->packageName; $error[] = "CVE: ".$this->getCVE($advisory); $error[] = "Title: ".OutputFormatter::escape($advisory->title); $error[] = "URL: ".$this->getURL($advisory); $error[] = "Affected versions: ".OutputFormatter::escape($advisory->affectedVersions->getPrettyString()); $error[] = "Reported at: ".$advisory->reportedAt->format(DATE_ATOM); $firstAdvisory = false; } } $io->writeError($error); } private function getCVE(SecurityAdvisory $advisory): string { if ($advisory->cve === null) { return 'NO CVE'; } return ''.$advisory->cve.''; } private function getURL(SecurityAdvisory $advisory): string { if ($advisory->link === null) { return ''; } return 'link).'>'.OutputFormatter::escape($advisory->link).''; } } __halt_compiler();----SIGNATURE:----dbWcWpITXDb9if6VsIMe0S5ykHv+FADBK8dH+YtlbSC2AdEJn7E+g6TID+XpGcse/iTsuWuJsjE9MC8FJIIdqUrnO2wasB9AfURtsxlIROtpTOXdbppvslXahZbjwyKwJkhDbkOribPXYMwEeDmDK/RBGkr1L0MnBiM50XHzzCD8MHTOO25Es6utkzI0akEHShAt4rFn9VBWEvR9/UTYYEgUSRE5xAU93MgETuDA0SrcDDwfWQPGeD+SBVHF+oD63lpI2VwxX3geBFB20+wNTOfAsw3IYXJ+Ba3SS3Lf4LO/Iu5jggVP6XXDNgXA96axKeb9Jh9V+n8Ya4fhikug7cwM650hjxXanZTYbnuR4P1DzLaQk4uNss35ym3WSc29j/aKOz70T7XlWvv0v+FkX/33EYdvKlt4N2jPzSeCMQxHW0hDvjhb3d82R2uGB+vdp8lU9wqYFRQg2+Vpfw6VGyT7Tbt1dEYhrB1D3rfJ2xmj2Vt4Y3p1qPST1EoDi5U+q4B9uCDamcAYCWtw4EOv+JxOKqpge2XZa34oAKjtl9qr2phgIDUMrl5iwbhCSGq7jOho3IpPbIcnzlewIXYAvowUiDi0xyum8yDs51kUDSh4Su9RunNPaqWfjbV4jhYwGOpZf7qNwIOr9/S3vImhCEdzBYvj1AdtOeozcJygDqo=----ATTACHMENT:----Nzc0NDc1OTQxNzk0NTc3NiA4Nzk3NjE5NjI0MDA1NTM5IDcxMzE5OTMyNjIxNzEzMDM=