From 0dc21a78ee69d175b6c3422bcbfa41b539decacd Mon Sep 17 00:00:00 2001 From: Mumfrey Date: Fri, 25 Jun 2021 18:01:27 +0100 Subject: [PATCH] Fix some version checks to properly respect *major* class version --- .../asm/mixin/MixinEnvironment.java | 11 ++++++++-- .../transformer/MixinApplicatorStandard.java | 6 +++++- .../mixin/transformer/MixinTargetContext.java | 21 ++++++++++++++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java b/src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java index 747443072..34bff3bb4 100644 --- a/src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java +++ b/src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java @@ -671,9 +671,9 @@ boolean isSupported() { private CompatibilityLevel maxCompatibleLevel; - private CompatibilityLevel(int ver, int classMajorVersion, int languageFeatures) { + private CompatibilityLevel(int ver, int classVersion, int languageFeatures) { this.ver = ver; - this.classVersion = classMajorVersion & 0xFF; + this.classVersion = classVersion; this.languageFeatures = languageFeatures; } @@ -702,6 +702,13 @@ public int getClassVersion() { return this.classVersion; } + /** + * Get the major class version expected at this compatibility level + */ + public int getClassMajorVersion() { + return this.classVersion & 0xFFFF; + } + /** * Get all supported language features */ diff --git a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinApplicatorStandard.java b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinApplicatorStandard.java index 4bb7b5edc..dd2ef0e12 100644 --- a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinApplicatorStandard.java +++ b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinApplicatorStandard.java @@ -434,7 +434,11 @@ protected void applyAttributes(MixinTargetContext mixin) { if (mixin.shouldSetSourceFile()) { this.targetClass.sourceFile = mixin.getSourceFile(); } - this.targetClass.version = Math.max(this.targetClass.version, mixin.getMinRequiredClassVersion()); + + int requiredVersion = mixin.getMinRequiredClassVersion(); + if ((requiredVersion & 0xFFFF) > (this.targetClass.version & 0xFFFF)) { + this.targetClass.version = requiredVersion; + } } /** diff --git a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java index ac9c05b2e..51f2077d2 100644 --- a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java +++ b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java @@ -1071,13 +1071,28 @@ FieldNode findRemappedField(FieldNode field) { * @param version version to require */ protected void requireVersion(int version) { - this.minRequiredClassVersion = Math.max(this.minRequiredClassVersion, version); + int majorVersion = version & 0xFFFF; + int minorVersion = (version >> 16) & 0xFFFF; + + if (majorVersion <= (this.minRequiredClassVersion & 0xFFFF)) { + return; + } + + this.minRequiredClassVersion = version; // This validation is done on the mixin beforehand, however it's still // possible that an upstream transformer can inject unsupported // instructions without updating the class version. - if ((version & 0xFFFF) > ASM.getMaxSupportedClassVersionMajor()) { - throw new InvalidMixinException(this, "Unsupported mixin class version " + version); + if (majorVersion > ASM.getMaxSupportedClassVersionMajor()) { + throw new InvalidMixinException(this, String.format("Unsupported mixin class version %d.%d. ASM supports %s", + majorVersion, minorVersion, ASM.getClassVersionString())); + } + + CompatibilityLevel compatibilityLevel = MixinEnvironment.getCompatibilityLevel(); + if (majorVersion > compatibilityLevel.getClassMajorVersion()) { + MixinTargetContext.logger.warn( + "{}: Class version {}.{} required is higher than the class version supported by the current compatibility level {} ", + this, majorVersion, minorVersion, compatibilityLevel); } }