PHP parser composer.lock (#609)

* PHP parse composer.lock

Signed-off-by: Nikita <33390074+Zilborg@users.noreply.github.com>

* rename PHP package type

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add PHP composer package support to source info SPDX helper

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* update directory cataloger integration tests (make exception for images)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

Co-authored-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Nikita 2021-11-10 22:08:41 +03:00 committed by GitHub
parent 319c6ee2eb
commit 25835ef589
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 736 additions and 2 deletions

View File

@ -31,6 +31,8 @@ func SourceInfo(p *pkg.Package) string {
answer = "acquired package info from go module information"
case pkg.RustPkg:
answer = "acquired package info from rust cargo manifest"
case pkg.PhpComposerPkg:
answer = "acquired package info from PHP composer manifest"
default:
answer = "acquired package info from the following paths"
}

View File

@ -124,6 +124,14 @@ func Test_SourceInfo(t *testing.T) {
"from rust cargo manifest",
},
},
{
input: pkg.Package{
Type: pkg.PhpComposerPkg,
},
expected: []string{
"from PHP composer manifest",
},
},
}
var pkgTypes []pkg.Type
for _, test := range tests {

View File

@ -12,6 +12,7 @@ import (
"github.com/anchore/syft/syft/pkg/cataloger/golang"
"github.com/anchore/syft/syft/pkg/cataloger/java"
"github.com/anchore/syft/syft/pkg/cataloger/javascript"
"github.com/anchore/syft/syft/pkg/cataloger/php"
"github.com/anchore/syft/syft/pkg/cataloger/python"
"github.com/anchore/syft/syft/pkg/cataloger/rpmdb"
"github.com/anchore/syft/syft/pkg/cataloger/ruby"
@ -49,6 +50,7 @@ func DirectoryCatalogers() []Cataloger {
ruby.NewGemFileLockCataloger(),
python.NewPythonIndexCataloger(),
python.NewPythonPackageCataloger(),
php.NewPHPIndexCataloger(),
javascript.NewJavascriptLockCataloger(),
deb.NewDpkgdbCataloger(),
rpmdb.NewRpmdbCataloger(),

View File

@ -0,0 +1,17 @@
/*
Package python provides a concrete Cataloger implementation for Python ecosystem files (egg, wheel, requirements.txt).
*/
package php
import (
"github.com/anchore/syft/syft/pkg/cataloger/common"
)
// NewPythonIndexCataloger returns a new cataloger for python packages referenced from poetry lock files, requirements.txt files, and setup.py files.
func NewPHPIndexCataloger() *common.GenericCataloger {
globParsers := map[string]common.ParserFn{
"**/composer.lock": parseComposerLock,
}
return common.NewGenericCataloger(nil, globParsers, "php-index-cataloger")
}

View File

@ -0,0 +1,50 @@
package php
import (
"encoding/json"
"fmt"
"io"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/common"
)
type ComposerLock struct {
Packages []Dependency `json:"packages"`
PackageDev []Dependency `json:"packages-dev"`
}
type Dependency struct {
Name string `json:"name"`
Version string `json:"version"`
}
// integrity check
var _ common.ParserFn = parseComposerLock
// parseComposerLock is a parser function for Composer.lock contents, returning "Default" php packages discovered.
func parseComposerLock(_ string, reader io.Reader) ([]pkg.Package, error) {
packages := make([]pkg.Package, 0)
dec := json.NewDecoder(reader)
for {
var lock ComposerLock
if err := dec.Decode(&lock); err == io.EOF {
break
} else if err != nil {
return nil, fmt.Errorf("failed to parse composer.lock file: %w", err)
}
for _, pkgMeta := range lock.Packages {
version := pkgMeta.Version
name := pkgMeta.Name
packages = append(packages, pkg.Package{
Name: name,
Version: version,
Language: pkg.PHP,
Type: pkg.PhpComposerPkg,
})
}
}
return packages, nil
}

View File

@ -0,0 +1,40 @@
package php
import (
"os"
"testing"
"github.com/anchore/syft/syft/pkg"
"github.com/go-test/deep"
)
func TestParseComposerFileLock(t *testing.T) {
expected := []pkg.Package{
{
Name: "adoy/fastcgi-client",
Version: "1.0.2",
Language: pkg.PHP,
Type: pkg.PhpComposerPkg,
},
{
Name: "alcaeus/mongo-php-adapter",
Version: "1.1.11",
Language: pkg.PHP,
Type: pkg.PhpComposerPkg,
},
}
fixture, err := os.Open("test-fixtures/composer.lock")
if err != nil {
t.Fatalf("failed to open fixture: %+v", err)
}
actual, err := parseComposerLock(fixture.Name(), fixture)
if err != nil {
t.Fatalf("failed to parse requirements: %+v", err)
}
differences := deep.Equal(expected, actual)
if differences != nil {
t.Errorf("returned package list differed from expectation: %+v", differences)
}
}

View File

@ -0,0 +1,298 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "746ba78c06aef0cf954135ea909f9eb9",
"packages": [
{
"name": "adoy/fastcgi-client",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/adoy/PHP-FastCGI-Client.git",
"reference": "6d9a552f0206a1db7feb442824540aa6c55e5b27"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/adoy/PHP-FastCGI-Client/zipball/6d9a552f0206a1db7feb442824540aa6c55e5b27",
"reference": "6d9a552f0206a1db7feb442824540aa6c55e5b27",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-0": {
"Adoy\\FastCGI\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Pierrick Charron",
"email": "pierrick@adoy.net"
}
],
"description": "Lightweight, single file FastCGI client for PHP.",
"keywords": [
"fastcgi",
"fcgi"
],
"time": "2019-12-11T13:49:21+00:00"
},
{
"name": "alcaeus/mongo-php-adapter",
"version": "1.1.11",
"source": {
"type": "git",
"url": "https://github.com/alcaeus/mongo-php-adapter.git",
"reference": "43b6add94c8b4cb9890d662cba4c0defde733dcf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/alcaeus/mongo-php-adapter/zipball/43b6add94c8b4cb9890d662cba4c0defde733dcf",
"reference": "43b6add94c8b4cb9890d662cba4c0defde733dcf",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-hash": "*",
"ext-mongodb": "^1.2.0",
"mongodb/mongodb": "^1.0.1",
"php": "^5.6 || ^7.0"
},
"provide": {
"ext-mongo": "1.6.14"
},
"require-dev": {
"phpunit/phpunit": "^5.7.27 || ^6.0 || ^7.0",
"squizlabs/php_codesniffer": "^3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-0": {
"Mongo": "lib/Mongo"
},
"psr-4": {
"Alcaeus\\MongoDbAdapter\\": "lib/Alcaeus/MongoDbAdapter"
},
"files": [
"lib/Mongo/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "alcaeus",
"email": "alcaeus@alcaeus.org"
},
{
"name": "Olivier Lechevalier",
"email": "olivier.lechevalier@gmail.com"
}
],
"description": "Adapter to provide ext-mongo interface on top of mongo-php-libary",
"keywords": [
"database",
"mongodb"
],
"time": "2019-11-11T20:47:32+00:00"
}
],
"packages-dev": [
{
"name": "behat/gherkin",
"version": "v4.6.2",
"source": {
"type": "git",
"url": "https://github.com/Behat/Gherkin.git",
"reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Behat/Gherkin/zipball/51ac4500c4dc30cbaaabcd2f25694299df666a31",
"reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31",
"shasum": ""
},
"require": {
"php": ">=5.3.1"
},
"require-dev": {
"phpunit/phpunit": "~4.5|~5",
"symfony/phpunit-bridge": "~2.7|~3|~4",
"symfony/yaml": "~2.3|~3|~4"
},
"suggest": {
"symfony/yaml": "If you want to parse features, represented in YAML files"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.4-dev"
}
},
"autoload": {
"psr-0": {
"Behat\\Gherkin": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
}
],
"description": "Gherkin DSL parser for PHP 5.3",
"homepage": "http://behat.org/",
"keywords": [
"BDD",
"Behat",
"Cucumber",
"DSL",
"gherkin",
"parser"
],
"time": "2020-03-17T14:03:26+00:00"
},
{
"name": "codeception/codeception",
"version": "4.1.6",
"source": {
"type": "git",
"url": "https://github.com/Codeception/Codeception.git",
"reference": "5515b6a6c6f1e1c909aaff2e5f3a15c177dfd1a9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/5515b6a6c6f1e1c909aaff2e5f3a15c177dfd1a9",
"reference": "5515b6a6c6f1e1c909aaff2e5f3a15c177dfd1a9",
"shasum": ""
},
"require": {
"behat/gherkin": "^4.4.0",
"codeception/lib-asserts": "^1.0",
"codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.1.1 | ^9.0",
"codeception/stub": "^2.0 | ^3.0",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"guzzlehttp/psr7": "~1.4",
"php": ">=5.6.0 <8.0",
"symfony/console": ">=2.7 <6.0",
"symfony/css-selector": ">=2.7 <6.0",
"symfony/event-dispatcher": ">=2.7 <6.0",
"symfony/finder": ">=2.7 <6.0",
"symfony/yaml": ">=2.7 <6.0"
},
"require-dev": {
"codeception/module-asserts": "*@dev",
"codeception/module-cli": "*@dev",
"codeception/module-db": "*@dev",
"codeception/module-filesystem": "*@dev",
"codeception/module-phpbrowser": "*@dev",
"codeception/specify": "~0.3",
"codeception/util-universalframework": "*@dev",
"monolog/monolog": "~1.8",
"squizlabs/php_codesniffer": "~2.0",
"symfony/process": ">=2.7 <6.0",
"vlucas/phpdotenv": "^2.0 | ^3.0 | ^4.0"
},
"suggest": {
"codeception/specify": "BDD-style code blocks",
"codeception/verify": "BDD-style assertions",
"hoa/console": "For interactive console functionality",
"stecman/symfony-console-completion": "For BASH autocompletion",
"symfony/phpunit-bridge": "For phpunit-bridge support"
},
"bin": [
"codecept"
],
"type": "library",
"extra": {
"branch-alias": []
},
"autoload": {
"psr-4": {
"Codeception\\": "src/Codeception",
"Codeception\\Extension\\": "ext"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Bodnarchuk",
"email": "davert@mail.ua",
"homepage": "http://codegyre.com"
}
],
"description": "BDD-style testing framework",
"homepage": "http://codeception.com/",
"keywords": [
"BDD",
"TDD",
"acceptance testing",
"functional testing",
"unit testing"
],
"time": "2020-06-07T16:31:51+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"intelligence/bt-base": 20,
"intelligence/bt-common": 20,
"intelligence/bt-lib-tools": 20,
"intelligence/ci-lib-cache": 20,
"intelligence/ci-lib-client": 20,
"intelligence/ci-lib-contributed": 20,
"intelligence/ci-lib-eav": 20,
"intelligence/ci-lib-report": 20,
"intelligence/git-leaks-elastic-client": 20,
"intelligence/phishing-elastic-client": 20,
"libs/gib-sso-client": 20,
"mozhin/phplib": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^7.4.0",
"ext-amqp": "^1.9",
"ext-ctype": "*",
"ext-curl": "^7.4",
"ext-date": "^7.4",
"ext-fileinfo": "*",
"ext-geoip": "^1.1",
"ext-gettext": "*",
"ext-iconv": "*",
"ext-imagick": "^3.4",
"ext-imap": "^7.4",
"ext-intl": "^7.4",
"ext-json": "*",
"ext-mbstring": "^7.4",
"ext-mongodb": "^1.4",
"ext-mysqli": "^7.4",
"ext-pdo_mysql": "^7.4",
"ext-redis": ">=3.1"
},
"platform-dev": []
}

