memberfilter.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 443 行

C
443
字号
/* * @(#)MemberFilter.c	1.10 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * *//* * @(#)MemberFilter.c	1.5 03/08/04 * * Native portion of sun.misc.MemberFilter. * Used in support of API Hiding for MIDlet running. * Very CVM-specific implementation. */#include "jni.h"#include "jvm.h"#include "javavm/include/classes.h"#include "javavm/include/directmem.h"#include "javavm/include/interpreter.h"#include "javavm/include/dualstack_impl.h"#include "javavm/include/globals.h"JNIEXPORT jboolean JNICALLJava_sun_misc_MemberFilter_findROMFilterData(JNIEnv* env,                                             jobject thisObject){#ifdef CVM_PRELOAD_LIB    /*     * The CVMdualStackMemberFilter data is derived from a     * fully ROMized bulid. The data contains typeids created     * by the ROMizer. Therefore, it is only safe to use     * CVMdualStackMemberFilter when CVM_PRELOAD_LIB is defined.     * If CVM_PRELOAD_LIB is not define, we need to create     * the member filter by reading in the configuration     * file.     */    if (CVMdualStackMemberFilter.nElements != 0) {        CVMglobals.dualStackMemberFilter = &CVMdualStackMemberFilter;        return JNI_TRUE;    }#endif    return JNI_FALSE;}					     static CVMUint32*parseMemberList(    JNIEnv* env,    jarray members,     int* memberCount,    CVMUint32 (*lookupFn)(CVMExecEnv*, const CVMUtf8*, const CVMUtf8*)){    int nmembers = (members == NULL) ? 0 : (*env)->GetArrayLength(env, members);    int i;    CVMUint32* memberArray;    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    *memberCount = nmembers;    if (nmembers == 0)	return NULL;    memberArray = (CVMUint32*)calloc(nmembers, sizeof(CVMUint32));    for (i=0; i<nmembers; i++){	jstring designator;	jboolean didCopy;	char* membername;	char* membersig;	/* first get the string at array[i] */	designator = (*env)->GetObjectArrayElement(env, members, i);	/* now get the characters from the string */	membername = (char*)((*env)->GetStringUTFChars(env, designator,						       &didCopy));	CVMassert(didCopy); /* hope so because we're going to scribble in it */	/* find : separator. Replace it with '\0' */	membersig = strchr(membername, ':');	CVMassert(membersig != NULL);	*membersig++ = '\0';	/* lookup the pair and save the resulting value */	memberArray[i] = lookupFn(ee, membername, membersig);	/* release the string characters and the string object */	(*env)->ReleaseStringUTFChars(env, designator, membername);	(*env)->DeleteLocalRef(env, designator);    }    return memberArray;}JNIEXPORT void JNICALLJava_sun_misc_MemberFilter_addRestrictions(    JNIEnv* env,    jobject thisObject,    jstring classname,    jarray  fields,    jarray  methods){    int length;    const char* classnameString;    struct linkedClassRestriction* lcrp, *listroot, **nextp;    jclass thisClass;    jfieldID partialDataField;    lcrp = (struct linkedClassRestriction*)calloc(				sizeof(struct linkedClassRestriction), 1);    /* get the typeid of the class */    length = (*env)->GetStringUTFLength(env, classname);    classnameString = (*env)->GetStringUTFChars(env, classname, NULL);    lcrp->thisClass = CVMtypeidNewClassID(CVMjniEnv2ExecEnv(env),					  classnameString, length);    (*env)->ReleaseStringUTFChars(env, classname, classnameString);    /* allocate the arrays of member typeids */    lcrp->fields = parseMemberList(env, fields, &(lcrp->nFields),				   CVMtypeidNewFieldIDFromNameAndSig);    lcrp->methods = parseMemberList(env, methods, &(lcrp->nMethods),				    CVMtypeidNewMethodIDFromNameAndSig);    /* insertion sort in linked list based on thisClass value */    thisClass = (*env)->GetObjectClass(env, thisObject);    partialDataField = (*env)->GetFieldID(env, thisClass, "partialData", "I");    listroot = (struct linkedClassRestriction*)		((*env)->GetIntField(env, thisObject, partialDataField));    nextp = &listroot;    while(CVM_TRUE){	if (*nextp == NULL || (*nextp)->thisClass > lcrp->thisClass){	    lcrp->next = *nextp;	    *nextp = lcrp;	    break;	}	nextp = &((*nextp)->next);    }    (*env)->SetIntField(env, thisObject, partialDataField, (jint)listroot);}JNIEXPORT void JNICALLJava_sun_misc_MemberFilter_doneAddingRestrictions(    JNIEnv* env,    jobject thisObject){    /*     * consolidate linked list into an array for faster access.     * dispose of linked list form.     */    struct linkedClassRestriction* lcrp, *listroot;    struct CVMClassRestrictions* crp;    struct CVMClassRestrictionElement *creep;    jclass thisClass;    jfieldID partialDataField;    int    nentries;    int    i;    thisClass = (*env)->GetObjectClass(env, thisObject);    partialDataField = (*env)->GetFieldID(env, thisClass, "partialData", "I");    listroot = (struct linkedClassRestriction*)		    ((*env)->GetIntField(env, thisObject, partialDataField));    /* count */    for (nentries=0, lcrp=listroot; lcrp!=NULL; lcrp = lcrp->next)	nentries += 1;    /* allocate */    crp = (struct CVMClassRestrictions*)calloc(1,                sizeof(struct CVMClassRestrictions));    creep = (struct CVMClassRestrictionElement*)calloc(1,                nentries*sizeof(struct CVMClassRestrictionElement ));    /* copy */    crp->nElements = nentries;    crp->restriction = creep;    for (i=0, lcrp=listroot; i<nentries; i++, lcrp = lcrp->next){        creep->thisClass = lcrp->thisClass;	creep->nMethods = lcrp->nMethods;	creep->nFields = lcrp->nFields;	creep->methods = lcrp->methods;	creep->fields  = lcrp->fields;        creep++;    }    /* set partialData field to null */    (*env)->SetIntField(env, thisObject, partialDataField, 0);    CVMglobals.dualStackMemberFilter = crp;    /* delete linked list elements */    lcrp = listroot;    while (lcrp != NULL){	listroot = lcrp->next;	free(lcrp);	lcrp = listroot;    }}/* * This is the array-element representation */static CVMClassRestrictionElement*lookupClass(const CVMClassRestrictions* crp, CVMClassTypeID cid){    int i, n;    CVMClassRestrictionElement* ep;    n = crp->nElements;    ep = &(crp->restriction[0]);    /* DEBUG{	char * className = CVMtypeidClassNameToAllocatedCString(cid);	CVMconsolePrintf(">>>> Looking for %s (0x%x) through %d classes", className, cid, n);	free(className);    }     */    for (i=0; i<n; i++, ep++){	if (ep->thisClass == cid){	    /* CVMconsolePrintf(": found at %d\n", i); */	    return ep;	}    }    /* not found */    /* DEBUG: CVMconsolePrintf(": not found\n", i); */    return NULL;}static CVMBoollookupMember(CVMUint32 mid, CVMUint32* memberArray, int nMembers){    int i;    CVMUint32* memberp = memberArray;    for (i=0; i<nMembers; i++, memberp++){	if (mid == *memberp)	    return CVM_TRUE;    }    return CVM_FALSE;}static voidsaveName(    JNIEnv* env,    jobject thisObject,    jclass thisClass,    CVMClassTypeID classID,     CVMUint32 memberID,    CVMBool isMethodType){    char* className;    char* memberName;    char* type;    jfieldID    fieldID;    jstring	stringObj;    className = CVMtypeidClassNameToAllocatedCString(classID);    if (isMethodType){	memberName = CVMtypeidMethodNameToAllocatedCString(memberID);	type = CVMtypeidMethodTypeToAllocatedCString(memberID);    }else{	memberName = CVMtypeidFieldNameToAllocatedCString(memberID);	type = CVMtypeidFieldTypeToAllocatedCString(memberID);    }    stringObj = (*env)->NewStringUTF(env, className);    fieldID = (*env)->GetFieldID(env, thisClass, "badClass",				 "Ljava/lang/String;");    (*env)->SetObjectField(env, thisObject, fieldID, stringObj);    (*env)->DeleteLocalRef(env, stringObj);    stringObj = (*env)->NewStringUTF(env, memberName);    fieldID = (*env)->GetFieldID(env, thisClass, "badMember",				 "Ljava/lang/String;");    (*env)->SetObjectField(env, thisObject, fieldID, stringObj);    (*env)->DeleteLocalRef(env, stringObj);    stringObj = (*env)->NewStringUTF(env, type);    fieldID = (*env)->GetFieldID(env, thisClass, "badSig",				 "Ljava/lang/String;");    (*env)->SetObjectField(env, thisObject, fieldID, stringObj);    (*env)->DeleteLocalRef(env, stringObj);    free(className);    free(memberName);    free(type);}JNIEXPORT jboolean JNICALLJava_sun_misc_MemberFilter_checkMemberAccessValidity0(    JNIEnv* env,    jobject thisObject,    jclass  newclass){    const CVMClassRestrictions* crp;    CVMClassRestrictionElement* creep;    jclass thisClass;    CVMClassBlock* cbp;    jclass classClass;    jfieldID classBlockPointer;    CVMInt32		  cpCount;    CVMInt32		  i, classIndex, typeIndex;    CVMClassTypeID	  classID;    CVMMethodTypeID	  mID;    CVMFieldTypeID	  fID;    CVMConstantPool*	  cp;    /* get pointer to the classes CVMClassBlock */    classClass = (*env)->GetObjectClass(env, newclass); // java.lang.Class    classBlockPointer = (*env)->GetFieldID(env, classClass,				 "classBlockPointer", "I");    cbp = (CVMClassBlock*)((*env)->GetIntField(env, newclass,				 classBlockPointer));    /* get pointer to our list of restrictions */    thisClass = (*env)->GetObjectClass(env, thisObject);    crp = CVMglobals.dualStackMemberFilter;    /* we are now on the inside. Look at the class's constant pool.     * return CVM_FALSE if we see anything we don't like.     */    cpCount = CVMcbConstantPoolCount(cbp);    cp = CVMcbConstantPool(cbp);    for (i=1; i<cpCount; i++){	switch(CVMcpEntryType(cp,i)){	case CVM_CONSTANT_Fieldref:	case CVM_CONSTANT_Methodref:	case CVM_CONSTANT_InterfaceMethodref:	    CVMassert(!CVMcpIsResolved(cp,i));	    classIndex = CVMcpGetMemberRefClassIdx(cp, i);	    typeIndex  = CVMcpGetMemberRefTypeIDIdx(cp, i);	    CVMassert(!CVMcpIsResolved(cp,classIndex));	    classID = CVMcpGetClassTypeID(cp, classIndex);	    creep = lookupClass(crp, classID);	    if (creep==NULL)		continue; /* we don't care about use of class "classID" */	    CVMassert(!CVMcpIsResolved(cp,typeIndex));	    switch(CVMcpEntryType(cp,i)){	    case CVM_CONSTANT_Fieldref:		fID = CVMcpGetFieldTypeID(cp, typeIndex);		if (!lookupMember(                        fID, creep->fields, creep->nFields)){		    /* not on the permitted list */		    saveName(env, thisObject, thisClass, classID, fID,			     CVM_FALSE);                    CVMcpSetIllegalEntryType(cp, i, Fieldref);		}		break;	    default:		mID = CVMcpGetMethodTypeID(cp, typeIndex);		if (!lookupMember(                        mID, creep->methods, creep->nMethods)){		    /* not on the permitted list */		    saveName(env, thisObject, thisClass, classID, mID,			     CVM_TRUE);	            switch(CVMcpEntryType(cp,i)) {		    case CVM_CONSTANT_Methodref:                        CVMcpSetIllegalEntryType(cp, i, Methodref);			break;		    case CVM_CONSTANT_InterfaceMethodref:                        CVMcpSetIllegalEntryType(cp, i, InterfaceMethodref);			break;		    }		}		break;	    }	}    }    /*     * If we found nothing to object to, then we succeed.     */    return CVM_TRUE;}JNIEXPORT void JNICALLJava_sun_misc_MemberFilter_finalize0(    JNIEnv* env,    jobject thisObject){    struct linkedClassRestriction* lcrp, *listroot;    jclass thisClass;    jfieldID partialDataField;    thisClass = (*env)->GetObjectClass(env, thisObject);    partialDataField = (*env)->GetFieldID(env, thisClass, "partialData", "I");    listroot = (struct linkedClassRestriction*)((*env)->GetIntField(env, thisObject, partialDataField));    if (listroot != NULL){	/* This MemberFilter isn't fully formed. Delete	 * the linked-list form.	 */	lcrp = listroot;	while (lcrp != NULL){	    listroot = lcrp->next;	    if (lcrp->methods != NULL)		free(lcrp->methods);	    if (lcrp->fields != NULL)		free(lcrp->fields);	    free(lcrp);	    lcrp = listroot;	}    }    /* set 'partialData' field to 0 */    (*env)->SetIntField(env, thisObject, partialDataField, 0);}/* Check if the super MB exists */CVMBoolCVMdualStackFindSuperMB(CVMExecEnv* ee,                        CVMClassBlock* currentCB,                        CVMClassBlock* superCB,                        CVMMethodBlock* superMB){    CVMBool needCheckFilter;    /* TODO: We should use in the CB to indicate     *       if a class have a filter applied,     *       instead of checking for classloader.     */    CVMD_gcUnsafeExec(ee, {        needCheckFilter = CVMclassloaderIsMIDPClassLoader(            ee, CVMcbClassLoader(currentCB), CVM_FALSE);    });    if (needCheckFilter) {        CVMClassRestrictionElement* cre;        const CVMClassRestrictions* crp;        crp = CVMglobals.dualStackMemberFilter;        cre = lookupClass(crp, CVMcbClassName(superCB));        if (cre != NULL) {            /* Check if the method exists. */	    return lookupMember(CVMmbNameAndTypeID(superMB),                                cre->methods, cre->nMethods);        }    }    return CVM_TRUE;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?