os-normalizer 0.4.2__tar.gz → 0.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of os-normalizer might be problematic. Click here for more details.
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/CHANGELOG.md +4 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/PKG-INFO +1 -1
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/windows.py +32 -17
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/pyproject.toml +1 -1
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/.gitignore +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/.python-version +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/.uv-cache/.gitignore +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/.uv-cache/.lock +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/.uv-cache/CACHEDIR.TAG +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/.uv-cache/interpreter-v4/7e11d242fb84b9e8/939db8dea853eb17.msgpack +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/.uv-cache/sdists-v9/.git +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/.uv-cache/sdists-v9/.gitignore +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/LICENSE +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/README.md +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/RELEASING.md +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/__init__.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/constants.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/cpe.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/helpers.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/models.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/os_normalizer.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/__init__.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/bsd.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/linux.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/macos.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/mobile.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/network/__init__.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/network/cisco.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/network/fortinet.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/network/huawei.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/network/juniper.py +0 -0
- {os_normalizer-0.4.2 → os_normalizer-0.4.3}/os_normalizer/parsers/network/netgear.py +0 -0
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
All notable changes to this project are documented here.
|
|
4
4
|
This file adheres to Keep a Changelog and Semantic Versioning.
|
|
5
5
|
|
|
6
|
+
## [0.4.3] - 2025-10-20
|
|
7
|
+
|
|
8
|
+
- Fixed: Windows build parsing and inconsistent strings
|
|
9
|
+
|
|
6
10
|
## [0.4.2] - 2025-10-20
|
|
7
11
|
|
|
8
12
|
- Fixed: Windows product fingerprinting by build number
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: os-normalizer
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: Normalize raw OS strings/metadata into structured data (family, product, version, arch).
|
|
5
5
|
Project-URL: Homepage, https://github.com/johnscillieri/os-normalizer
|
|
6
6
|
Project-URL: Repository, https://github.com/johnscillieri/os-normalizer
|
|
@@ -20,7 +20,8 @@ if TYPE_CHECKING:
|
|
|
20
20
|
|
|
21
21
|
VERSION_PATTERN = re.compile(r"\b(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?\b")
|
|
22
22
|
NT_PATTERN = re.compile(r"\bnt\s*(\d+)(?:\.(\d+))?", re.IGNORECASE)
|
|
23
|
-
BUILD_PATTERN = re.compile(r"\bbuild\s*(?:number\s*)?(\d{3,5})\b", re.IGNORECASE)
|
|
23
|
+
BUILD_PATTERN = re.compile(r"\bbuild\s*(?:number\s*)?[:=\s-]*?(\d{3,5})\b", re.IGNORECASE)
|
|
24
|
+
KERNEL_PATTERN = re.compile(r"\bkernel\s*[:=\s-]*?(\d+)(?:\.(\d+))?", re.IGNORECASE)
|
|
24
25
|
SP_PATTERN = re.compile(r"\bsp(\d)\b", re.IGNORECASE)
|
|
25
26
|
|
|
26
27
|
EDITION_KEYWORDS: list[tuple[str, str]] = [
|
|
@@ -141,6 +142,13 @@ def _extract_version_state(text: str) -> VersionState:
|
|
|
141
142
|
state.nt_minor = state.nt_minor if state.nt_minor is not None else minr
|
|
142
143
|
state.explicit = True
|
|
143
144
|
|
|
145
|
+
if state.nt_major is None:
|
|
146
|
+
kernel_match = KERNEL_PATTERN.search(text)
|
|
147
|
+
if kernel_match:
|
|
148
|
+
state.nt_major = int(kernel_match.group(1))
|
|
149
|
+
state.nt_minor = int(kernel_match.group(2)) if kernel_match.group(2) else 0
|
|
150
|
+
state.explicit = True
|
|
151
|
+
|
|
144
152
|
if state.build is None:
|
|
145
153
|
build_match = BUILD_PATTERN.search(text)
|
|
146
154
|
if build_match:
|
|
@@ -157,11 +165,8 @@ def _apply_build_context(state: VersionState, product: str | None, server_hint:
|
|
|
157
165
|
return product, server_hint
|
|
158
166
|
|
|
159
167
|
product_from_build, channel, is_server_build = _lookup_build(build_num, server_hint)
|
|
160
|
-
if product_from_build:
|
|
161
|
-
|
|
162
|
-
product = product_from_build
|
|
163
|
-
elif product != product_from_build and _build_inference_is_more_precise(product, product_from_build):
|
|
164
|
-
product = product_from_build
|
|
168
|
+
if product_from_build and (not product or _build_inference_should_replace(product, product_from_build)):
|
|
169
|
+
product = product_from_build
|
|
165
170
|
if is_server_build:
|
|
166
171
|
server_hint = True
|
|
167
172
|
state.channel = channel
|
|
@@ -192,11 +197,18 @@ def _apply_version_numbers(p: OSData, defaults: ProductDefaults, state: VersionS
|
|
|
192
197
|
def _set_kernel_version(p: OSData, defaults: ProductDefaults | None, state: VersionState) -> None:
|
|
193
198
|
"""Populate kernel_version using explicit tokens, build channel, or defaults."""
|
|
194
199
|
kernel_version: str | None = None
|
|
195
|
-
if
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
200
|
+
if (
|
|
201
|
+
state.explicit
|
|
202
|
+
and state.channel
|
|
203
|
+
and (state.nt_major is None or state.nt_major >= 10)
|
|
204
|
+
and (defaults is None or defaults.kernel_version is None)
|
|
205
|
+
):
|
|
206
|
+
kernel_version = state.channel
|
|
207
|
+
elif state.explicit and state.nt_major is not None:
|
|
208
|
+
if state.nt_minor is not None:
|
|
199
209
|
kernel_version = f"{state.nt_major}.{state.nt_minor}"
|
|
210
|
+
elif state.nt_major >= 10 and state.channel:
|
|
211
|
+
kernel_version = state.channel
|
|
200
212
|
if kernel_version is None and defaults and defaults.kernel_version:
|
|
201
213
|
kernel_version = defaults.kernel_version
|
|
202
214
|
if kernel_version:
|
|
@@ -253,13 +265,16 @@ def _lookup_build(build_num: int, server_hint: bool) -> tuple[str | None, str |
|
|
|
253
265
|
return candidate
|
|
254
266
|
|
|
255
267
|
|
|
256
|
-
def
|
|
257
|
-
"""Return True when
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
268
|
+
def _build_inference_should_replace(existing: str, inferred: str) -> bool:
|
|
269
|
+
"""Return True when build metadata should override a detected product label."""
|
|
270
|
+
existing_lower = existing.lower()
|
|
271
|
+
inferred_lower = inferred.lower()
|
|
272
|
+
|
|
273
|
+
if existing_lower == inferred_lower:
|
|
274
|
+
return False
|
|
275
|
+
if inferred_lower.startswith(existing_lower):
|
|
276
|
+
return False
|
|
277
|
+
return True
|
|
263
278
|
|
|
264
279
|
|
|
265
280
|
def _product_from_nt(major: int, minor: int, server_hint: bool) -> str | None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|