more robust "delivery suspend software"

upstream's code doesn't allow any way to match a version that `semver`
can't parse, not even with `*`:

```
> semver.satisfies('1-2-3','*');
false
> semver.satisfies('1.3','*');
false
> semver.satisfies('1.2.3','*');
true
```

while I was there, I added support for regexp in both name and
version, and added unit tests
This commit is contained in:
dakkar 2025-08-03 12:36:33 +01:00
parent 4505a848f6
commit 9b164003d4
4 changed files with 140 additions and 13 deletions

View file

@ -222,18 +222,37 @@ export class UtilityService {
@bindThis
public isDeliverSuspendedSoftware(software: Pick<MiInstance, 'softwareName' | 'softwareVersion'>): SoftwareSuspension | undefined {
if (software.softwareName == null) return undefined;
if (software.softwareVersion == null) {
// software version is null; suspend iff versionRange is *
return this.meta.deliverSuspendedSoftware.find(x =>
x.software === software.softwareName
&& x.versionRange.trim() === '*');
} else {
const softwareVersion = software.softwareVersion;
return this.meta.deliverSuspendedSoftware.find(x =>
x.software === software.softwareName
&& semver.satisfies(softwareVersion, x.versionRange, { includePrerelease: true }));
// a missing name or version is treated as the empty string
const instanceName = software.softwareName ?? '';
const instanceVersion = software.softwareVersion ?? '';
function maybeRegexpMatch(test: string, target: string): boolean {
const regexpStrPair = test.trim().match(/^\/(.+)\/(.*)$/);
if (!regexpStrPair) return false; // not a regexp, can't match
try {
return new RE2(regexpStrPair[1], regexpStrPair[2]).test(target);
} catch (err) {
return false; // not a well-formed regexp, can't match
}
}
// each element of `meta.deliverSuspendedSoftware` can have a
// normal string, a `*`, or a `/regexp/` for software or
// versionRange
return this.meta.deliverSuspendedSoftware.find(
x => (
(
x.software.trim() === '*' ||
x.software === instanceName ||
maybeRegexpMatch(x.software, instanceName)
) && (
x.versionRange.trim() === '*' ||
semver.satisfies(instanceVersion, x.versionRange, { includePrerelease: true }) ||
maybeRegexpMatch(x.versionRange, instanceVersion)
)
)
);
}
/**