Skip to content
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

Further adjusted handling of binary/string data #280

Merged
merged 1 commit into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 12 additions & 4 deletions wordfence/cli/remediate/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,25 @@
REPORT_FORMAT_CSV, REPORT_FORMAT_TSV, REPORT_FORMAT_NULL_DELIMITED, \
REPORT_FORMAT_LINE_DELIMITED
from ..context import CliContext
from ...util.encoding import bytes_to_str


class RemediationReportColumn(ReportColumnEnum):
PATH = 'path', lambda record: os.fsdecode(record.result.path),
STATUS = 'status', lambda record: record.get_status(),
TYPE = 'type', lambda record: record.result.identity.type,
SITE = 'site', \
lambda record: record.result.identity.site.core_path \
lambda record: os.fsdecode(
record.result.identity.site.core_path
) \
if record.result.identity.site is not None \
else None
TARGET_PATH = 'target_path', lambda record: record.result.target_path,
TARGET_PATH = 'target_path', \
lambda record: os.fsdecode(record.result.target_path),
WORDPRESS_VERSION = 'wordpress_version', \
lambda record: record.result.identity.site.get_version() \
lambda record: bytes_to_str(
record.result.identity.site.get_version()
) \
if record.result.identity.site is not None \
else None
EXTENSION_SLUG = 'extension_slug', \
Expand All @@ -37,7 +43,9 @@ class RemediationReportColumn(ReportColumnEnum):
lambda record: record.result.identity.extension.get_name() \
if record.result.identity.extension is not None else None
EXTENSION_VERSION = 'extension_version', \
lambda record: record.result.identity.extension.version \
lambda record: bytes_to_str(
record.result.identity.extension.version
) \
if record.result.identity.extension is not None else None


