mirror of
https://git.freebsd.org/ports.git
synced 2025-05-25 15:36:35 -04:00
103 lines
3.2 KiB
Python
103 lines
3.2 KiB
Python
#!/usr/bin/env python
|
|
|
|
import datetime
|
|
import xml.etree.ElementTree as ET
|
|
import sys
|
|
import re
|
|
|
|
if len(sys.argv) != 2:
|
|
print("Usage: %s vuln.xml" % (sys.argv[0]))
|
|
sys.exit(1)
|
|
|
|
re_date = re.compile(r'^(19|20)[0-9]{2}-[0-9]{2}-[0-9]{2}$')
|
|
re_invalid_package_name = re.compile('[@!#$%^&*()<>?/\|}{~:]')
|
|
|
|
# warn if description has more than X characters
|
|
DESCRIPTION_LENGTH = 5000
|
|
|
|
tree = ET.parse(sys.argv[1])
|
|
root = tree.getroot()
|
|
|
|
namespace = "{http://www.vuxml.org/apps/vuxml-1}"
|
|
|
|
ret = 0
|
|
|
|
|
|
def dateof(string):
|
|
return datetime.datetime.strptime(string, "%Y-%m-%d")
|
|
|
|
all_vids = set()
|
|
|
|
|
|
for vuln in root:
|
|
vid = vuln.get("vid")
|
|
|
|
cancelled = False if vuln.find(namespace+"cancelled") is None else True
|
|
if cancelled:
|
|
continue
|
|
|
|
# Validate Vids
|
|
if vid in all_vids:
|
|
print("Error: duplicate vid : {0}".format(vid))
|
|
all_vids.add(vid)
|
|
|
|
# Validate References
|
|
references = vuln.find(namespace+"references")
|
|
if references is None:
|
|
print("Error: references is None : {0}".format(vid))
|
|
ret = 1
|
|
else:
|
|
prev = references[0]
|
|
for reference in references:
|
|
if reference.tag < prev.tag:
|
|
#print("Warn: tags out of order ({1} and {2}): {0}".format(vid, prev.tag[len(namespace):], reference.tag[len(namespace):]))
|
|
pass
|
|
prev = reference
|
|
|
|
# Validate Dates
|
|
dates = vuln.find(namespace+"dates")
|
|
if dates is None:
|
|
print("Error: no date : {0}".format(vid))
|
|
ret = 1
|
|
else:
|
|
discovery = dates.find(namespace+"discovery")
|
|
entry = dates.find(namespace+"entry")
|
|
modified = dates.find(namespace+"modified")
|
|
if discovery is None:
|
|
print("Error: discovery is None : {0}".format(vid))
|
|
ret = 1
|
|
elif entry is None:
|
|
print("Error: entry is None : {0}".format(vid))
|
|
ret = 1
|
|
else:
|
|
if modified is None:
|
|
modified = entry
|
|
if not (dateof(discovery.text) <= dateof(entry.text) <= dateof(modified.text)):
|
|
print("Error: dates are insane : {0}".format(vid))
|
|
ret = 1
|
|
|
|
# Make sure the dates are in YYYY-MM-DD format
|
|
datelist = [discovery.text, entry.text] + ([modified.text] if modified is not None else [])
|
|
for d in datelist:
|
|
if not re_date.match(d):
|
|
print("Warning: dates must be in YYYY-MM-DD format: {0}".format(d))
|
|
|
|
# Check description lengths
|
|
description = vuln.find(namespace + "description")
|
|
description_len = len(ET.tostring(description))
|
|
if description_len > DESCRIPTION_LENGTH:
|
|
print("Warning: description too long ({0} chars, {1} is warning threshold): {2})" \
|
|
.format(description_len, DESCRIPTION_LENGTH, vid))
|
|
|
|
# Walk and validate package names
|
|
affects = vuln.find(namespace + "affects")
|
|
packages = affects.findall(namespace + "package")
|
|
for package in packages:
|
|
names = package.findall(namespace + "name")
|
|
|
|
for name in names:
|
|
if (re_invalid_package_name.search(name.text) is not None):
|
|
print("Error: invalid package name: " + name.text + " for VID " + format(vid))
|
|
ret = 1
|
|
|
|
sys.exit(ret)
|