specification icon indicating copy to clipboard operation
specification copied to clipboard

Add support for array of callstack frames

Open prabhu opened this issue 2 years ago • 5 comments

Currently, callstack frames is limited to a single array.

https://github.com/CycloneDX/specification/blob/master/schema/bom-1.5.schema.json#L1576C24-L1576C24

This limits the number of evidence to just 1, as shown in the screenshot below:

Selection_019

This attribute could become an array of arrays to support multiple evidences.

prabhu avatar Aug 16 '23 08:08 prabhu

This attribute could become an array of arrays to support multiple evidences.

this would be a a breaking change

jkowalleck avatar Aug 16 '23 10:08 jkowalleck

this would be a a breaking change

We should be able to make this either an array of object (as it is today) or an array of arrays without breaking changes.

stevespringett avatar Oct 16 '23 04:10 stevespringett

@prabhu can you please propose a non-breaking option that would be compatible with existing v1.5 (single array) and array of arrays? I'd like to get this introduced in v1.6 if possible. This should be possible with JSON and XML.

stevespringett avatar Nov 09 '23 20:11 stevespringett

@stevespringett how about an optional nested property frames?

message Callstack {
  repeated Frames frames = 1;

  message Frames {
    // A package organizes modules into namespaces, providing a unique namespace for each type it contains.
    optional string package = 1;
    // A module or class that encloses functions/methods and other code.
    string module = 2;
    // A block of code designed to perform a particular task.
    optional string function = 3;
    // Optional arguments that are passed to the module or function.
    repeated string parameters = 4;
    // The line number the code that is called resides on.
    optional int32 line = 5;
    // The column the code that is called resides.
    optional int32 column = 6;
    // The full path and filename of the module.
    optional string fullFilename = 7;
    // For multiple callstack, nest the frames
    optional Frames frames = 8;
  }
}

Example transformation

Current

"callstack": {
  "frames": [
    {
      "package": "com.example.vulnspring",
      "module": "com.example.vulnspring.WebController",
      "function": "update",
      "line": 92,
      "column": 23,
      "fullFilename": "src/main/java/com/example/vulnspring/WebController.java",      
    },
    {
      "package": "com.example.vulnspring",
      "module": "com.example.vulnspring.WebController",
      "function": "update",
      "line": 95,
      "column": 20,
      "fullFilename": "src/main/java/com/example/vulnspring/WebController.java"
    },
    {
      "package": "com.example.vulnspring",
      "module": "com.example.vulnspring.WebController",
      "function": "update",
      "line": 95,
      "column": 20,
      "fullFilename": "src/main/java/com/example/vulnspring/WebController.java"
    },
    {
      "package": "com.example.vulnspring",
      "module": "com.example.vulnspring.WebController",
      "function": "update",
      "line": 95,
      "column": 18,
      "fullFilename": "src/main/java/com/example/vulnspring/WebController.java"
    },
    {
      "package": "com.example.vulnspring",
      "module": "com.example.vulnspring.WebController",
      "function": "update",
      "line": 94,
      "column": 35,
      "fullFilename": "src/main/java/com/example/vulnspring/WebController.java"
    }
  ]
}

New

"callstack": {
  "frames": [
    {
      "package": "com.example.vulnspring",
      "module": "com.example.vulnspring.WebController",
      "function": "update",
      "line": 92,
      "column": 23,
      "fullFilename": "src/main/java/com/example/vulnspring/WebController.java",
      "frames": [
        {
          "package": "com.example.vulnspring",
          "module": "com.example.vulnspring.WebController",
          "function": "update",
          "line": 95,
          "column": 20,
          "fullFilename": "src/main/java/com/example/vulnspring/WebController.java"
        },
        {
          "package": "com.example.vulnspring",
          "module": "com.example.vulnspring.WebController",
          "function": "update",
          "line": 95,
          "column": 20,
          "fullFilename": "src/main/java/com/example/vulnspring/WebController.java"
        },
        {
          "package": "com.example.vulnspring",
          "module": "com.example.vulnspring.WebController",
          "function": "update",
          "line": 95,
          "column": 18,
          "fullFilename": "src/main/java/com/example/vulnspring/WebController.java"
        },
        {
          "package": "com.example.vulnspring",
          "module": "com.example.vulnspring.WebController",
          "function": "update",
          "line": 94,
          "column": 35,
          "fullFilename": "src/main/java/com/example/vulnspring/WebController.java"
        }
      ]
    }    
  ]
}

Now the outer frame could have more objects.

prabhu avatar Nov 09 '23 22:11 prabhu

@prabhu would you be able to submit a non-breaking PR supporting JSON Schema, XML Schema, and Protobuf that achieves the desired outcome?

In JSON Schema for example, I believe it is possible to specify that an array will contain an object OR another array. I believe the same is possible in XML.

I'm not sure about the whole inner frame concept. Let's try to get the object model that we want and figure out a way to make it happen in the schemas. We are less concerned about breaking changes with protobuf since protobufs are not sharable files.

stevespringett avatar Dec 09 '23 04:12 stevespringett