View File

@ -9,6 +9,7 @@ const (
Java Language = "java"
JavaScript Language = "javascript"
Python Language = "python"
PHP Language = "php"
Ruby Language = "ruby"
Go Language = "go"
Rust Language = "rust"
@ -19,6 +20,7 @@ var AllLanguages = []Language{
Java,
JavaScript,
Python,
PHP,
Ruby,
Go,
Rust,

View File

@ -14,6 +14,7 @@ const (
RpmPkg Type = "rpm"
NpmPkg Type = "npm"
PythonPkg Type = "python"
PhpComposerPkg Type = "php-composer"
JavaPkg Type = "java-archive"
JenkinsPluginPkg Type = "jenkins-plugin"
GoModulePkg Type = "go-module"
@ -29,6 +30,7 @@ var AllPkgs = []Type{
RpmPkg,
NpmPkg,
PythonPkg,
PhpComposerPkg,
JavaPkg,
JenkinsPluginPkg,
GoModulePkg,
@ -47,6 +49,8 @@ func (t Type) PackageURLType() string {
return "deb"
case PythonPkg:
return packageurl.TypePyPi
case PhpComposerPkg:
return packageurl.TypeComposer
case NpmPkg:
return packageurl.TypeNPM
case JavaPkg, JenkinsPluginPkg:

View File

@ -167,6 +167,15 @@ var dirOnlyTestCases = []testCase{
"libc-utils": "0.7.2-r0",
},
},
{
name: "find php composer package",
pkgType: pkg.PhpComposerPkg,
pkgLanguage: pkg.PHP,
pkgInfo: map[string]string{
"adoy/fastcgi-client": "1.0.2",
"alcaeus/mongo-php-adapter": "1.1.11",
},
},
}
var commonTestCases = []testCase{

View File

@ -57,9 +57,10 @@ func TestPkgCoverageImage(t *testing.T) {
definedLanguages.Add(l.String())
}
// for image we remove the go mod and rust support by default
// for image scans we should not expect to see any of the following package types
definedLanguages.Remove(pkg.Go.String())
definedLanguages.Remove(pkg.Rust.String())
definedLanguages.Remove(pkg.PHP.String())
observedPkgs := internal.NewStringSet()
definedPkgs := internal.NewStringSet()
@ -67,10 +68,11 @@ func TestPkgCoverageImage(t *testing.T) {
definedPkgs.Add(string(p))
}
// for image we remove the go-module and rust-crate support by default
// for image scans we should not expect to see any of the following package types
definedPkgs.Remove(string(pkg.KbPkg))
definedPkgs.Remove(string(pkg.GoModulePkg))
definedPkgs.Remove(string(pkg.RustPkg))
definedPkgs.Remove(string(pkg.PhpComposerPkg))
var cases []testCase
cases = append(cases, commonTestCases...)
@ -195,6 +197,8 @@ func TestPkgCoverageDirectory(t *testing.T) {
definedLanguages.Remove(pkg.UnknownLanguage.String())
observedPkgs.Remove(string(pkg.UnknownPkg))
definedPkgs.Remove(string(pkg.UnknownPkg))
// for directory scans we should not expect to see any of the following package types
definedPkgs.Remove(string(pkg.KbPkg))
// ensure that integration test commonTestCases stay in sync with the available catalogers

View File

@ -0,0 +1,298 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "746ba78c06aef0cf954135ea909f9eb9",
"packages": [
{
"name": "adoy/fastcgi-client",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/adoy/PHP-FastCGI-Client.git",
"reference": "6d9a552f0206a1db7feb442824540aa6c55e5b27"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/adoy/PHP-FastCGI-Client/zipball/6d9a552f0206a1db7feb442824540aa6c55e5b27",
"reference": "6d9a552f0206a1db7feb442824540aa6c55e5b27",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-0": {
"Adoy\\FastCGI\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Pierrick Charron",
"email": "pierrick@adoy.net"
}
],
"description": "Lightweight, single file FastCGI client for PHP.",
"keywords": [
"fastcgi",
"fcgi"
],
"time": "2019-12-11T13:49:21+00:00"
},
{
"name": "alcaeus/mongo-php-adapter",
"version": "1.1.11",
"source": {
"type": "git",
"url": "https://github.com/alcaeus/mongo-php-adapter.git",
"reference": "43b6add94c8b4cb9890d662cba4c0defde733dcf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/alcaeus/mongo-php-adapter/zipball/43b6add94c8b4cb9890d662cba4c0defde733dcf",
"reference": "43b6add94c8b4cb9890d662cba4c0defde733dcf",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-hash": "*",
"ext-mongodb": "^1.2.0",
"mongodb/mongodb": "^1.0.1",
"php": "^5.6 || ^7.0"
},
"provide": {
"ext-mongo": "1.6.14"
},
"require-dev": {
"phpunit/phpunit": "^5.7.27 || ^6.0 || ^7.0",
"squizlabs/php_codesniffer": "^3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-0": {
"Mongo": "lib/Mongo"
},
"psr-4": {
"Alcaeus\\MongoDbAdapter\\": "lib/Alcaeus/MongoDbAdapter"
},
"files": [
"lib/Mongo/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "alcaeus",
"email": "alcaeus@alcaeus.org"
},
{
"name": "Olivier Lechevalier",
"email": "olivier.lechevalier@gmail.com"
}
],
"description": "Adapter to provide ext-mongo interface on top of mongo-php-libary",
"keywords": [
"database",
"mongodb"
],
"time": "2019-11-11T20:47:32+00:00"
}
],
"packages-dev": [
{
"name": "behat/gherkin",
"version": "v4.6.2",
"source": {
"type": "git",
"url": "https://github.com/Behat/Gherkin.git",
"reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Behat/Gherkin/zipball/51ac4500c4dc30cbaaabcd2f25694299df666a31",
"reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31",
"shasum": ""
},
"require": {
"php": ">=5.3.1"
},
"require-dev": {
"phpunit/phpunit": "~4.5|~5",
"symfony/phpunit-bridge": "~2.7|~3|~4",
"symfony/yaml": "~2.3|~3|~4"
},
"suggest": {
"symfony/yaml": "If you want to parse features, represented in YAML files"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.4-dev"
}
},
"autoload": {
"psr-0": {
"Behat\\Gherkin": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
}
],
"description": "Gherkin DSL parser for PHP 5.3",
"homepage": "http://behat.org/",
"keywords": [
"BDD",
"Behat",
"Cucumber",
"DSL",
"gherkin",
"parser"
],
"time": "2020-03-17T14:03:26+00:00"
},
{
"name": "codeception/codeception",
"version": "4.1.6",
"source": {
"type": "git",
"url": "https://github.com/Codeception/Codeception.git",
"reference": "5515b6a6c6f1e1c909aaff2e5f3a15c177dfd1a9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/5515b6a6c6f1e1c909aaff2e5f3a15c177dfd1a9",
"reference": "5515b6a6c6f1e1c909aaff2e5f3a15c177dfd1a9",
"shasum": ""
},
"require": {
"behat/gherkin": "^4.4.0",
"codeception/lib-asserts": "^1.0",
"codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.1.1 | ^9.0",
"codeception/stub": "^2.0 | ^3.0",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"guzzlehttp/psr7": "~1.4",
"php": ">=5.6.0 <8.0",
"symfony/console": ">=2.7 <6.0",
"symfony/css-selector": ">=2.7 <6.0",
"symfony/event-dispatcher": ">=2.7 <6.0",
"symfony/finder": ">=2.7 <6.0",
"symfony/yaml": ">=2.7 <6.0"
},
"require-dev": {
"codeception/module-asserts": "*@dev",
"codeception/module-cli": "*@dev",
"codeception/module-db": "*@dev",
"codeception/module-filesystem": "*@dev",
"codeception/module-phpbrowser": "*@dev",
"codeception/specify": "~0.3",
"codeception/util-universalframework": "*@dev",
"monolog/monolog": "~1.8",
"squizlabs/php_codesniffer": "~2.0",
"symfony/process": ">=2.7 <6.0",
"vlucas/phpdotenv": "^2.0 | ^3.0 | ^4.0"
},
"suggest": {
"codeception/specify": "BDD-style code blocks",
"codeception/verify": "BDD-style assertions",
"hoa/console": "For interactive console functionality",
"stecman/symfony-console-completion": "For BASH autocompletion",
"symfony/phpunit-bridge": "For phpunit-bridge support"
},
"bin": [
"codecept"
],
"type": "library",
"extra": {
"branch-alias": []
},
"autoload": {
"psr-4": {
"Codeception\\": "src/Codeception",
"Codeception\\Extension\\": "ext"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Bodnarchuk",
"email": "davert@mail.ua",
"homepage": "http://codegyre.com"
}
],
"description": "BDD-style testing framework",
"homepage": "http://codeception.com/",
"keywords": [
"BDD",
"TDD",
"acceptance testing",
"functional testing",
"unit testing"
],
"time": "2020-06-07T16:31:51+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"intelligence/bt-base": 20,
"intelligence/bt-common": 20,
"intelligence/bt-lib-tools": 20,
"intelligence/ci-lib-cache": 20,
"intelligence/ci-lib-client": 20,
"intelligence/ci-lib-contributed": 20,
"intelligence/ci-lib-eav": 20,
"intelligence/ci-lib-report": 20,
"intelligence/git-leaks-elastic-client": 20,
"intelligence/phishing-elastic-client": 20,
"libs/gib-sso-client": 20,
"mozhin/phplib": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^7.4.0",
"ext-amqp": "^1.9",
"ext-ctype": "*",
"ext-curl": "^7.4",
"ext-date": "^7.4",
"ext-fileinfo": "*",
"ext-geoip": "^1.1",
"ext-gettext": "*",
"ext-iconv": "*",
"ext-imagick": "^3.4",
"ext-imap": "^7.4",
"ext-intl": "^7.4",
"ext-json": "*",
"ext-mbstring": "^7.4",
"ext-mongodb": "^1.4",
"ext-mysqli": "^7.4",
"ext-pdo_mysql": "^7.4",
"ext-redis": ">=3.1"
},
"platform-dev": []
}