1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.data.composer;
19
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 import javax.json.Json;
24 import javax.json.JsonArray;
25 import javax.json.JsonException;
26 import javax.json.JsonObject;
27 import javax.json.JsonReader;
28 import javax.json.stream.JsonParsingException;
29 import java.io.InputStream;
30 import java.util.ArrayList;
31 import java.util.List;
32 import javax.annotation.concurrent.NotThreadSafe;
33
34
35
36
37
38
39
40 @NotThreadSafe
41 public class ComposerLockParser {
42
43
44
45
46 private final JsonReader jsonReader;
47
48
49
50 private final List<ComposerDependency> composerDependencies;
51
52
53
54 private final boolean skipDev;
55
56
57
58 private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockParser.class);
59
60
61
62
63
64
65 public ComposerLockParser(InputStream inputStream, boolean skipDev) {
66 LOGGER.debug("Creating a ComposerLockParser");
67 this.jsonReader = Json.createReader(inputStream);
68 this.composerDependencies = new ArrayList<>();
69 this.skipDev = skipDev;
70 }
71
72
73
74
75 public void process() {
76 LOGGER.debug("Beginning Composer lock processing");
77 try {
78 final JsonObject composer = jsonReader.readObject();
79 if (composer.containsKey("packages")) {
80 LOGGER.debug("Found packages");
81 final JsonArray packages = composer.getJsonArray("packages");
82 for (JsonObject pkg : packages.getValuesAs(JsonObject.class)) {
83 processPackageEntry(pkg);
84 }
85 }
86 if (composer.containsKey("packages-dev") && !skipDev) {
87 LOGGER.debug("Found packages-dev");
88 final JsonArray devPackages = composer.getJsonArray("packages-dev");
89 for (JsonObject pkg : devPackages.getValuesAs(JsonObject.class)) {
90 processPackageEntry(pkg);
91 }
92 }
93 } catch (JsonParsingException jsonpe) {
94 throw new ComposerException("Error parsing stream", jsonpe);
95 } catch (JsonException jsone) {
96 throw new ComposerException("Error reading stream", jsone);
97 } catch (IllegalStateException ise) {
98 throw new ComposerException("Illegal state in composer stream", ise);
99 } catch (ClassCastException cce) {
100 throw new ComposerException("Not exactly composer lock", cce);
101 }
102 }
103
104 protected void processPackageEntry(JsonObject pkg) {
105 if (pkg.containsKey("name")) {
106 final String groupName = pkg.getString("name");
107 if (groupName.indexOf('/') >= 0 && groupName.indexOf('/') <= groupName.length() - 1) {
108 if (pkg.containsKey("version")) {
109 final String group = groupName.substring(0, groupName.indexOf('/'));
110 final String project = groupName.substring(groupName.indexOf('/') + 1);
111 String version = pkg.getString("version");
112
113 if (version.startsWith("v")) {
114 version = version.substring(1);
115 }
116 LOGGER.debug("Got package {}/{}/{}", group, project, version);
117 composerDependencies.add(new ComposerDependency(group, project, version));
118 } else {
119 LOGGER.debug("Group/package {} does not have a version", groupName);
120 }
121 } else {
122 LOGGER.debug("Got a dependency with no name");
123 }
124 }
125 }
126
127
128
129
130
131
132 public List<ComposerDependency> getDependencies() {
133 return composerDependencies;
134 }
135 }