19
19
20
20
import com .fasterxml .jackson .annotation .JsonProperty ;
21
21
import com .fasterxml .jackson .databind .DeserializationFeature ;
22
+ import com .fasterxml .jackson .databind .JsonNode ;
22
23
import com .fasterxml .jackson .databind .ObjectMapper ;
23
24
import com .fasterxml .jackson .databind .ObjectReader ;
24
25
import com .github .packageurl .MalformedPackageURLException ;
25
26
import com .github .packageurl .PackageURL ;
26
27
import com .github .packageurl .PackageURLBuilder ;
28
+ import java .util .Map ;
29
+ import java .util .stream .Collectors ;
27
30
import org .owasp .dependencycheck .Engine ;
28
31
import org .owasp .dependencycheck .analyzer .exception .AnalysisException ;
29
32
import org .owasp .dependencycheck .data .nvd .ecosystem .Ecosystem ;
@@ -118,26 +121,48 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An
118
121
}
119
122
120
123
final DependencyTree tree ;
124
+ List <MavenDependency > deps ;
121
125
try {
122
- final InstallFile installFile = INSTALL_FILE_READER .readValue (dependencyFile );
123
- tree = installFile .getDependencyTree ();
124
- } catch (IOException e ) {
125
- return ;
126
- }
126
+ JsonNode jsonNode = MAPPER .readTree (dependencyFile );
127
+ JsonNode v2Version = jsonNode .path ("version" );
128
+ JsonNode v010Version = jsonNode .path ("dependency_tree" ).path ("version" );
129
+
130
+ if (v2Version .isTextual ()) {
131
+ final InstallFileV2 installFile = INSTALL_FILE_V2_READER .readValue (dependencyFile );
132
+ if (!Objects .equals (installFile .getAutogeneratedSentinel (), "THERE_IS_NO_DATA_ONLY_ZUUL" )) {
133
+ return ;
134
+ }
135
+ if (!Objects .equals (installFile .getVersion (), "2" )) {
136
+ LOGGER .warn ("Unsupported pinned maven_install.json version {}. Continuing optimistically." , installFile .getVersion ());
137
+ }
138
+ deps = installFile .getArtifacts ().entrySet ().stream ().map (entry -> new MavenDependency (
139
+ entry .getKey () + ":" + entry .getValue ().getVersion ()
140
+ )).collect (Collectors .toList ());
141
+ } else if (v010Version .isTextual ()) {
142
+ final InstallFile installFile = INSTALL_FILE_READER .readValue (dependencyFile );
143
+ tree = installFile .getDependencyTree ();
144
+ if (tree == null ) {
145
+ return ;
146
+ } else if (!Objects .equals (tree .getAutogeneratedSentinel (), "THERE_IS_NO_DATA_ONLY_ZUUL" )) {
147
+ return ;
148
+ }
149
+ if (!Objects .equals (tree .getVersion (), "0.1.0" )) {
150
+ LOGGER .warn ("Unsupported pinned maven_install.json version {}. Continuing optimistically." , tree .getVersion ());
151
+ }
152
+ deps = tree .getDependencies ();
153
+ } else {
154
+ LOGGER .warn ("No pinned maven_install.json version found. Cannot Parse" );
155
+ return ;
156
+ }
127
157
128
- if ( tree == null ) {
129
- return ;
130
- } else if (! Objects . equals ( tree . getAutogeneratedSentinel (), "THERE_IS_NO_DATA_ONLY_ZUUL" )) {
158
+
159
+ } catch ( IOException e ) {
160
+ System . out . println ( "e" );
131
161
return ;
132
162
}
133
163
134
164
engine .removeDependency (dependency );
135
165
136
- if (!Objects .equals (tree .getVersion (), "0.1.0" )) {
137
- LOGGER .warn ("Unsupported pinned maven_install.json version {}. Continuing optimistically." , tree .getVersion ());
138
- }
139
-
140
- List <MavenDependency > deps = tree .getDependencies ();
141
166
if (deps == null ) {
142
167
deps = Collections .emptyList ();
143
168
}
@@ -300,7 +325,12 @@ public String getVersion() {
300
325
* {@code .dependency_tree.dependencies}.
301
326
*/
302
327
private static class MavenDependency {
328
+ public MavenDependency (String coord ) {
329
+ this .coord = coord ;
330
+ }
303
331
332
+ public MavenDependency () {
333
+ }
304
334
/**
305
335
* The standard Maven coordinate string
306
336
* {@code group:artifact[:optional classifier][:optional packaging]:version}.
@@ -322,10 +352,98 @@ public String getCoord() {
322
352
* A reusable reader for {@link InstallFile}.
323
353
*/
324
354
private static final ObjectReader INSTALL_FILE_READER ;
355
+ private static final ObjectReader INSTALL_FILE_V2_READER ;
356
+ private static final ObjectMapper MAPPER ;
325
357
326
358
static {
327
- final ObjectMapper mapper = new ObjectMapper ();
328
- mapper .configure (DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES , false );
329
- INSTALL_FILE_READER = mapper .readerFor (InstallFile .class );
359
+ MAPPER = new ObjectMapper ();
360
+ MAPPER .configure (DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES , false );
361
+ INSTALL_FILE_READER = MAPPER .readerFor (InstallFile .class );
362
+ INSTALL_FILE_V2_READER = MAPPER .readerFor (InstallFileV2 .class );
330
363
}
364
+
365
+ /**
366
+ * Represents the entire pinned Maven dependency set in an install.json
367
+ * file.
368
+ *
369
+ * <p>
370
+ * At the time of writing, the latest version is 2, and the dependencies
371
+ * are stored in {@code .artifacts}.
372
+ *
373
+ * <p>
374
+ * The top-level keys we care about are {@code .artifacts}. {@code .version}.
375
+ */
376
+ private static class InstallFileV2 {
377
+
378
+ /**
379
+ * The file format version.
380
+ */
381
+ @ JsonProperty ("version" )
382
+ private String version ;
383
+
384
+ /**
385
+ * A list of Maven dependencies made available. Note that this map is transitively closed and
386
+ * pinned to a specific version of each artifact.
387
+ * <p>
388
+ * The key is the Maven coordinate string, less the version
389
+ * {@code group:artifact[:optional classifier][:optional packaging]}.
390
+ * <p>
391
+ * The value contains the version of the artifact.
392
+ */
393
+ @ JsonProperty ("artifacts" )
394
+ private Map <String , Artifactv2 > artifacts ;
395
+
396
+ /**
397
+ * A sentinel value placed in the file to indicate that it is an auto-generated pinned maven
398
+ * install file.
399
+ */
400
+ @ JsonProperty ("__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY" )
401
+ private String autogeneratedSentinel ;
402
+
403
+ /**
404
+ * Returns artifacts.
405
+ *
406
+ * @return artifacts
407
+ */
408
+ public Map <String , Artifactv2 > getArtifacts () {
409
+ return artifacts ;
410
+ }
411
+
412
+ /**
413
+ * Returns version.
414
+ *
415
+ * @return version
416
+ */
417
+ public String getVersion () {
418
+ return version ;
419
+ }
420
+
421
+ /**
422
+ * Returns autogeneratedSentinel.
423
+ *
424
+ * @return autogeneratedSentinel
425
+ */
426
+ public String getAutogeneratedSentinel () {
427
+ return autogeneratedSentinel ;
428
+ }
429
+ }
430
+ private static class Artifactv2 {
431
+
432
+ /**
433
+ * The version of the artifact.
434
+ */
435
+ @ JsonProperty ("version" )
436
+ private String version ;
437
+
438
+ /**
439
+ * Returns the value of version.
440
+ *
441
+ * @return the value of version
442
+ */
443
+ public String getVersion () {
444
+ return version ;
445
+ }
446
+ }
447
+
448
+
331
449
}
0 commit comments