Skip to content

Commit

Permalink
Fix some version checks to properly respect *major* class version
Browse files Browse the repository at this point in the history
  • Loading branch information
Mumfrey committed Jun 25, 2021
1 parent 33c1d2e commit 0dc21a7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 6 deletions.
11 changes: 9 additions & 2 deletions src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down

0 comments on commit 0dc21a7

Please sign in to comment.