Skip to content

Commit c5c69a4

Browse files
authored
Merge pull request #163 from sbs2001/fix-npm
Fix npm importer
2 parents 80a7b6e + bf31b16 commit c5c69a4

4 files changed

Lines changed: 35 additions & 41 deletions

File tree

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ pytest-mock==1.13.0
2323
pytz==2019.3
2424
PyYAML==5.3
2525
saneyaml==0.4
26-
semantic-version==2.8.2
2726
six==1.13.0
2827
soupsieve==1.9.5
2928
sqlparse==0.3.0

vulnerabilities/data_dump.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ def npm_dump(extract_data):
174174
for version in data['affected_versions']:
175175
package_affected = Package.objects.create(
176176
name=package_name,
177+
type='npm',
177178
version=version,
178179
)
179180
ImpactedPackage.objects.create(

vulnerabilities/scraper/npm.py

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,30 @@
2222
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
2323

2424
import json
25-
import re
26-
import semantic_version
25+
from dephell_specifier import RangeSpecifier
2726
from urllib.request import urlopen
27+
from urllib.error import HTTPError
28+
2829

2930
NPM_URL = 'https://registry.npmjs.org{}'
3031
PAGE = '/-/npm/v1/security/advisories?page=0'
3132

3233

33-
def remove_spaces(x):
34-
"""
35-
Remove Multiple Space, spaces after relational operator
36-
and remove v charecter in front of version string (ex v1.2.3)
37-
"""
38-
x = re.sub(r' +', ' ', x)
39-
x = re.sub(r'< +', '<', x)
40-
x = re.sub(r'> +', '>', x)
41-
x = re.sub(r'<= +', '<=', x)
42-
x = re.sub(r'>= +', '>=', x)
43-
x = re.sub(r'>=[vV]', '>=', x)
44-
x = re.sub(r'<=[vV]', '<=', x)
45-
x = re.sub(r'>[vV]', '>', x)
46-
x = re.sub(r'<[vV]', '<', x)
47-
return x
48-
49-
5034
def get_all_versions(package_name):
5135
"""
5236
Returns all versions available for a module
5337
"""
38+
package_name = package_name.strip()
5439
package_url = NPM_URL.format(f'/{package_name}')
55-
with urlopen(package_url) as response:
56-
data = json.load(response)
40+
try:
41+
with urlopen(package_url) as response:
42+
data = json.load(response)
43+
except HTTPError as e:
44+
if e.code == 404:
45+
return []
46+
else:
47+
raise
48+
# NPM registry has no data regarding this package, we skip these
5749
return [v for v in data.get('versions', {})]
5850

5951

@@ -62,20 +54,21 @@ def extract_versions(package_name, aff_version_range, fixed_version_range):
6254
Seperate list of affected versions and unaffected versions from all versions
6355
using the ranges specified.
6456
"""
65-
aff_spec = semantic_version.NpmSpec(remove_spaces(aff_version_range))
66-
fix_spec = semantic_version.NpmSpec(remove_spaces(fixed_version_range))
57+
aff_spec = RangeSpecifier(aff_version_range)
58+
fix_spec = RangeSpecifier(fixed_version_range)
6759
all_ver = get_all_versions(package_name)
60+
if not all_ver:
61+
# NPM registry has no data regarding this package, we skip these
62+
return ([], [])
6863
aff_ver = []
6964
fix_ver = []
7065
# Unaffected version is that version which is in the fixed_version_range
7166
# or which is absent in the aff_version_range
7267
for ver in all_ver:
73-
cur_version = semantic_version.Version(ver)
74-
if cur_version in fix_spec or cur_version not in aff_spec:
68+
if ver in fix_spec or ver not in aff_spec:
7569
fix_ver.append(ver)
7670
else:
7771
aff_ver.append(ver)
78-
7972
return (aff_ver, fix_ver)
8073

8174

@@ -96,6 +89,9 @@ def extract_data(JSON):
9689
obj.get('vulnerable_versions', ''),
9790
obj.get('patched_versions', '')
9891
)
92+
if not affected_versions and not fixed_versions:
93+
continue
94+
# NPM registry has no data regarding this package finally we skip these
9995

10096
package_vulnerabilities.append({
10197
'package_name': package_name,
@@ -113,12 +109,19 @@ def scrape_vulnerabilities():
113109
"""
114110
Extract JSON From NPM registry
115111
"""
116-
nextpage = PAGE
117112
package_vulnerabilities = []
113+
nextpage = PAGE
118114
while nextpage:
119-
cururl = NPM_URL.format(nextpage)
120-
response = json.load(urlopen(cururl))
121-
package_vulnerabilities.extend(extract_data(response))
122-
next_page = response.get('urls', {}).get('next')
115+
try:
116+
cururl = NPM_URL.format(nextpage)
117+
response = json.load(urlopen(cururl))
118+
package_vulnerabilities.extend(extract_data(response))
119+
nextpage = response.get('urls', {}).get('next')
120+
121+
except HTTPError as error:
122+
if error.code == 404:
123+
break
124+
else:
125+
raise
123126

124127
return package_vulnerabilities

vulnerabilities/tests/test_npm.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,11 @@
2727

2828
from vulnerabilities.scraper.npm import extract_data
2929
from vulnerabilities.scraper.npm import get_all_versions
30-
from vulnerabilities.scraper.npm import remove_spaces
3130

3231
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
3332
TEST_DATA = os.path.join(BASE_DIR, 'test_data/')
3433

3534

36-
def test_remove_space():
37-
res = remove_spaces(">= 1.2.1 || <= 2.1.1")
38-
assert res == '>=1.2.1 || <=2.1.1'
39-
40-
res = remove_spaces(">= v1.2.1 || <= V2.1.1")
41-
assert res == '>=1.2.1 || <=2.1.1'
42-
43-
4435
def test_get_all_versions():
4536
x = get_all_versions('electron')
4637
expected = ['0.1.2', '2.0.0', '3.0.0',

0 commit comments

Comments
 (0)