Skip to content

Commit

Permalink
Merge pull request #32 from jasinner/public-oracle
Browse files Browse the repository at this point in the history
update public date on oracle flaws to be 3rd Tuesday from Apr 2022
  • Loading branch information
jasinner committed Jul 11, 2024
2 parents f0f4623 + c498476 commit 0045554
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 32 deletions.
2 changes: 1 addition & 1 deletion advisory_parser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
from .parser import Parser


__version__ = "1.12"
__version__ = "1.13"
78 changes: 59 additions & 19 deletions advisory_parser/parsers/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Author: Martin Prpič, Red Hat Product Security
# License: LGPLv3+

import calendar
import re
from datetime import datetime, timedelta

Expand All @@ -14,6 +15,21 @@
MARIADB_VULN_PAGE = "https://mariadb.com/kb/en/security/"
VERSION_REGEX = re.compile(r"(\d\d?\.\d\.\d\d?)")

month_to_num = {
"jan": 1,
"feb": 2,
"mar": 3,
"apr": 4,
"may": 5,
"jun": 6,
"jul": 7,
"aug": 8,
"sep": 9,
"oct": 10,
"nov": 11,
"dec": 12,
}


def _nearest_tuesday(year, month, day=17):
"""For a given year and month, return nearest Tuesday to the 17th of that month
Expand All @@ -24,25 +40,8 @@ def _nearest_tuesday(year, month, day=17):
July and October."
[https://www.oracle.com/security-alerts/]
"""
month_to_num = {
"jan": 1,
"feb": 2,
"mar": 3,
"apr": 4,
"may": 5,
"jun": 6,
"jul": 7,
"aug": 8,
"sep": 9,
"oct": 10,
"nov": 11,
"dec": 12,
}

if month.lower() not in month_to_num:
raise AdvisoryParserTextException("Invalid month parsed from advisory URL:", str(month))

base_date = datetime(year, month_to_num[month.lower()], day)
base_date = datetime(year, month, day)

previous_tuesday = base_date - timedelta(days=((base_date.weekday() + 6) % 7))
next_tuesday = base_date + timedelta(days=((1 - base_date.weekday()) % 7))
Expand All @@ -54,6 +53,34 @@ def _nearest_tuesday(year, month, day=17):
)


def _third_tuesday(year, month):
"""For a given year and month, return the 3rd Tuesday of that month
"Critical Patch Updates provide security patches for supported Oracle on-premises products.
They are available to customers with valid support contracts. Starting in April 2022,
Critical Patch Updates are released on the third Tuesday of January, April, July, and October
(They were previously published on the Tuesday closest to the 17th day of January, April, July,
and October). The next four dates are:
16 July 2024
15 October 2024
21 January 2025
15 April 2025
"
[https://www.oracle.com/security-alerts/]
"""

c = calendar.Calendar()
monthcal = c.monthdatescalendar(year, month)
third_tuesday = [
day
for week in monthcal
for day in week
if day.weekday() == calendar.TUESDAY and day.month == month
][2]
return third_tuesday


def create_mariadb_cve_map():
# Pull plain text of the MariaDB page since the HTML is invalid: it
# doesn't define </li> ending tags for list elements. The HTML would
Expand Down Expand Up @@ -98,7 +125,20 @@ def parse_mysql_advisory(url):
# Extract the CPU's month and year from the URL since the verbose page has
# no dates on it
month, year = url_match.groups()
cpu_date = _nearest_tuesday(int(year), month)
if month.lower() not in month_to_num:
raise AdvisoryParserTextException("Invalid month parsed from advisory URL:", str(month))
month_num = month_to_num[month.lower()]
year_int = int(year)
# Starting in April 2022, Critical Patch Updates are released on the third Tuesday of January,
# April, July, and October (They were previously published on the Tuesday closest to the 17th
# day of January, April, July, and October).
# [https://www.oracle.com/security-alerts/]
if year_int < 2022:
cpu_date = _nearest_tuesday(year_int, month_num)
elif year_int == 2022 and month_num < 4:
cpu_date = _nearest_tuesday(year_int, month_num)
else:
cpu_date = _third_tuesday(year_int, month_num)
advisory_id = "CPU {} {}".format(month.capitalize(), year)

# Fetch the CPU verbose page
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

setup(
name="advisory-parser",
version="1.12",
version="1.13",
description="Security flaw parser for upstream security advisories",
long_description=description,
url="https://github.com/RedHatProductSecurity/advisory-parser",
Expand Down
36 changes: 25 additions & 11 deletions tests/test_mysql_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,42 @@
except ImportError:
from mock import patch

from advisory_parser.parsers.mysql import parse_mysql_advisory, _nearest_tuesday
from advisory_parser.parsers.mysql import parse_mysql_advisory, _nearest_tuesday, _third_tuesday


@pytest.mark.parametrize(
"year, month, day, expected_date",
[
(2017, "jul", 3, datetime(2017, 7, 4)),
(2017, "jul", 4, datetime(2017, 7, 4)), # Tuesday
(2017, "jul", 5, datetime(2017, 7, 4)),
(2017, "jul", 6, datetime(2017, 7, 4)),
(2017, "jul", 7, datetime(2017, 7, 4)),
(2017, "jul", 8, datetime(2017, 7, 11)),
(2017, "jul", 9, datetime(2017, 7, 11)),
(2017, "jul", 10, datetime(2017, 7, 11)),
(2017, "jul", 11, datetime(2017, 7, 11)), # Tuesday
(2017, "jul", 12, datetime(2017, 7, 11)),
(2017, 7, 3, datetime(2017, 7, 4)),
(2017, 7, 4, datetime(2017, 7, 4)), # Tuesday
(2017, 7, 5, datetime(2017, 7, 4)),
(2017, 7, 6, datetime(2017, 7, 4)),
(2017, 7, 7, datetime(2017, 7, 4)),
(2017, 7, 8, datetime(2017, 7, 11)),
(2017, 7, 9, datetime(2017, 7, 11)),
(2017, 7, 10, datetime(2017, 7, 11)),
(2017, 7, 11, datetime(2017, 7, 11)), # Tuesday
(2017, 7, 12, datetime(2017, 7, 11)),
],
)
def test_nearest_tuesday(year, month, day, expected_date):
assert expected_date == _nearest_tuesday(year, month, day)


@pytest.mark.parametrize(
"year, month, expected_date",
[
(2017, 7, datetime(2017, 7, 18).date()),
(2024, 7, datetime(2024, 7, 16).date()),
(2024, 10, datetime(2024, 10, 15).date()),
(2025, 1, datetime(2025, 1, 21).date()),
(2025, 4, datetime(2025, 4, 15).date()),
],
)
def test_third_tuesday(year, month, expected_date):
assert expected_date == _third_tuesday(year, month)


@patch("advisory_parser.parsers.mysql.get_request")
@patch("advisory_parser.parsers.mysql.create_mariadb_cve_map")
@pytest.mark.parametrize(
Expand Down

0 comments on commit 0045554

Please sign in to comment.