Skip to content

refactor: refactor javascript parser (#1721) #1722

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ffba885
Updated spelling.yml
XDRAGON2002 Dec 29, 2021
c191f20
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Dec 30, 2021
576871b
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Jan 6, 2022
5707392
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Jan 7, 2022
63981f0
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Jan 26, 2022
ad0032f
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Jan 27, 2022
a38777e
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Jan 29, 2022
db3e815
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Feb 7, 2022
e3d5602
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Mar 1, 2022
eadbc73
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Mar 6, 2022
a23f5c3
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Mar 12, 2022
2b5759a
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Mar 16, 2022
8723ee4
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Mar 18, 2022
dd8c8d3
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Mar 26, 2022
0d78f26
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 May 10, 2022
78f041d
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Jun 15, 2022
d48bc14
Merge branch 'main' of https://github.com/intel/cve-bin-tool into main
XDRAGON2002 Jun 27, 2022
402bdb9
refactor: refactor javascript parser
XDRAGON2002 Jun 27, 2022
dfab7b1
fix: update file handling
XDRAGON2002 Jul 5, 2022
3b7217b
Merge branch 'main' into issue_1721
terriko Jul 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions cve_bin_tool/parsers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Copyright (C) 2022 Intel Corporation
# SPDX-License-Identifier: GPL-3.0-or-later

__all__ = [
"Parser",
]
__all__ = ["Parser", "javascript"]


class Parser:
Expand Down
73 changes: 73 additions & 0 deletions cve_bin_tool/parsers/javascript.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Copyright (C) 2022 Intel Corporation
# SPDX-License-Identifier: GPL-3.0-or-later

import json

from cve_bin_tool.parsers import Parser
from cve_bin_tool.util import ProductInfo, ScanInfo


class JavascriptParser(Parser):
def __init__(self, cve_db, logger):
self.cve_db = cve_db
self.logger = logger
self.filename = ""

def find_vendor(self, product, version):
"""Find vendor for Javascript product"""
if version == "*":
return None
vendor_package_pair = self.cve_db.get_vendor_product_pairs(product)
vendorlist: list[ScanInfo] = []
if vendor_package_pair != []:
# To handle multiple vendors, return all combinations of product/vendor mappings
for v in vendor_package_pair:
vendor = v["vendor"]
file_path = self.filename
# Tidy up version string
if "^" in version:
version = version[1:]
self.logger.debug(f"{file_path} {product} {version} by {vendor}")
vendorlist.append(
ScanInfo(ProductInfo(vendor, product, version), file_path)
)
return vendorlist if len(vendorlist) > 0 else None
return None

def run_checker(self, filename):
"""Process package-lock.json file and extract product and dependency details"""
self.filename = filename
fh = open(self.filename)
data = json.load(fh)
product = data["name"]
version = data["version"]
vendor = self.find_vendor(product, version)
if vendor is not None:
yield from vendor
# Now process dependencies
for i in data["dependencies"]:
# To handle @actions/<product>: lines, extract product name from line
product = i.split("/")[1] if "/" in i else i
# Handle different formats. Either <product> : <version> or
# <product>: {
# ...
# "version" : <version>
# ...
# }
try:
version = data["dependencies"][i]["version"]
except Exception:
# Cater for case when version field not present
version = data["dependencies"][i]
vendor = self.find_vendor(product, version)
if vendor is not None:
yield from vendor
if "requires" in data["dependencies"][i]:
for r in data["dependencies"][i]["requires"]:
# To handle @actions/<product>: lines, extract product name from line
product = r.split("/")[1] if "/" in r else r
version = data["dependencies"][i]["requires"][r]
vendor = self.find_vendor(product, version)
if vendor is not None:
yield from vendor
self.logger.debug(f"Done scanning file: {self.filename}")
60 changes: 3 additions & 57 deletions cve_bin_tool/version_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations

import json
import os
import subprocess
import sys
Expand All @@ -19,6 +18,7 @@
from cve_bin_tool.extractor import Extractor, TempDirExtractorContext
from cve_bin_tool.file import is_binary
from cve_bin_tool.log import LOGGER
from cve_bin_tool.parsers.javascript import JavascriptParser
from cve_bin_tool.strings import Strings
from cve_bin_tool.util import DirWalk, ProductInfo, ScanInfo, inpath
from cve_bin_tool.validator import validate_pom
Expand Down Expand Up @@ -272,63 +272,9 @@ def run_java_checker(self, filename: str) -> Iterator[ScanInfo]:

self.logger.debug(f"Done scanning file: {filename}")

def find_js_vendor(self, product: str, version: str) -> list[ScanInfo] | None:
"""Find vendor for Javascript product"""
if version == "*":
return None
vendor_package_pair = self.cve_db.get_vendor_product_pairs(product)
vendorlist: list[ScanInfo] = []
if vendor_package_pair != []:
# To handle multiple vendors, return all combinations of product/vendor mappings
for v in vendor_package_pair:
vendor = v["vendor"]
file_path = "".join(self.file_stack)
# Tidy up version string
if "^" in version:
version = version[1:]
self.logger.debug(f"{file_path} {product} {version} by {vendor}")
vendorlist.append(
ScanInfo(ProductInfo(vendor, product, version), file_path)
)
return vendorlist if len(vendorlist) > 0 else None
return None

def run_js_checker(self, filename: str) -> Iterator[ScanInfo]:
"""Process package-lock.json file and extract product and dependency details"""
fh = open(filename)
data = json.load(fh)
product = data["name"]
version = data["version"]
vendor = self.find_js_vendor(product, version)
if vendor is not None:
yield from vendor
# Now process dependencies
for i in data["dependencies"]:
# To handle @actions/<product>: lines, extract product name from line
product = i.split("/")[1] if "/" in i else i
# Handle different formats. Either <product> : <version> or
# <product>: {
# ...
# "version" : <version>
# ...
# }
try:
version = data["dependencies"][i]["version"]
except Exception:
# Cater for case when version field not present
version = data["dependencies"][i]
vendor = self.find_js_vendor(product, version)
if vendor is not None:
yield from vendor
if "requires" in data["dependencies"][i]:
for r in data["dependencies"][i]["requires"]:
# To handle @actions/<product>: lines, extract product name from line
product = r.split("/")[1] if "/" in r else r
version = data["dependencies"][i]["requires"][r]
vendor = self.find_js_vendor(product, version)
if vendor is not None:
yield from vendor
self.logger.debug(f"Done scanning file: {filename}")
parser = JavascriptParser(self.cve_db, self.logger)
yield from parser.run_checker(filename)

def run_python_package_checkers(
self, filename: str, lines: str
Expand Down