我非常接近最终使用命令行为JCDK 2.2.2创建CAP文件。我首先将源文件Transfer.java编译成类文件Transfer.class,然后尝试生成CAP文件。一切都很好,除了我得到错误
尝试从类文件构建Java Card小程序时,从CAP转换器工具错误:第56行:smartTransfer.Transfer:不支持int类型的中间值,必须将中间值转换为short或byte类型。
。我不知道这个错误来自何处,因此无法将值分配给字节或短。
我记得当我使用JCDK 3.0.5安装Eclipse Neon时,有一个未知位置的int错误,但applet仍在运行。我想由于我的系统上的JRE。
这是我的applet代码:
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报头时,我能想到的唯一未分配的中间值将是指令情况。
这个错误可能来自哪里?
答案 0 :(得分:3)
错误已经清楚地告诉您源文件中包含有问题代码的行。在您的情况下,错误是由if语句
的所有行引起的if ((offset + lc) > SIZE_MEMORY)
在这种情况下,整数类型的中间值为offset + lc
。虽然plus运算符的两个操作数都是short,但是plus运算符的结果是int。因此,您需要将此值明确地转换为简短的:
if ((short)(offset + lc) > SIZE_MEMORY)
另请注意,常量SIZE_MEMORY
应该是short类型而不是byte:
final static short SIZE_MEMORY = (short) 127;