/* Code called from dvmJniStartup()
 * Initializes the gPolicyTable for fast lookup of taint policy 
 * profiles for methods.
 */
void dvmTaintPropJniStartup()
{
    TaintPolicy* policy;
    u4 hash;
    
    /* Create the policy table (perfect size) */
    gPolicyTable = dvmHashTableCreate(
	    dvmHashSize(TAINT_POLICY_TABLE_SIZE), 
	    freeTaintPolicy);

    for (policy = gDvmJniTaintPolicy; policy->classDescriptor != NULL; policy++) {
	const TaintProfile *profile;
    
	/* Create the method table for this class */
	policy->methodTable = dvmHashTableCreate(
		TAINT_PROFILE_TABLE_SIZE, freeTaintProfile);

	/* Add all of the methods */
	for (profile = &policy->profiles[0]; profile->methodName != NULL; profile++) {
	    hash = dvmComputeUtf8Hash(profile->methodName);
	    dvmHashTableLookup(policy->methodTable, hash,(void *) profile,
		    hashcmpTaintProfile, true);
	}

	/* Add this class to gPolicyTable */
	hash = dvmComputeUtf8Hash(policy->classDescriptor);
	dvmHashTableLookup(gPolicyTable, hash, policy, 
		hashcmpTaintPolicy, true);
    }

#ifdef TAINT_JNI_LOG
    /* JNI logging for debugging purposes */
    gJniLogSeen = dvmHashTableCreate(dvmHashSize(50), free);
#endif
}
Example #2
0
/*
 * Some quick hash table tests.
 */
bool dvmTestHash()
{
    HashTable* pTab;
    char tmpStr[64];
    const char* str;
    u4 hash;
    int i;

    ALOGV("TestHash BEGIN");

    pTab = dvmHashTableCreate(dvmHashSize(12), free);
    if (pTab == NULL)
        return false;

    dvmHashTableLock(pTab);

    /* add some entries */
    for (i = 0; i < kNumTestEntries; i++) {
        sprintf(tmpStr, "entry %d", i);
        hash = dvmComputeUtf8Hash(tmpStr);
        dvmHashTableLookup(pTab, hash, strdup(tmpStr),
            (HashCompareFunc) strcmp, true);
    }

    dvmHashTableUnlock(pTab);

    /* make sure we can find all entries */
    for (i = 0; i < kNumTestEntries; i++) {
        sprintf(tmpStr, "entry %d", i);
        hash = dvmComputeUtf8Hash(tmpStr);
        str = (const char*) dvmHashTableLookup(pTab, hash, tmpStr,
                (HashCompareFunc) strcmp, false);
        if (str == NULL) {
            ALOGE("TestHash: failure: could not find '%s'", tmpStr);
            /* return false */
        }
    }

    /* make sure it behaves correctly when entry not found and !doAdd */
    sprintf(tmpStr, "entry %d", 17);
    hash = dvmComputeUtf8Hash(tmpStr);
    str = (const char*) dvmHashTableLookup(pTab, hash, tmpStr,
            (HashCompareFunc) strcmp, false);
    if (str == NULL) {
        /* good */
    } else {
        ALOGE("TestHash found nonexistent string (improper add?)");
    }

    dumpForeach(pTab);
    dumpIterator(pTab);

    /* make sure they all get freed */
    dvmHashTableFree(pTab);


    /*
     * Round 2: verify probing & tombstones.
     */
    pTab = dvmHashTableCreate(dvmHashSize(2), free);
    if (pTab == NULL)
        return false;

    hash = 0;

    /* two entries, same hash, different values */
    const char* str1;
    str1 = (char*) dvmHashTableLookup(pTab, hash, strdup("one"),
            (HashCompareFunc) strcmp, true);
    assert(str1 != NULL);
    str = (const char*) dvmHashTableLookup(pTab, hash, strdup("two"),
            (HashCompareFunc) strcmp, true);

    /* remove the first one */
    if (!dvmHashTableRemove(pTab, hash, (void*)str1))
        ALOGE("TestHash failed to delete item");
    else
        free((void*)str1);     // "Remove" doesn't call the free func

    /* make sure iterator doesn't included deleted entries */
    int count = 0;
    HashIter iter;
    for (dvmHashIterBegin(pTab, &iter); !dvmHashIterDone(&iter);
        dvmHashIterNext(&iter))
    {
        count++;
    }
    if (count != 1) {
        ALOGE("TestHash wrong number of entries (%d)", count);
    }

    /* see if we can find them */
    str = (const char*) dvmHashTableLookup(pTab, hash, (void*)"one",
            (HashCompareFunc) strcmp,false);
    if (str != NULL)
        ALOGE("TestHash deleted entry has returned!");
    str = (const char*) dvmHashTableLookup(pTab, hash, (void*)"two",
            (HashCompareFunc) strcmp,false);
    if (str == NULL)
        ALOGE("TestHash entry vanished");

    /* force a table realloc to exercise tombstone removal */
    for (i = 0; i < 20; i++) {
        sprintf(tmpStr, "entry %d", i);
        str = (const char*) dvmHashTableLookup(pTab, hash, strdup(tmpStr),
                (HashCompareFunc) strcmp, true);
        assert(str != NULL);
    }

    dvmHashTableFree(pTab);
    ALOGV("TestHash END");

    return true;
}