java - CAP 转换器失败并显示 'unsupported int type of intermediate value, must cast value to type short or byte'

标签 java applet smartcard javacard apdu

我即将最终使用命令行为 JCDK 2.2.2 创建 CAP 文件。我首先将源文件 Transfer.java 编译为类文件 Transfer.class,然后尝试生成 CAP 文件。一切都很好,除了我收到错误

error: line 56: smartTransfer.Transfer: unsupported int type of intermediate value, must cast intermediate value to type short or byte.

尝试从类文件构建我的 Java Card 小程序时使用 CAP 转换器工具。我不知道这个错误从何而来,因此无法将该值分配给字节或短整型。

我记得当我用JCDK 3.0.5安装Eclipse Neon时,出现了未知位置的int错误,但小程序仍然运行。我猜是因为我的系统上有 JRE。

这是我的小程序代码:

package smartTransfer;
import javacard.framework.*;

public class Transfer extends Applet {
final static byte CLASS = (byte) 0x80;
final static byte WRITE_USER_INFO_INS = 0x07;
final static byte WRITEIT_USER_INFO_INS = 0x08;
final static byte READ_USER_INFO_INS = 0x09;
final static byte READIT_USER_INFO_INS = 0x06;
final static byte SIZE_MEMORY = (short) 127;
static byte[] memory;
static byte[] memoryy;

public static void install(byte[] bArray, short bOffset, byte bLength) throws ISOException {
    new Transfer().register();
    memory = new byte[SIZE_MEMORY];
    memoryy = new byte[SIZE_MEMORY];
}

public void process(APDU apdu)
throws ISOException {
    if (selectingApplet()) return;
    byte[] buffer = apdu.getBuffer();
    if (buffer[ISO7816.OFFSET_CLA] !=CLASS) {
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }
    byte ins = buffer[ISO7816.OFFSET_INS];
    switch (ins) {
    case READ_USER_INFO_INS:
        readUserInfo(apdu);
        break;
    case READIT_USER_INFO_INS:
        readitUserInfo(apdu);
        break;
    case WRITE_USER_INFO_INS:
        writeUserInfo(apdu);
        break;
    case WRITEIT_USER_INFO_INS:
        writeitUserInfo(apdu);
    default:
        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    }
}

private void writeUserInfo(APDU apdu) {
    byte[] cmd_apdu = apdu.getBuffer();
    if (cmd_apdu[ISO7816.OFFSET_P1] != 0x00) 
        ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF);
    if (offset >= SIZE_MEMORY) 
        ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short lc = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF);
    if ((offset + lc) > SIZE_MEMORY) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    if (lc == 0x00) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    getAPDUBody(apdu);    
        Util.arrayCopy(cmd_apdu, (short)((ISO7816.OFFSET_CDATA) & 0x00FF), 
                memory, offset, lc);
        ISOException.throwIt(ISO7816.SW_NO_ERROR); 
     }

public void getAPDUBody(APDU apdu) {
    byte[] buffer = apdu.getBuffer();
    short lc = (short)(buffer[ISO7816.OFFSET_LC] & 0x00FF); 
    if (lc != apdu.setIncomingAndReceive()) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}  

private void readUserInfo(APDU apdu) {
    byte[] cmd_apdu = apdu.getBuffer();
    if (cmd_apdu[ISO7816.OFFSET_P1] != 0x00) ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF); 
    if (offset >= SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short le = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF);
    if (le == 0x00) le = (short)(SIZE_MEMORY - offset);
    if ((offset + le) > SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    apdu.setOutgoing(); 
    apdu.setOutgoingLength((short)le);  
    apdu.sendBytesLong(memory, (short)offset, (short)le); 

}

private void writeitUserInfo(APDU apdu) {
    byte[] cmd_apdu = apdu.getBuffer();
    if (cmd_apdu[ISO7816.OFFSET_P1] != 0) 
        ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF); 
    if (offset >= SIZE_MEMORY) 
        ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short lc = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF);
    if ((offset + lc) > SIZE_MEMORY) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    if (lc == 0x00) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    getAPDUBody(apdu);    
        Util.arrayCopy(cmd_apdu, (short)((ISO7816.OFFSET_CDATA) & 0x00FF), 
                memoryy, offset, lc); 
        ISOException.throwIt(ISO7816.SW_NO_ERROR); 
     }

private void readitUserInfo(APDU apdu) {
    byte[] cmd_apdu = apdu.getBuffer();
    if (cmd_apdu[ISO7816.OFFSET_P1] != 0x00) ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF); 
    if (offset >= SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short le = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF); 
    if (le == 0x00) le = (short)(SIZE_MEMORY - offset);
    if ((offset + le) > SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    apdu.setOutgoing(); 
    apdu.setOutgoingLength((short)le);  
    apdu.sendBytesLong(memoryy, (short)offset, (short)le); 

  }
}

我知道错误出现在第 56 行,但我猜这可能来自 Transfer.class 文件(我无法打开该文件来读取),而不是来自源代码。但我能想到的唯一未分配的中间值是在读取传入的 APDU header 时的指令情况。

这个错误从何而来?

最佳答案

该错误已经清楚地告诉您源文件中包含有问题代码的行。在您的情况下,错误是由所有带有 if 语句的行引起的

if ((offset + lc) > SIZE_MEMORY) 

本例中整数类型的中间值为offset + lc。尽管加号运算符的两个操作数都是短整型,但加号运算符的结果是 int。因此,您需要显式地将此值转换回短值:

if ((short)(offset + lc) > SIZE_MEMORY) 

另请注意,常量 SIZE_MEMORY 可能应该是短类型而不是字节类型:

final static short SIZE_MEMORY = (short) 127;

关于java - CAP 转换器失败并显示 'unsupported int type of intermediate value, must cast value to type short or byte',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43309566/

相关文章:

linux - 关于智能卡安装

java - 为什么<jvmarg value ="-version"/>会禁用打印输出

Java Sprite 掉落?

java - Heroku 中的 CPU/内存监控(适用于 Java)

java - MySQL 和 JApplet(是的,另一个)

c - mifare desfire 中的 ISO14443-4(RATS)

Java smartcardio APDU 响应超时

java - 是否可以在同一方法中使用 (string, int) 来获得 return (string) 和 return (int) ?

java - 如何使 JFrame 透明?

ios - 隐藏标签栏时不会更新安全区域插图