예제 #1
0
static int
call_diff (const char *out)
{
    call_diff_add_arg (NULL);

    if (out == RUN_TTY)
	return diff_run( call_diff_argc, call_diff_argv, NULL,
			 &call_diff_stdout_callbacks );
    else
	return diff_run( call_diff_argc, call_diff_argv, out,
			 &call_diff_file_callbacks );
}
예제 #2
0
int generate_diff(deng_t ** d, slist_t * l1, slist_t * l2, char * file, bool display, options_t * opt)
{
	int ret;
	clist_t * cl1, * cl2;
	int un1, un2, idf, mf;
	deng_t * eng;

	eng = diff_engine_initialize(l1, l2, opt);
	if (eng == NULL)
		return -1;

	cl1 = clist_init(l1);
	cl2 = clist_init(l2);

	if (file)
		ret = diff_run(eng, cl1, cl2, DIFF_EQUAL_NAME, DIFF_NEQUAL_STR, false);
	else
	{
		ret = diff_run(eng, cl1, cl2, DIFF_EQUAL_SIG_HASH_CRC, DIFF_EQUAL_SIG_HASH, false);
		ret = diff_run(eng, cl1, cl2, DIFF_NEQUAL_PRED, DIFF_NEQUAL_STR, false);
	}

	//printf("%s\n",file);
	
	if (display)
	{
		eng->mlist = siglist_init(eng->matched, file);
		eng->ulist = siglist_init(eng->unmatched, file);
		eng->ilist = siglist_init(eng->identical, file);

		un1 = un2 = idf = mf = 0;

		for (size_t i=0; i<l1->num; i++)
		{
			if (sig_is_class(l1->sigs[i]))
			{
				sig_free(l1->sigs[i]);
				continue;
			}

			if (sig_get_matched_type(l1->sigs[i]) == DIFF_UNMATCHED)
			{
				sig_set_nfile(l1->sigs[i], 1);
				siglist_add(eng->ulist, l1->sigs[i]);
				un1++;
			}
			else
			{
				
				// was || should be && ?
				
				if (l1->sigs[i]->hash2 == l1->sigs[i]->msig->hash2 && sig_equal(l1->sigs[i], l1->sigs[i]->msig, DIFF_EQUAL_SIG_HASH))
				{
					siglist_add(eng->ilist, l1->sigs[i]);
					idf++;
				}
				else
				{
					siglist_add(eng->mlist, l1->sigs[i]);
					mf++;
				}
			}
		}

		for (size_t i=0; i<l2->num; i++)
		{
			if (sig_is_class(l2->sigs[i]))
			{
				sig_free(l2->sigs[i]);
				continue;
			}

			if (sig_get_matched_type(l2->sigs[i]) == DIFF_UNMATCHED)
			{
				sig_set_nfile(l2->sigs[i], 2);
				siglist_add(eng->ulist, l2->sigs[i]);
				un2++;
			}
		}


		msg("Identical functions:   %d\n", idf);
		msg("Matched functions:     %d\n", mf);
		msg("Unmatched functions 1: %d\n", un1);
		msg("Unmatched functions 2: %d\n", un2);
		display_results(eng);
	}

	if (d)
		*d = eng;

	return 0;
}
예제 #3
0
int diff_run(deng_t * eng, clist_t * cl1, clist_t * cl2, int min_type, int max_type, bool pclass)
{
	dpsig_t * dsig, * dsig2;
	int changed = 0;
	int type = min_type;
	int mtype = max_type;
	bool b;

	if (pclass && max_type > DIFF_EQUAL_SIG_HASH)
		mtype = DIFF_EQUAL_SIG_HASH;

	do
	{
		clist_reset(cl1);
		clist_reset(cl2);

		changed = 0;
		while (	(dsig = clist_get_best_sig(cl1, type)) != NULL)
		{
			clist_reset(cl2);
			dsig2 = clist_get_eq_sig(cl2, dsig, type);
			if (dsig2)
			{	
				sig_set_matched_sig(dsig->sig, dsig2->sig, type);

				eng->unmatched -= 2;
							
				/*
				
				 struct signature
				 {
					(...)
					unsigned long sig;
					unsigned long hash;
					unsigned long hash2;
					unsigned long crc_hash;
					unsigned long str_hash;
					unsigned long lines;
					(...)
				 };
				 
				*/
				
				/*
				 Debug:
				 
				 if(dsig->sig->hash2 != dsig2->sig->hash2) {
					
					printf("SIG:   %lu : %lu\n",dsig->sig->sig,dsig2->sig->sig);
					printf("HASH:  %lu : %lu\n",dsig->sig->hash,dsig2->sig->hash);
					printf("HASH2: %lu : %lu\n",dsig->sig->hash2,dsig2->sig->hash2);
					printf("CRC:   %lu : %lu\n",dsig->sig->crc_hash,dsig2->sig->crc_hash);
				
				}*/
				
				// was OR, should be AND ?
				
				if (sig_equal(dsig->sig, dsig2->sig, DIFF_EQUAL_SIG_HASH) && (dsig->sig->hash2 == dsig2->sig->hash2))
				{
					eng->identical++;
				} else {
					eng->matched++;
				}
								
				changed = 1;

				clist_update_and_remove(cl1, dsig);
				clist_update_and_remove(cl2, dsig2);

				b = sig_is_class(dsig->sig);

				// string matching is not 100% reliable so we only match on crc/hash
				if (mtype == DIFF_NEQUAL_STR)
					b = true;

				diff_run(eng, sig_get_crefs(dsig->sig, SIG_PRED), sig_get_crefs(dsig2->sig, SIG_PRED), min_type, max_type, b);
				diff_run(eng, sig_get_crefs(dsig->sig, SIG_SUCC), sig_get_crefs(dsig2->sig, SIG_SUCC), min_type, max_type, b);

			}
		}

		if (changed == 0)
			type++;
	} while(type <= mtype);

	return 0;
}