Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error message when loading an invalid class version #15084

Merged
merged 1 commit into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions runtime/bcutil/cfreader.c
Original file line number Diff line number Diff line change
Expand Up @@ -2570,25 +2570,25 @@ static I_32
checkClassVersion(J9CfrClassFile* classfile, U_8* segment, U_32 vmVersionShifted, U_32 flags)
{
const U_32 offset = 6;
const U_16 max_allowed_version = vmVersionShifted >> BCT_MajorClassFileVersionMaskShift;
const U_16 maxMajorVersion = vmVersionShifted >> BCT_MajorClassFileVersionMaskShift;
const U_16 majorVersion = classfile->majorVersion;
const U_16 minorVersion = classfile->minorVersion;
U_32 errorCode = J9NLS_CFR_ERR_MAJOR_VERSION__ID;
U_32 errorCode = J9NLS_CFR_ERR_MAJOR_VERSION2__ID;

/* Support versions 45.0 -> <whatever is legal for this VM> */
if (majorVersion == max_allowed_version) {
errorCode = J9NLS_CFR_ERR_MINOR_VERSION__ID;
if (majorVersion == maxMajorVersion) {
errorCode = J9NLS_CFR_ERR_MINOR_VERSION2__ID;
if (0 == minorVersion) {
return 0;
} else if (0xffff == minorVersion) {
errorCode = J9NLS_CFR_ERR_PREVIEW_VERSION__ID;
errorCode = J9NLS_CFR_ERR_PREVIEW_VERSION_NOT_ENABLED__ID;
/* Preview flags won't be set for Java 8 & earlier (excluding cfdump) */
if (J9_ARE_ANY_BITS_SET(flags, BCT_AnyPreviewVersion | BCT_EnablePreview)) {
return 0;
}
}
} else if ((majorVersion >= 45) && (majorVersion < max_allowed_version)) {
errorCode = J9NLS_CFR_ERR_MINOR_VERSION__ID;
} else if ((majorVersion >= 45) && (majorVersion < maxMajorVersion)) {
errorCode = J9NLS_CFR_ERR_MINOR_VERSION2__ID;
if (majorVersion <= 55) {
/* versions prior to and including Java 11, allow any minor */
return 0;
Expand All @@ -2598,7 +2598,7 @@ checkClassVersion(J9CfrClassFile* classfile, U_8* segment, U_32 vmVersionShifted
return 0;
}
if (0xffff == minorVersion) {
errorCode = J9NLS_CFR_ERR_PREVIEW_VERSION__ID;
errorCode = J9NLS_CFR_ERR_PREVIEW_VERSION2__ID;
/* Allow cfdump to dump preview classes from other releases */
if (J9_ARE_ANY_BITS_SET(flags, BCT_AnyPreviewVersion)) {
return 0;
Expand All @@ -2607,6 +2607,9 @@ checkClassVersion(J9CfrClassFile* classfile, U_8* segment, U_32 vmVersionShifted
}

buildError((J9CfrError *) segment, errorCode, CFR_ThrowUnsupportedClassVersionError, offset);
((J9CfrError *) segment)->errorMaxMajorVersion = maxMajorVersion;
((J9CfrError *) segment)->errorMajorVersion = majorVersion;
((J9CfrError *) segment)->errorMinorVersion = minorVersion;
keithc-ca marked this conversation as resolved.
Show resolved Hide resolved
return -1;
}

Expand Down Expand Up @@ -2830,8 +2833,8 @@ j9bcutil_readClassFileBytes(J9PortLibrary *portLib,

Trc_BCU_j9bcutil_readClassFileBytes_Entry();

/* There must be at least enough space for the classfile struct. */
if (segmentLength < (UDATA) sizeof(J9CfrClassFile)) {
/* There must be at least enough space for the classfile struct or error struct. */
if ((segmentLength < (UDATA) sizeof(J9CfrClassFile)) || (segmentLength < (UDATA) sizeof(J9CfrError))) {
Trc_BCU_j9bcutil_readClassFileBytes_Exit(-2);
return -2;
}
Expand Down
609 changes: 251 additions & 358 deletions runtime/nls/cfre/cfrerr.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_ca.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_cs.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_de.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_es.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_fr.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_hu.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_it.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_ja.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_ko.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_pl.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_pt_BR.nls

Large diffs are not rendered by default.

180 changes: 13 additions & 167 deletions runtime/nls/cfre/cfrerr_ru.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_sk.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_sl.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_tr.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_zh.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_zh_CN.nls

Large diffs are not rendered by default.

181 changes: 12 additions & 169 deletions runtime/nls/cfre/cfrerr_zh_TW.nls

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,9 @@ typedef struct J9CfrError {
I_32 errorBsmIndex;
U_32 errorBsmArgsIndex;
U_32 errorCPType;
U_16 errorMaxMajorVersion;
U_16 errorMajorVersion;
U_16 errorMinorVersion;
struct J9CfrMethod* errorMember;
struct J9CfrConstantPoolInfo* constantPool;
} J9CfrError;
Expand Down
84 changes: 82 additions & 2 deletions runtime/verutil/cfrerr.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2019 IBM Corp. and others
* Copyright (c) 1991, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -78,6 +78,70 @@ getJ9CfrErrorBsmMessage(J9PortLibrary* portLib, J9CfrError* error, const U_8* cl
return errorString;
}

const char*
getJ9CfrErrorMajorVersionMessage(J9PortLibrary* portLib, J9CfrError* error, const U_8* className, UDATA classNameLength)
{
PORT_ACCESS_FROM_PORT(portLib);
const char *template = j9nls_lookup_message(J9NLS_ERROR | J9NLS_DO_NOT_APPEND_NEWLINE, J9NLS_CFR_ERR_MAJOR_VERSION2, NULL);
UDATA allocSize = strlen(template) + classNameLength + (MAX_INT_SIZE * 4) + 1;
char *errorString = j9mem_allocate_memory(allocSize, OMRMEM_CATEGORY_VM);

if (NULL != errorString) {
j9str_printf(PORTLIB, errorString, allocSize, template,
error->errorMajorVersion, error->errorMinorVersion, classNameLength, className, error->errorMaxMajorVersion, error->errorOffset);
}

return errorString;
}

const char*
getJ9CfrErrorMinorVersionMessage(J9PortLibrary* portLib, J9CfrError* error, const U_8* className, UDATA classNameLength)
{
PORT_ACCESS_FROM_PORT(portLib);
const char *template = j9nls_lookup_message(J9NLS_ERROR | J9NLS_DO_NOT_APPEND_NEWLINE, J9NLS_CFR_ERR_MINOR_VERSION2, NULL);
UDATA allocSize = strlen(template) + classNameLength + (MAX_INT_SIZE * 3) + 1;
char *errorString = j9mem_allocate_memory(allocSize, OMRMEM_CATEGORY_VM);

if (NULL != errorString) {
j9str_printf(PORTLIB, errorString, allocSize, template,
classNameLength, className, error->errorMinorVersion, error->errorMajorVersion, error->errorOffset);
}

return errorString;
}

const char*
getJ9CfrErrorPreviewVersionMessage(J9PortLibrary* portLib, J9CfrError* error, const U_8* className, UDATA classNameLength)
{
PORT_ACCESS_FROM_PORT(portLib);
const char *template = j9nls_lookup_message(J9NLS_ERROR | J9NLS_DO_NOT_APPEND_NEWLINE, J9NLS_CFR_ERR_PREVIEW_VERSION2, NULL);
UDATA allocSize = strlen(template) + classNameLength + (MAX_INT_SIZE * 4) + 1;
char *errorString = j9mem_allocate_memory(allocSize, OMRMEM_CATEGORY_VM);

if (NULL != errorString) {
j9str_printf(PORTLIB, errorString, allocSize, template,
error->errorMajorVersion, error->errorMinorVersion, classNameLength, className, error->errorMaxMajorVersion, error->errorOffset);
}

return errorString;
}

const char*
getJ9CfrErrorPreviewVersionNotEnabledMessage(J9PortLibrary* portLib, J9CfrError* error, const U_8* className, UDATA classNameLength)
{
PORT_ACCESS_FROM_PORT(portLib);
const char *template = j9nls_lookup_message(J9NLS_ERROR | J9NLS_DO_NOT_APPEND_NEWLINE, J9NLS_CFR_ERR_PREVIEW_VERSION_NOT_ENABLED, NULL);
UDATA allocSize = strlen(template) + classNameLength + (MAX_INT_SIZE * 3) + 1;
char *errorString = j9mem_allocate_memory(allocSize, OMRMEM_CATEGORY_VM);

if (NULL != errorString) {
j9str_printf(PORTLIB, errorString, allocSize, template,
error->errorMajorVersion, error->errorMinorVersion, classNameLength, className, error->errorOffset);
}

return errorString;
}

const char*
getJ9CfrErrorDetailMessageNoMethod(J9PortLibrary* portLib, J9CfrError* error, const U_8* className, UDATA classNameLength)
{
Expand All @@ -87,6 +151,18 @@ getJ9CfrErrorDetailMessageNoMethod(J9PortLibrary* portLib, J9CfrError* error, co
case J9NLS_CFR_ERR_BAD_BOOTSTRAP_ARGUMENT_ENTRY__ID:
errorString = getJ9CfrErrorBsmMessage(portLib, error, className, classNameLength);
break;
case J9NLS_CFR_ERR_MAJOR_VERSION2__ID:
errorString = getJ9CfrErrorMajorVersionMessage(portLib, error, className, classNameLength);
break;
case J9NLS_CFR_ERR_MINOR_VERSION2__ID:
errorString = getJ9CfrErrorMinorVersionMessage(portLib, error, className, classNameLength);
break;
case J9NLS_CFR_ERR_PREVIEW_VERSION2__ID:
errorString = getJ9CfrErrorPreviewVersionMessage(portLib, error, className, classNameLength);
break;
case J9NLS_CFR_ERR_PREVIEW_VERSION_NOT_ENABLED__ID:
errorString = getJ9CfrErrorPreviewVersionNotEnabledMessage(portLib, error, className, classNameLength);
break;
default:
errorString = getJ9CfrErrorNormalMessage(portLib, error, className, classNameLength);
break;
Expand Down Expand Up @@ -146,7 +222,7 @@ buildError(J9CfrError * errorStruct, UDATA code, UDATA action, UDATA offset)
errorStruct->errorPC = 0;
errorStruct->errorMember = NULL;
errorStruct->constantPool = NULL;

/* Jazz 82615: Initialize with default values if detailed error message is not required */
errorStruct->verboseErrorType = 0;
errorStruct->errorDataIndex = 0;
Expand All @@ -156,6 +232,10 @@ buildError(J9CfrError * errorStruct, UDATA code, UDATA action, UDATA offset)
errorStruct->errorBsmIndex = -1;
errorStruct->errorBsmArgsIndex = 0;
errorStruct->errorCPType = 0;

errorStruct->errorMaxMajorVersion = 0;
errorStruct->errorMajorVersion = 0;
errorStruct->errorMinorVersion = 0;
}

void
Expand Down