Expand Down
5 changes: 3 additions & 2 deletions wordfence/cli/vulnscan/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ...api.intelligence import VulnerabilityFeedVariant
from ...util.terminal import Color, escape, RESET
from ...util.html import Tag
from ...util.versioning import version_to_str
from ..reporting import Report, ReportColumnEnum, ReportFormatEnum, \
ReportRecord, ReportManager, ReportFormat, ReportColumn, \
BaseHumanReadableWriter, ReportEmail, get_config_options, \
Expand All @@ -22,7 +23,7 @@
class VulnScanReportColumn(ReportColumnEnum):
SOFTWARE_TYPE = 'software_type', lambda record: record.software.type.value
SLUG = 'slug', lambda record: record.software.slug
VERSION = 'version', lambda record: record.software.version.decode('ascii')
VERSION = 'version', lambda record: version_to_str(record.software.version)
ID = 'id', \
lambda record: record.vulnerability.identifier
TITLE = 'title', lambda record: record.vulnerability.title
Expand Down Expand Up @@ -92,7 +93,7 @@ def get_severity_color(self, severity: str) -> str:
def format_record(self, record) -> str:
vuln = record.vulnerability
sw = record.software
sw_version = sw.version.decode('ascii')
sw_version = version_to_str(sw.version)
yellow = escape(color=Color.YELLOW)
link = vuln.get_wordfence_link()
blue = escape(color=Color.BLUE)
Expand Down
7 changes: 4 additions & 3 deletions wordfence/cli/vulnscan/vulnscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
is_cve_id
from ...api.intelligence import VulnerabilityFeedVariant
from ...util.caching import Cacheable, DURATION_ONE_DAY
from ...util.versioning import version_to_str
from ...wordpress.site import WordpressSite, WordpressStructureOptions, \
WordpressLocator, WordpressException
from ...wordpress.plugin import PluginLoader, Plugin
Expand Down Expand Up @@ -47,7 +48,7 @@ def _scan_plugins(
for plugin in plugins:
log.debug(
f'Plugin {plugin.slug}, version: ' +
plugin.version.decode('ascii')
version_to_str(plugin.version)
)
scanner.scan_plugin(plugin, path)

Expand Down Expand Up @@ -75,7 +76,7 @@ def _scan_themes(
for theme in themes:
log.debug(
f'Theme {theme.slug}, version: ' +
theme.version.decode('ascii')
version_to_str(theme.version)
)
scanner.scan_theme(theme, path)

Expand Down Expand Up @@ -119,7 +120,7 @@ def _scan(
version = site.get_version()
log.debug(
'WordPress Core Version: ' +
version.decode('ascii', 'replace')
version_to_str(version)
)
if scan_path is None:
scan_path = path
Expand Down
4 changes: 3 additions & 1 deletion wordfence/php/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from enum import Enum
from collections import deque

from ..util.encoding import str_to_bytes

from .lexing import Lexer, Token, TokenType, CharacterType, STRING_ESCAPE


Expand Down Expand Up @@ -45,7 +47,7 @@ class PhpStateType:

def make_strings_binary(value: Any) -> Any:
if isinstance(value, str):
return value.encode('ascii', 'ignore')
return str_to_bytes(value)
return value


Expand Down
13 changes: 13 additions & 0 deletions wordfence/util/encoding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Optional


def bytes_to_str(value: Optional[bytes]) -> Optional[str]:
if value is None:
return None
return value.decode('latin1', 'replace')


def str_to_bytes(value: Optional[str]) -> Optional[bytes]:
if value is None:
return None
return value.encode('latin1', 'replace')
3 changes: 2 additions & 1 deletion wordfence/util/pcre/bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Optional

from ..library import load_library, LibraryNotAvailableException
from ..encoding import bytes_to_str

from .pcre import PcreException, PcreLibraryNotAvailableException, \
PcreOptions, \
Expand All @@ -18,7 +19,7 @@
_pcre_version = pcre.pcre_version
_pcre_version.argtypes = []
_pcre_version.restype = c_char_p
VERSION = _pcre_version().decode('ascii')
VERSION = bytes_to_str(_pcre_version())


class PcreError(IntEnum):
Expand Down
3 changes: 2 additions & 1 deletion wordfence/util/vectorscan/bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Dict, Optional, Callable, Union, Any

from ..library import load_library, LibraryNotAvailableException
from ..encoding import bytes_to_str
from .. import signals

from .vectorscan import VectorscanException, \
Expand All @@ -19,7 +20,7 @@
_hs_version = hs.hs_version
_hs_version.argtypes = []
_hs_version.restype = c_char_p
VERSION = _hs_version().decode('ascii')
VERSION = bytes_to_str(_hs_version())
API_VERSION = ''.join(VERSION.split()[:1])


Expand Down
10 changes: 9 additions & 1 deletion wordfence/util/versioning.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import re
from typing import List, Dict, Union, Optional

from .encoding import str_to_bytes, bytes_to_str


PHP_VERSION_DELIMITER = b'.'
PHP_VERSION_ALTERNATE_DELIMITERS = [b'_', b'-', b'+']
Expand Down Expand Up @@ -101,7 +103,7 @@ class PhpVersion:

def __init__(self, version: Union[str, bytes]):
if isinstance(version, str):
version = version.encode('ascii')
version = str_to_bytes(version)
self.version = version
self._components = self.extract_components(version)

Expand Down Expand Up @@ -153,3 +155,9 @@ def compare_php_versions(
if comparison != 0:
return comparison
return 0


def version_to_str(version: Optional[bytes]) -> str:
if version is None:
return 'unknown'
return bytes_to_str(version)
3 changes: 2 additions & 1 deletion wordfence/wordpress/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from ..logging import log
from ..util.io import SYMLINK_IO_ERRORS
from ..util.encoding import str_to_bytes
from .exceptions import ExtensionException


Expand Down Expand Up @@ -93,7 +94,7 @@ def load(
try:
version = header['Version']
if isinstance(version, str):
version = version.encode('ascii')
version = str_to_bytes(version)
except KeyError:
version = None
if base_path is None:
Expand Down
3 changes: 2 additions & 1 deletion wordfence/wordpress/identifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Optional

from ..util.io import resolve_path, get_path_components
from ..util.encoding import bytes_to_str
from .site import WordpressSite
from .exceptions import WordpressException
from .extension import Extension
Expand Down Expand Up @@ -73,7 +74,7 @@ def __str__(self) -> str:
software = self.extension.get_name()
version = self.extension.version
if isinstance(version, bytes):
version = version.decode('ascii')
version = bytes_to_str(version)
return (
os.fsdecode(self.local_path) +
f' of {self.type.value} {software} ({version})'
Expand Down
Loading