1919
2020import com .fasterxml .jackson .annotation .JsonProperty ;
2121import com .fasterxml .jackson .databind .DeserializationFeature ;
22+ import com .fasterxml .jackson .databind .JsonNode ;
2223import com .fasterxml .jackson .databind .ObjectMapper ;
2324import com .fasterxml .jackson .databind .ObjectReader ;
2425import com .github .packageurl .MalformedPackageURLException ;
2526import com .github .packageurl .PackageURL ;
2627import com .github .packageurl .PackageURLBuilder ;
28+ import java .util .Map ;
29+ import java .util .stream .Collectors ;
2730import org .owasp .dependencycheck .Engine ;
2831import org .owasp .dependencycheck .analyzer .exception .AnalysisException ;
2932import org .owasp .dependencycheck .data .nvd .ecosystem .Ecosystem ;
@@ -118,26 +121,48 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An
118121 }
119122
120123 final DependencyTree tree ;
124+ List <MavenDependency > deps ;
121125 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+ }
127157
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" );
131161 return ;
132162 }
133163
134164 engine .removeDependency (dependency );
135165
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 ();
141166 if (deps == null ) {
142167 deps = Collections .emptyList ();
143168 }
@@ -300,7 +325,12 @@ public String getVersion() {
300325 * {@code .dependency_tree.dependencies}.
301326 */
302327 private static class MavenDependency {
328+ public MavenDependency (String coord ) {
329+ this .coord = coord ;
330+ }
303331
332+ public MavenDependency () {
333+ }
304334 /**
305335 * The standard Maven coordinate string
306336 * {@code group:artifact[:optional classifier][:optional packaging]:version}.
@@ -322,10 +352,98 @@ public String getCoord() {
322352 * A reusable reader for {@link InstallFile}.
323353 */
324354 private static final ObjectReader INSTALL_FILE_READER ;
355+ private static final ObjectReader INSTALL_FILE_V2_READER ;
356+ private static final ObjectMapper MAPPER ;
325357
326358 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 );
330363 }
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+
331449}
0 commit comments