From 632b1de404d5fd186d9b6c9999f577895964a80e Mon Sep 17 00:00:00 2001 From: Aaron Acosta Date: Tue, 17 Dec 2024 00:42:10 -0800 Subject: [PATCH] feat: added cocoapods lockfile to the list of supported lockfiles (#330) Added necessary interface changes to support 1) a new ecosystem, cocoapods, 2) new lockfile + manifest types for cocoapods, and 3) a new parser type for (you guessed it) cocoapods. - [x] I ran `make setup && make` to update the generated code after editing a `.atd` file (TODO: have a CI check) - [x] I made sure we're still backward compatible with old versions of the CLI. For example, the Semgrep backend need to still be able to *consume* data generated by Semgrep 1.50.0. See https://atd.readthedocs.io/en/latest/atdgen-tutorial.html#smooth-protocol-upgrades Note that the types related to the semgrep-core JSON output or the semgrep-core RPC do not need to be backward compatible! Co-authored-by: Aaron Acosta --- semgrep_output_v1.atd | 5 +++ semgrep_output_v1.jsonschema | 4 ++ semgrep_output_v1.proto | 2 +- semgrep_output_v1.py | 84 ++++++++++++++++++++++++++++++++++-- semgrep_output_v1.ts | 20 +++++++++ semgrep_output_v1_j.ml | 32 +++++++++++++- semgrep_output_v1_j.mli | 4 +- 7 files changed, 142 insertions(+), 9 deletions(-) diff --git a/semgrep_output_v1.atd b/semgrep_output_v1.atd index 1488a5b0..919f33d7 100644 --- a/semgrep_output_v1.atd +++ b/semgrep_output_v1.atd @@ -509,6 +509,7 @@ type ecosystem | Nuget | Pub | SwiftPM + | Cocoapods (* Deprecated: Mix is a build system, should use Hex, which is the ecosystem *) | Mix | Hex @@ -1674,6 +1675,7 @@ type sca_parser_name = [ | Composer_lock | Pubspec_lock | Package_swift + | Podfile_lock | Package_resolved | Mix_lock ] @@ -2025,6 +2027,7 @@ type lockfile_kind | NugetPackagesLockJson | PubspecLock | SwiftPackageResolved (* not a real lockfile *) + | PodfileLock | MixLock | ConanLock ] @@ -2067,6 +2070,8 @@ type manifest_kind (* Package.swift * https://docs.swift.org/package-manager/PackageDescription/PackageDescription.html *) | PackageSwift + (* Podfile - https://guides.cocoapods.org/using/the-podfile.html *) + | Podfile (* mix.exs * https://hexdocs.pm/elixir/introduction-to-mix.html#project-compilation *) | MixExs diff --git a/semgrep_output_v1.jsonschema b/semgrep_output_v1.jsonschema index 949665fd..ace6318d 100644 --- a/semgrep_output_v1.jsonschema +++ b/semgrep_output_v1.jsonschema @@ -336,6 +336,7 @@ { "const": "nuget" }, { "const": "pub" }, { "const": "swiftpm" }, + { "const": "cocoapods" }, { "const": "mix" }, { "const": "hex" } ] @@ -1325,6 +1326,7 @@ { "const": "composer_lock" }, { "const": "pubspec_lock" }, { "const": "package_swift" }, + { "const": "podfile_lock" }, { "const": "package_resolved" }, { "const": "mix_lock" } ] @@ -1685,6 +1687,7 @@ { "const": "NugetPackagesLockJson" }, { "const": "PubspecLock" }, { "const": "SwiftPackageResolved" }, + { "const": "PodfileLock" }, { "const": "MixLock" }, { "const": "ConanLock" } ] @@ -1703,6 +1706,7 @@ { "const": "NugetManifestJson" }, { "const": "PubspecYaml" }, { "const": "PackageSwift" }, + { "const": "Podfile" }, { "const": "MixExs" }, { "const": "Pipfile" }, { "const": "PyprojectToml" }, diff --git a/semgrep_output_v1.proto b/semgrep_output_v1.proto index 1ba7d24c..ce65ff5b 100644 --- a/semgrep_output_v1.proto +++ b/semgrep_output_v1.proto @@ -1,6 +1,6 @@ // Generated by jsonschema2protobuf. DO NOT EDIT! // Source file: semgrep_output_v1.jsonschema -// Source file sha256 digest: a481d8b00723625c34818da9a0986f0e1cc579fa3d5ba1ad7ae4cd7af79ab974 +// Source file sha256 digest: 18d5eed99a95ef7ab173fc0b5a4b302224b414ffe16b5f33027813a6880c7097 syntax = "proto3"; diff --git a/semgrep_output_v1.py b/semgrep_output_v1.py index 4215d26a..395549e0 100644 --- a/semgrep_output_v1.py +++ b/semgrep_output_v1.py @@ -482,6 +482,23 @@ def to_json_string(self, **kw: Any) -> str: return json.dumps(self.to_json(), **kw) +@dataclass(frozen=True) +class Cocoapods: + """Original type: ecosystem = [ ... | Cocoapods | ... ]""" + + @property + def kind(self) -> str: + """Name of the class representing this variant.""" + return 'Cocoapods' + + @staticmethod + def to_json() -> Any: + return 'cocoapods' + + def to_json_string(self, **kw: Any) -> str: + return json.dumps(self.to_json(), **kw) + + @dataclass(frozen=True) class Mix: """Original type: ecosystem = [ ... | Mix | ... ]""" @@ -520,7 +537,7 @@ def to_json_string(self, **kw: Any) -> str: class Ecosystem: """Original type: ecosystem = [ ... ]""" - value: Union[Npm, Pypi, Gem, Gomod, Cargo, Maven, Composer, Nuget, Pub, SwiftPM, Mix, Hex] + value: Union[Npm, Pypi, Gem, Gomod, Cargo, Maven, Composer, Nuget, Pub, SwiftPM, Cocoapods, Mix, Hex] @property def kind(self) -> str: @@ -550,6 +567,8 @@ def from_json(cls, x: Any) -> 'Ecosystem': return cls(Pub()) if x == 'swiftpm': return cls(SwiftPM()) + if x == 'cocoapods': + return cls(Cocoapods()) if x == 'mix': return cls(Mix()) if x == 'hex': @@ -3294,6 +3313,23 @@ def to_json_string(self, **kw: Any) -> str: return json.dumps(self.to_json(), **kw) +@dataclass(frozen=True) +class PodfileLock: + """Original type: lockfile_kind = [ ... | PodfileLock | ... ]""" + + @property + def kind(self) -> str: + """Name of the class representing this variant.""" + return 'PodfileLock' + + @staticmethod + def to_json() -> Any: + return 'PodfileLock' + + def to_json_string(self, **kw: Any) -> str: + return json.dumps(self.to_json(), **kw) + + @dataclass(frozen=True) class MixLock: """Original type: lockfile_kind = [ ... | MixLock | ... ]""" @@ -3332,7 +3368,7 @@ def to_json_string(self, **kw: Any) -> str: class LockfileKind: """Original type: lockfile_kind = [ ... ]""" - value: Union[PipRequirementsTxt, PoetryLock, PipfileLock, UvLock, NpmPackageLockJson, YarnLock, PnpmLock, GemfileLock, GoMod, CargoLock, MavenDepTree, GradleLockfile, ComposerLock, NugetPackagesLockJson, PubspecLock, SwiftPackageResolved, MixLock, ConanLock] + value: Union[PipRequirementsTxt, PoetryLock, PipfileLock, UvLock, NpmPackageLockJson, YarnLock, PnpmLock, GemfileLock, GoMod, CargoLock, MavenDepTree, GradleLockfile, ComposerLock, NugetPackagesLockJson, PubspecLock, SwiftPackageResolved, PodfileLock, MixLock, ConanLock] @property def kind(self) -> str: @@ -3374,6 +3410,8 @@ def from_json(cls, x: Any) -> 'LockfileKind': return cls(PubspecLock()) if x == 'SwiftPackageResolved': return cls(SwiftPackageResolved()) + if x == 'PodfileLock': + return cls(PodfileLock()) if x == 'MixLock': return cls(MixLock()) if x == 'ConanLock': @@ -3882,6 +3920,23 @@ def to_json_string(self, **kw: Any) -> str: return json.dumps(self.to_json(), **kw) +@dataclass(frozen=True) +class Podfile: + """Original type: manifest_kind = [ ... | Podfile | ... ]""" + + @property + def kind(self) -> str: + """Name of the class representing this variant.""" + return 'Podfile' + + @staticmethod + def to_json() -> Any: + return 'Podfile' + + def to_json_string(self, **kw: Any) -> str: + return json.dumps(self.to_json(), **kw) + + @dataclass(frozen=True) class MixExs: """Original type: manifest_kind = [ ... | MixExs | ... ]""" @@ -3988,7 +4043,7 @@ def to_json_string(self, **kw: Any) -> str: class ManifestKind: """Original type: manifest_kind = [ ... ]""" - value: Union[RequirementsIn, PackageJson, Gemfile, GoMod_, CargoToml, PomXml, BuildGradle, SettingsGradle, ComposerJson, NugetManifestJson, PubspecYaml, PackageSwift, MixExs, Pipfile, PyprojectToml, ConanFileTxt, ConanFilePy, Csproj] + value: Union[RequirementsIn, PackageJson, Gemfile, GoMod_, CargoToml, PomXml, BuildGradle, SettingsGradle, ComposerJson, NugetManifestJson, PubspecYaml, PackageSwift, Podfile, MixExs, Pipfile, PyprojectToml, ConanFileTxt, ConanFilePy, Csproj] @property def kind(self) -> str: @@ -4022,6 +4077,8 @@ def from_json(cls, x: Any) -> 'ManifestKind': return cls(PubspecYaml()) if x == 'PackageSwift': return cls(PackageSwift()) + if x == 'Podfile': + return cls(Podfile()) if x == 'MixExs': return cls(MixExs()) if x == 'Pipfile': @@ -5732,6 +5789,23 @@ def to_json_string(self, **kw: Any) -> str: return json.dumps(self.to_json(), **kw) +@dataclass +class PodfileLock_: + """Original type: sca_parser_name = [ ... | Podfile_lock | ... ]""" + + @property + def kind(self) -> str: + """Name of the class representing this variant.""" + return 'PodfileLock_' + + @staticmethod + def to_json() -> Any: + return 'podfile_lock' + + def to_json_string(self, **kw: Any) -> str: + return json.dumps(self.to_json(), **kw) + + @dataclass class PackageResolved: """Original type: sca_parser_name = [ ... | Package_resolved | ... ]""" @@ -5770,7 +5844,7 @@ def to_json_string(self, **kw: Any) -> str: class ScaParserName: """Original type: sca_parser_name = [ ... ]""" - value: Union[GemfileLock_, GoMod2, GoSum, GradleLockfile_, GradleBuild, Jsondoc, Pipfile_, PnpmLock_, PoetryLock_, PyprojectToml_, Requirements, Yarn1, Yarn2, Pomtree, CargoParser, ComposerLock_, PubspecLock_, PackageSwift_, PackageResolved, MixLock_] + value: Union[GemfileLock_, GoMod2, GoSum, GradleLockfile_, GradleBuild, Jsondoc, Pipfile_, PnpmLock_, PoetryLock_, PyprojectToml_, Requirements, Yarn1, Yarn2, Pomtree, CargoParser, ComposerLock_, PubspecLock_, PackageSwift_, PodfileLock_, PackageResolved, MixLock_] @property def kind(self) -> str: @@ -5816,6 +5890,8 @@ def from_json(cls, x: Any) -> 'ScaParserName': return cls(PubspecLock_()) if x == 'package_swift': return cls(PackageSwift_()) + if x == 'podfile_lock': + return cls(PodfileLock_()) if x == 'package_resolved': return cls(PackageResolved()) if x == 'mix_lock': diff --git a/semgrep_output_v1.ts b/semgrep_output_v1.ts index effb4ec6..7b93cc04 100644 --- a/semgrep_output_v1.ts +++ b/semgrep_output_v1.ts @@ -179,6 +179,7 @@ export type Ecosystem = | { kind: 'Nuget' /* JSON: "nuget" */ } | { kind: 'Pub' /* JSON: "pub" */ } | { kind: 'SwiftPM' /* JSON: "swiftpm" */ } +| { kind: 'Cocoapods' /* JSON: "cocoapods" */ } | { kind: 'Mix' /* JSON: "mix" */ } | { kind: 'Hex' /* JSON: "hex" */ } @@ -735,6 +736,7 @@ export type ScaParserName = | { kind: 'Composer_lock' /* JSON: "composer_lock" */ } | { kind: 'Pubspec_lock' /* JSON: "pubspec_lock" */ } | { kind: 'Package_swift' /* JSON: "package_swift" */ } +| { kind: 'Podfile_lock' /* JSON: "podfile_lock" */ } | { kind: 'Package_resolved' /* JSON: "package_resolved" */ } | { kind: 'Mix_lock' /* JSON: "mix_lock" */ } @@ -923,6 +925,7 @@ export type LockfileKind = | { kind: 'NugetPackagesLockJson' } | { kind: 'PubspecLock' } | { kind: 'SwiftPackageResolved' } +| { kind: 'PodfileLock' } | { kind: 'MixLock' } | { kind: 'ConanLock' } @@ -939,6 +942,7 @@ export type ManifestKind = | { kind: 'NugetManifestJson' } | { kind: 'PubspecYaml' } | { kind: 'PackageSwift' } +| { kind: 'Podfile' } | { kind: 'MixExs' } | { kind: 'Pipfile' } | { kind: 'PyprojectToml' } @@ -1585,6 +1589,8 @@ export function writeEcosystem(x: Ecosystem, context: any = x): any { return 'pub' case 'SwiftPM': return 'swiftpm' + case 'Cocoapods': + return 'cocoapods' case 'Mix': return 'mix' case 'Hex': @@ -1614,6 +1620,8 @@ export function readEcosystem(x: any, context: any = x): Ecosystem { return { kind: 'Pub' } case 'swiftpm': return { kind: 'SwiftPM' } + case 'cocoapods': + return { kind: 'Cocoapods' } case 'mix': return { kind: 'Mix' } case 'hex': @@ -3206,6 +3214,8 @@ export function writeScaParserName(x: ScaParserName, context: any = x): any { return 'pubspec_lock' case 'Package_swift': return 'package_swift' + case 'Podfile_lock': + return 'podfile_lock' case 'Package_resolved': return 'package_resolved' case 'Mix_lock': @@ -3251,6 +3261,8 @@ export function readScaParserName(x: any, context: any = x): ScaParserName { return { kind: 'Pubspec_lock' } case 'package_swift': return { kind: 'Package_swift' } + case 'podfile_lock': + return { kind: 'Podfile_lock' } case 'package_resolved': return { kind: 'Package_resolved' } case 'mix_lock': @@ -3789,6 +3801,8 @@ export function writeLockfileKind(x: LockfileKind, context: any = x): any { return 'PubspecLock' case 'SwiftPackageResolved': return 'SwiftPackageResolved' + case 'PodfileLock': + return 'PodfileLock' case 'MixLock': return 'MixLock' case 'ConanLock': @@ -3830,6 +3844,8 @@ export function readLockfileKind(x: any, context: any = x): LockfileKind { return { kind: 'PubspecLock' } case 'SwiftPackageResolved': return { kind: 'SwiftPackageResolved' } + case 'PodfileLock': + return { kind: 'PodfileLock' } case 'MixLock': return { kind: 'MixLock' } case 'ConanLock': @@ -3866,6 +3882,8 @@ export function writeManifestKind(x: ManifestKind, context: any = x): any { return 'PubspecYaml' case 'PackageSwift': return 'PackageSwift' + case 'Podfile': + return 'Podfile' case 'MixExs': return 'MixExs' case 'Pipfile': @@ -3907,6 +3925,8 @@ export function readManifestKind(x: any, context: any = x): ManifestKind { return { kind: 'PubspecYaml' } case 'PackageSwift': return { kind: 'PackageSwift' } + case 'Podfile': + return { kind: 'Podfile' } case 'MixExs': return { kind: 'MixExs' } case 'Pipfile': diff --git a/semgrep_output_v1_j.ml b/semgrep_output_v1_j.ml index ac9c702f..79b61ccc 100644 --- a/semgrep_output_v1_j.ml +++ b/semgrep_output_v1_j.ml @@ -265,8 +265,8 @@ type lockfile_kind = Semgrep_output_v1_t.lockfile_kind = PipRequirementsTxt | PoetryLock | PipfileLock | UvLock | NpmPackageLockJson | YarnLock | PnpmLock | GemfileLock | GoMod | CargoLock | MavenDepTree | GradleLockfile | ComposerLock - | NugetPackagesLockJson | PubspecLock | SwiftPackageResolved | MixLock - | ConanLock + | NugetPackagesLockJson | PubspecLock | SwiftPackageResolved | PodfileLock + | MixLock | ConanLock [@@deriving show, eq, yojson] @@ -1377,6 +1377,7 @@ let write_ecosystem = ( | `Nuget -> Buffer.add_string ob "\"nuget\"" | `Pub -> Buffer.add_string ob "\"pub\"" | `SwiftPM -> Buffer.add_string ob "\"swiftpm\"" + | `Cocoapods -> Buffer.add_string ob "\"cocoapods\"" | `Mix -> Buffer.add_string ob "\"mix\"" | `Hex -> Buffer.add_string ob "\"hex\"" ) @@ -1430,6 +1431,10 @@ let read_ecosystem = ( Yojson.Safe.read_space p lb; Yojson.Safe.read_gt p lb; `SwiftPM + | "cocoapods" -> + Yojson.Safe.read_space p lb; + Yojson.Safe.read_gt p lb; + `Cocoapods | "mix" -> Yojson.Safe.read_space p lb; Yojson.Safe.read_gt p lb; @@ -1463,6 +1468,8 @@ let read_ecosystem = ( `Pub | "swiftpm" -> `SwiftPM + | "cocoapods" -> + `Cocoapods | "mix" -> `Mix | "hex" -> @@ -10218,6 +10225,7 @@ let write_lockfile_kind : _ -> lockfile_kind -> _ = ( | NugetPackagesLockJson -> Buffer.add_string ob "\"NugetPackagesLockJson\"" | PubspecLock -> Buffer.add_string ob "\"PubspecLock\"" | SwiftPackageResolved -> Buffer.add_string ob "\"SwiftPackageResolved\"" + | PodfileLock -> Buffer.add_string ob "\"PodfileLock\"" | MixLock -> Buffer.add_string ob "\"MixLock\"" | ConanLock -> Buffer.add_string ob "\"ConanLock\"" ) @@ -10295,6 +10303,10 @@ let read_lockfile_kind = ( Yojson.Safe.read_space p lb; Yojson.Safe.read_gt p lb; (SwiftPackageResolved : lockfile_kind) + | "PodfileLock" -> + Yojson.Safe.read_space p lb; + Yojson.Safe.read_gt p lb; + (PodfileLock : lockfile_kind) | "MixLock" -> Yojson.Safe.read_space p lb; Yojson.Safe.read_gt p lb; @@ -10340,6 +10352,8 @@ let read_lockfile_kind = ( (PubspecLock : lockfile_kind) | "SwiftPackageResolved" -> (SwiftPackageResolved : lockfile_kind) + | "PodfileLock" -> + (PodfileLock : lockfile_kind) | "MixLock" -> (MixLock : lockfile_kind) | "ConanLock" -> @@ -11339,6 +11353,7 @@ let write_manifest_kind = ( | `NugetManifestJson -> Buffer.add_string ob "\"NugetManifestJson\"" | `PubspecYaml -> Buffer.add_string ob "\"PubspecYaml\"" | `PackageSwift -> Buffer.add_string ob "\"PackageSwift\"" + | `Podfile -> Buffer.add_string ob "\"Podfile\"" | `MixExs -> Buffer.add_string ob "\"MixExs\"" | `Pipfile -> Buffer.add_string ob "\"Pipfile\"" | `PyprojectToml -> Buffer.add_string ob "\"PyprojectToml\"" @@ -11404,6 +11419,10 @@ let read_manifest_kind = ( Yojson.Safe.read_space p lb; Yojson.Safe.read_gt p lb; `PackageSwift + | "Podfile" -> + Yojson.Safe.read_space p lb; + Yojson.Safe.read_gt p lb; + `Podfile | "MixExs" -> Yojson.Safe.read_space p lb; Yojson.Safe.read_gt p lb; @@ -11457,6 +11476,8 @@ let read_manifest_kind = ( `PubspecYaml | "PackageSwift" -> `PackageSwift + | "Podfile" -> + `Podfile | "MixExs" -> `MixExs | "Pipfile" -> @@ -18995,6 +19016,7 @@ let write_sca_parser_name = ( | `Composer_lock -> Buffer.add_string ob "\"composer_lock\"" | `Pubspec_lock -> Buffer.add_string ob "\"pubspec_lock\"" | `Package_swift -> Buffer.add_string ob "\"package_swift\"" + | `Podfile_lock -> Buffer.add_string ob "\"podfile_lock\"" | `Package_resolved -> Buffer.add_string ob "\"package_resolved\"" | `Mix_lock -> Buffer.add_string ob "\"mix_lock\"" ) @@ -19080,6 +19102,10 @@ let read_sca_parser_name = ( Yojson.Safe.read_space p lb; Yojson.Safe.read_gt p lb; `Package_swift + | "podfile_lock" -> + Yojson.Safe.read_space p lb; + Yojson.Safe.read_gt p lb; + `Podfile_lock | "package_resolved" -> Yojson.Safe.read_space p lb; Yojson.Safe.read_gt p lb; @@ -19129,6 +19155,8 @@ let read_sca_parser_name = ( `Pubspec_lock | "package_swift" -> `Package_swift + | "podfile_lock" -> + `Podfile_lock | "package_resolved" -> `Package_resolved | "mix_lock" -> diff --git a/semgrep_output_v1_j.mli b/semgrep_output_v1_j.mli index e9e33a70..2b5c422c 100644 --- a/semgrep_output_v1_j.mli +++ b/semgrep_output_v1_j.mli @@ -265,8 +265,8 @@ type lockfile_kind = Semgrep_output_v1_t.lockfile_kind = PipRequirementsTxt | PoetryLock | PipfileLock | UvLock | NpmPackageLockJson | YarnLock | PnpmLock | GemfileLock | GoMod | CargoLock | MavenDepTree | GradleLockfile | ComposerLock - | NugetPackagesLockJson | PubspecLock | SwiftPackageResolved | MixLock - | ConanLock + | NugetPackagesLockJson | PubspecLock | SwiftPackageResolved | PodfileLock + | MixLock | ConanLock [@@deriving show, eq, yojson]