Harden java-package validation (#1165)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 10b8fe1e-18f4-42cb-8672-11215715a713
This commit is contained in:
Bruno Borges
2026-07-29 00:50:01 -04:00
committed by GitHub
parent 6e26972896
commit 19c23b379e
8 changed files with 403 additions and 63 deletions
+6 -30
View File
@@ -22,42 +22,18 @@ import {
import {JetBrainsDistribution} from './jetbrains/installer.js';
import {KonaDistribution} from './kona/installer.js';
import {OpenJdkDistribution} from './openjdk/installer.js';
enum JavaDistribution {
Adopt = 'adopt',
AdoptHotspot = 'adopt-hotspot',
AdoptOpenJ9 = 'adopt-openj9',
Temurin = 'temurin',
Zulu = 'zulu',
Liberica = 'liberica',
LibericaNik = 'liberica-nik',
JdkFile = 'jdkfile',
Microsoft = 'microsoft',
Semeru = 'semeru',
Corretto = 'corretto',
Oracle = 'oracle',
Dragonwell = 'dragonwell',
SapMachine = 'sapmachine',
GraalVM = 'graalvm',
GraalVMCommunity = 'graalvm-community',
JetBrains = 'jetbrains',
Kona = 'kona',
OracleOpenJdk = 'oracle-openjdk'
}
import {JavaDistribution, validateJavaPackage} from './package-types.js';
export function getJavaDistribution(
distributionName: string,
installerOptions: JavaInstallerOptions,
jdkFile?: string
): JavaBase | null {
if (
installerOptions.packageType === 'jdk+jmods' &&
distributionName !== JavaDistribution.Temurin
) {
throw new Error(
"java-package 'jdk+jmods' is only supported for distribution 'temurin'."
);
}
validateJavaPackage(
distributionName,
installerOptions.packageType,
installerOptions.version
);
switch (distributionName) {
case JavaDistribution.JdkFile:
+135
View File
@@ -0,0 +1,135 @@
import semver from 'semver';
import {convertVersionToSemver} from '../util.js';
export enum JavaDistribution {
Adopt = 'adopt',
AdoptHotspot = 'adopt-hotspot',
AdoptOpenJ9 = 'adopt-openj9',
Temurin = 'temurin',
Zulu = 'zulu',
Liberica = 'liberica',
LibericaNik = 'liberica-nik',
JdkFile = 'jdkfile',
Microsoft = 'microsoft',
Semeru = 'semeru',
Corretto = 'corretto',
Oracle = 'oracle',
Dragonwell = 'dragonwell',
SapMachine = 'sapmachine',
GraalVM = 'graalvm',
GraalVMCommunity = 'graalvm-community',
JetBrains = 'jetbrains',
Kona = 'kona',
OracleOpenJdk = 'oracle-openjdk'
}
export const JAVA_PACKAGE_CAPABILITIES = {
[JavaDistribution.Adopt]: ['jdk', 'jre'],
[JavaDistribution.AdoptHotspot]: ['jdk', 'jre'],
[JavaDistribution.AdoptOpenJ9]: ['jdk', 'jre'],
[JavaDistribution.Temurin]: ['jdk', 'jre', 'jdk+jmods'],
[JavaDistribution.Zulu]: [
'jdk',
'jre',
'jdk+fx',
'jre+fx',
'jdk+crac',
'jre+crac'
],
[JavaDistribution.Liberica]: ['jdk', 'jre', 'jdk+fx', 'jre+fx'],
[JavaDistribution.LibericaNik]: ['jdk', 'jdk+fx'],
[JavaDistribution.JdkFile]: ['jdk'],
[JavaDistribution.Microsoft]: ['jdk'],
[JavaDistribution.Semeru]: ['jdk', 'jre'],
[JavaDistribution.Corretto]: ['jdk', 'jre'],
[JavaDistribution.Oracle]: ['jdk'],
[JavaDistribution.Dragonwell]: ['jdk'],
[JavaDistribution.SapMachine]: ['jdk', 'jre'],
[JavaDistribution.GraalVM]: ['jdk'],
[JavaDistribution.GraalVMCommunity]: ['jdk'],
[JavaDistribution.JetBrains]: [
'jdk',
'jre',
'jdk+jcef',
'jre+jcef',
'jdk+ft',
'jre+ft'
],
[JavaDistribution.Kona]: ['jdk'],
[JavaDistribution.OracleOpenJdk]: ['jdk']
} as const satisfies Record<JavaDistribution, readonly string[]>;
export function validateJavaPackage(
distributionName: string,
packageType: string,
version: string
): void {
if (!isJavaDistribution(distributionName)) {
return;
}
const supportedPackages: readonly string[] =
JAVA_PACKAGE_CAPABILITIES[distributionName];
if (!supportedPackages.includes(packageType)) {
throw createUnsupportedPackageError(
distributionName,
packageType,
supportedPackages
);
}
if (
distributionName === JavaDistribution.Temurin &&
packageType === 'jdk+jmods' &&
!canResolveTemurinJmods(version)
) {
throw createUnsupportedPackageError(
distributionName,
packageType,
supportedPackages,
`Package 'jdk+jmods' requires Java 24 or later; requested version '${version}'.`
);
}
}
function isJavaDistribution(value: string): value is JavaDistribution {
return Object.prototype.hasOwnProperty.call(JAVA_PACKAGE_CAPABILITIES, value);
}
function canResolveTemurinJmods(version: string): boolean {
const normalizedVersion = version.trim().toLowerCase();
if (normalizedVersion === 'latest') {
return true;
}
let normalizedRange = normalizedVersion
.replace(/-ea$/, '')
.replace('-ea.', '+');
if (/^\d+(\.\d+){3,}$/.test(normalizedRange)) {
normalizedRange = convertVersionToSemver(normalizedRange);
}
if (!semver.validRange(normalizedRange)) {
// JavaBase owns general version validation and its targeted error messages.
return true;
}
return semver.intersects(normalizedRange, '>=24.0.0', {
includePrerelease: true
});
}
function createUnsupportedPackageError(
distributionName: JavaDistribution,
packageType: string,
supportedPackages: readonly string[],
detail?: string
): Error {
const message = [
`Java package '${packageType}' is not supported for distribution '${distributionName}'.`,
`Supported package types: ${supportedPackages.join(', ')}.`
];
if (detail) {
message.push(detail);
}
return new Error(message.join(' '));
}