📄 verifier.c
字号:
/*0332./ *=======================================================================*/
/*0333*/
/*0334*/static bool_t
/*0335*/vIsProtectedAccess(METHOD thisMethod, unsigned short index, bool_t isMethod) {
/*0336*/ INSTANCE_CLASS thisClass = thisMethod->ofClass;
/*0337*/ CONSTANTPOOL constPool = thisClass->constPool;
/*0338*/ unsigned short memberClassIndex =
/*0339*/ constPool->entries[index].method.classIndex;
/*0340*/ INSTANCE_CLASS memberClass =
/*0341*/ (INSTANCE_CLASS)constPool->entries[memberClassIndex].clazz;
/*0342*/ INSTANCE_CLASS tClass;
/*0343*/ unsigned short nameTypeIndex;
/*0344*/ unsigned long nameTypeKey;
/*0345*/
/*0346*/ if (memberClass->clazz.packageName == thisClass->clazz.packageName) {
/*0347*/ return FALSE;
/*0348*/ }
/*0349*/
/*0350*/ /* if memberClass isn't a superclass of this class, then we don't worry
/*0351./ * about this case */
/*0352*/ for (tClass = thisClass; ; tClass = tClass->superClass) {
/*0353*/ if (tClass == NULL) {
/*0354*/ return FALSE;
/*0355*/ } else if (tClass == memberClass) {
/*0356*/ break;
/*0357*/ }
/*0358*/ }
/*0359*/
/*0360*/ nameTypeIndex = constPool->entries[index].method.nameTypeIndex;
/*0361*/ nameTypeKey = constPool->entries[nameTypeIndex].nameTypeKey.i;
/*0362*/
/*0363*/ if (isMethod) {
/*0364*/ FOR_EACH_METHOD(method, memberClass->methodTable)
/*0365*/ if (method->nameTypeKey.i == nameTypeKey) {
/*0366*/ return (method->accessFlags & ACC_PROTECTED) != 0;
/*0367*/ }
/*0368*/ END_FOR_EACH_METHOD
/*0369*/ } else {
/*0370*/ FOR_EACH_FIELD(field, memberClass->fieldTable)
/*0371*/ if (field->nameTypeKey.i == nameTypeKey) {
/*0372*/ return (field->accessFlags & ACC_PROTECTED) != 0;
/*0373*/ }
/*0374*/ END_FOR_EACH_FIELD
/*0375*/ }
/*0376*/ return FALSE;
/*0377*/}
/*0378*/
/*0379*//*=========================================================================
/*0380./ * FUNCTION: vPushStack
/*0381./ * TYPE: private operation on the virtual stack
/*0382./ * OVERVIEW: Push a type key onto the virtual stack maintained by
/*0383./ * the verifier. Performs stack overflow check.
/*0384./ *
/*0385./ * INTERFACE:
/*0386./ * parameters: typeKey: the type to be pushed.
/*0387./ * returns: 0 on success, or an error code.
/*0388./ *=======================================================================*/
/*0389*/
/*0390*/static int
/*0391*/vPushStack(unsigned short typeKey)
/*0392*/{
/*0393*/ if (vSP >= vMaxStack) {
/*0394*/ return VE_STACK_OVERFLOW;
/*0395*/ }
/*0396*/ vStack[vSP++] = typeKey;
/*0397*/ return 0;
/*0398*/}
/*0399*/
/*0400*//*=========================================================================
/*0401./ * FUNCTION: vPopStack
/*0402./ * TYPE: private operation on the virtual stack
/*0403./ * OVERVIEW: Pop a type key from the virtual stack maintained by
/*0404./ * the verifier. Performs stack overflow check and type
/*0405./ * check.
/*0406./ *
/*0407./ * INTERFACE:
/*0408./ * parameters: typeKey: the type expected to be poped.
/*0409./ * returns: 0 on success, or an error code.
/*0410./ *=======================================================================*/
/*0411*/
/*0412*/static int
/*0413*/vPopStack(unsigned short typeKey)
/*0414*/{
/*0415*/ if (typeKey == ITEM_DoubleWord || typeKey == ITEM_Category2) {
/*0416*/ if (vSP <= 1) {
/*0417*/ return VE_STACK_UNDERFLOW;
/*0418*/ }
/*0419*/ lastStackPop2.snd = vStack[vSP - 1];
/*0420*/ lastStackPop2.fst = vStack[vSP - 2];
/*0421*/ vSP -= 2;
/*0422*/
/*0423*/ /*
/*0424./ * Neither of the following situations are allowed
/*0425./ * on the operand stack:
/*0426./ *
/*0427./ * | | <-- vSP --> | |
/*0428./ * | ITEM_Category1 | | ITEM_Category1 |
/*0429./ * | ITEM_Long_2 | | ITEM_Double_2 |
/*0430./ * | ITEM_Long | | ITEM_Double |
/*0431./ * ------------------ ------------------
/*0432./ */
/*0433*/ return ((lastStackPop2.fst == ITEM_Long_2) ||
/*0434*/ (lastStackPop2.fst == ITEM_Double_2) ? VE_STACK_BAD_TYPE : 0);
/*0435*/ }
/*0436*/ if (vSP == 0) { /* vSP is unsigned, See bug 4323211 */
/*0437*/ return VE_STACK_UNDERFLOW;
/*0438*/ }
/*0439*/ lastStackPop = vStack[vSP - 1];
/*0440*/ vSP--;
/*0441*/
/*0442*/ if (typeKey == ITEM_Category1) {
/*0443*/ if (lastStackPop == ITEM_Integer ||
/*0444*/#if IMPLEMENTS_FLOAT
/*0445*/ lastStackPop == ITEM_Float ||
/*0446*/#endif
/*0447*/ lastStackPop == ITEM_Null ||
/*0448*/ lastStackPop > 255 ||
/*0449*/ lastStackPop == ITEM_InitObject ||
/*0450*/ (lastStackPop & ITEM_NewObject_Flag)) {
/*0451*/ return 0;
/*0452*/ } else {
/*0453*/ return VE_STACK_EXPECT_CAT1;
/*0454*/ }
/*0455*/ }
/*0456*/ if (!vIsAssignable(lastStackPop, typeKey, NULL)) {
/*0457*/ return VE_STACK_BAD_TYPE;
/*0458*/ }
/*0459*/ return 0;
/*0460*/}
/*0461*/
/*0462*//*=========================================================================
/*0463./ * FUNCTION: vGetLocal
/*0464./ * TYPE: private operation on the virtual local frame
/*0465./ * OVERVIEW: Get a type key from the virtual local frame maintained by
/*0466./ * the verifier. Performs stack overflow check and type
/*0467./ * check.
/*0468./ *
/*0469./ * INTERFACE:
/*0470./ * parameters: index: local index.
/*0471./ * typeKey: the type expected.
/*0472./ * returns: 0 on success, or an error code.
/*0473./ *=======================================================================*/
/*0474*/
/*0475*/static int
/*0476*/vGetLocal(unsigned int index, unsigned short typeKey)
/*0477*/{
/*0478*/ if (index >= vFrameSize) {
/*0479*/ return VE_LOCALS_OVERFLOW;
/*0480*/ }
/*0481*/ lastLocalGet = vLocals[index];
/*0482*/ if (!vIsAssignable(lastLocalGet, typeKey, NULL)) {
/*0483*/ return VE_LOCALS_BAD_TYPE;
/*0484*/ }
/*0485*/ return 0;
/*0486*/}
/*0487*/
/*0488*//*=========================================================================
/*0489./ * FUNCTION: vSetLocal
/*0490./ * TYPE: private operation on the virtual local frame
/*0491./ * OVERVIEW: Set a type key in the virtual local frame maintained by
/*0492./ * the verifier. Performs stack overflow check.
/*0493./ *
/*0494./ * INTERFACE:
/*0495./ * parameters: index: local index.
/*0496./ * typeKey: the supplied type.
/*0497./ * returns: 0 on success, or an error code.
/*0498./ *=======================================================================*/
/*0499*/
/*0500*/static int
/*0501*/vSetLocal(unsigned int index, unsigned short typeKey)
/*0502*/{
/*0503*/ if (index >= vFrameSize) {
/*0504*/ return VE_LOCALS_OVERFLOW;
/*0505*/ }
/*0506*/ if (vLocals[index] == ITEM_Long_2
/*0507*/#if IMPLEMENTS_FLOAT
/*0508*/ || vLocals[index] == ITEM_Double_2
/*0509*/#endif
/*0510*/ ) {
/*0511*/ if (index < 1) {
/*0512*/ return VE_LOCALS_UNDERFLOW;
/*0513*/ }
/*0514*/ vLocals[index - 1] = ITEM_Bogus;
/*0515*/ }
/*0516*/ if (vLocals[index] == ITEM_Long
/*0517*/#if IMPLEMENTS_FLOAT
/*0518*/ || vLocals[index] == ITEM_Double
/*0519*/#endif
/*0520*/ ) {
/*0521*/ if (index >= (unsigned int)vFrameSize - 1) {
/*0522*/ return VE_LOCALS_OVERFLOW;
/*0523*/ }
/*0524*/ vLocals[index + 1] = ITEM_Bogus;
/*0525*/ }
/*0526*/ vLocals[index] = typeKey;
/*0527*/ return 0;
/*0528*/}
/*0529*/
/*0530*//*=========================================================================
/*0531./ * FUNCTION: getObjectArrayElementKey
/*0532./ * TYPE: private operation on type keys
/*0533./ * OVERVIEW: Obtain the element type key of a given object array type.
/*0534./ *
/*0535./ * INTERFACE:
/*0536./ * parameters: typeKey: object array type key.
/*0537./ * returns: element type key.
/*0538./ *
/*0539./ * DANGER:
/*0540./ * Before calling this function, make sure that typeKey in fact is an
/*0541./ * object array.
/*0542./ *=======================================================================*/
/*0543*/
/*0544*/static unsigned short
/*0545*/getObjectArrayElementKey(unsigned short typeKey)
/*0546*/{
/*0547*/ int n = (typeKey >> FIELD_KEY_ARRAY_SHIFT);
/*0548*/ if (typeKey == ITEM_Null) {
/*0549*/ return ITEM_Null;
/*0550*/ } else if (n < MAX_FIELD_KEY_ARRAY_DEPTH) {
/*0551*/ return ((n - 1) << FIELD_KEY_ARRAY_SHIFT) + (typeKey & 0x1FFF);
/*0552*/ } else {
/*0553*/ CLASS arrayClass = change_Key_to_CLASS(typeKey);
/*0554*/ const char* baseNameString = arrayClass->baseName->string;
/*0555*/ UString baseName =
/*0556*/ getUStringX(&baseNameString, 1, arrayClass->baseName->length - 1);
/*0557*/ UString packageName = arrayClass->packageName;
/*0558*/ CLASS elemClass = change_Name_to_CLASS(packageName, baseName);
/*0559*/ return elemClass->key;
/*0560*/ }
/*0561*/}
/*0562*/
/*0563*//*=========================================================================
/*0564./ * FUNCTION: makeObjectArrayElementKey
/*0565./ * TYPE: private operation on type keys
/*0566./ * OVERVIEW: Obtain the object array type key whose element type is the
/*0567./ * given element type key.
/*0568./ *
/*0569./ * INTERFACE:
/*0570./ * parameters: typeKey: element type key.
/*0571./ * returns: object array type key.
/*0572./ *
/*0573./ * DANGER:
/*0574./ * Before calling this function, make sure that typeKey in fact is an
/*0575./ * object type.
/*0576./ *=======================================================================*/
/*0577*/
/*0578*/static unsigned short
/*0579*/makeObjectArrayClassKey(unsigned short typeKey)
/*0580*/{
/*0581*/ int n = (typeKey >> FIELD_KEY_ARRAY_SHIFT);
/*0582*/ if (n < MAX_FIELD_KEY_ARRAY_DEPTH - 1) {
/*0583*/ return (1 << FIELD_KEY_ARRAY_SHIFT) + typeKey;
/*0584*/ } else {
/*0585*/ CLASS elemClass = change_Key_to_CLASS(typeKey);
/*0586*/ ARRAY_CLASS arrayClass = getObjectArrayClass(elemClass);
/*0587*/ return arrayClass->clazz.key;
/*0588*/ }
/*0589*/}
/*0590*/
/*0591*//*=========================================================================
/*0592./ * FUNCTION: isArrayClassKey
/*0593./ * TYPE: private operation on type keys
/*0594./ * OVERVIEW: Check if the given type key denotes an array type of the
/*0595./ * given dimension.
/*0596./ *
/*0597./ * INTERFACE:
/*0598./ * parameters: typeKey: a type key.
/*0599./ * dim: dimension.
/*0600./ * returns: TRUE if the type key is an array of dim dimension, FALSE
/*0601./ * otherwise.
/*0602./ *=======================================================================*/
/*0603*/
/*0604*/static bool_t
/*0605*/isArrayClassKey(unsigned short typeKey, int dim)
/*0606*/{
/*0607*/ if (typeKey == ITEM_Null) {
/*0608*/ return TRUE;
/*0609*/ } else {
/*0610*/ int n = (typeKey >> FIELD_KEY_ARRAY_SHIFT);
/*0611*/ /* n is the dimension of the class. It has the value
/*0612./ * 0..MAX_FIELD_KEY_ARRAY_DEPTH, in which the last value means
/*0613./ * MAX_FIELD_KEY_ARRAY_DEPTH or more. . .
/*0614./ */
/*0615*/ if (dim <= MAX_FIELD_KEY_ARRAY_DEPTH) {
/*0616*/ return n >= dim;
/*0617*/ } if (n < MAX_FIELD_KEY_ARRAY_DEPTH) {
/*0618*/ /* We are looking for at more than MAX_FIELD_KEY_ARRAY_DEPTH,
/*0619./ * dimensions, so n needs to be that value. */
/*0620*/ return FALSE;
/*0621*/ } else {
/*0622*/ CLASS arrayClass = change_Key_to_CLASS(typeKey);
/*0623*/ char *baseName = arrayClass->baseName->string;
/*0624*/ /* The first dim characters of baseName must be [ */
/*0625*/ for ( ; dim > 0; --dim) {
/*0626*/ if (*baseName++ != '[') {
/*0627*/ return FALSE;
/*0628*/ }
/*0629*/ }
/*0630*/ return TRUE;
/*0631*/ }
/*0632*/ }
/*0633*/}
/*0634*/
/*0635*//*=========================================================================
/*0636./ * FUNCTION: change_Field_to_StackType
/*0637./ * TYPE: private operation on type keys
/*0638./ * OVERVIEW: Change an individual field type to a stack type
/*0639./ *
/*0640./ * INTERFACE:
/*0641./ * parameters: fieldType: field type
/*0642./ * stackTypeP: pointer for placing the corresponding stack type(s)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -