unit_tests/check_jsnorm.c
4a6ade44
 #if HAVE_CONFIG_H
 #include "clamav-config.h"
 #endif
 
 #include <stdio.h>
 #ifdef HAVE_CHECK
 
 #include <stdlib.h>
 #include <limits.h>
 #include <string.h>
 #include <check.h>
 #include "../libclamav/clamav.h"
 #include "../libclamav/others.h"
5be3029f
 #include "../libclamav/dconf.h"
 #include "../libclamav/htmlnorm.h"
4a6ade44
 #include "../libclamav/jsparse/js-norm.h"
 #include "../libclamav/jsparse/lexglobal.h"
 #include "../libclamav/jsparse/textbuf.h"
 #include "../libclamav/jsparse/generated/keywords.h"
 #include "../libclamav/jsparse/generated/operators.h"
a39b29cb
 #include "checks.h"
4a6ade44
 
 struct test {
 	const char *str;
 	int is;
 };
 
 static struct test kw_test[] = {
 	{"new",1},
 	{"eval",0},
 	{"function",1},
 	{"eval1",0},
 	{"ne",0}
 };
 
 static struct test op_test[] = {
 	{"-",1},
 	{"---",0}
 };
 
 START_TEST (test_keywords)
 {
     const struct keyword *kw = in_word_set(kw_test[_i].str, strlen(kw_test[_i].str));
     if(kw_test[_i].is) {
 	    fail_unless(kw && !strcmp(kw->name, kw_test[_i].str), "keyword mismatch");
     } else {
 	    fail_unless(!kw, "non-keyword detected as keyword");
     }
 }
 END_TEST
 
 START_TEST (test_operators)
 {
     const struct operator *op = in_op_set(op_test[_i].str, strlen(op_test[_i].str));
     if(op_test[_i].is)
 	    fail_unless(op && !strcmp(op->name, op_test[_i].str), "operator mismatch");
     else
 	    fail_unless(!op, "non-operator detected as operator");
 }
 END_TEST
 
 START_TEST (test_token_string)
 {
 	char str[] = "test";
 	yystype tok;
 	memset(&tok, 0, sizeof(tok));
 
 	TOKEN_SET(&tok, string, str);
 	fail_unless(TOKEN_GET(&tok, string) == str, "token string get/set");
 	fail_unless(TOKEN_GET(&tok, cstring) == str, "token string->cstring");
 	fail_unless(TOKEN_GET(&tok, scope) == NULL, "token string->scope");
 	fail_unless(TOKEN_GET(&tok, ival) == -1, "token string->ival");
 }
 END_TEST
 
 START_TEST (test_token_cstring)
 {
 	const char *str = "test";
 	yystype tok;
 	memset(&tok, 0, sizeof(tok));
 
 	TOKEN_SET(&tok, cstring, str);
 	fail_unless(TOKEN_GET(&tok, string) == NULL, "token cstring->string");
 	fail_unless(TOKEN_GET(&tok, cstring) == str, "token string->cstring");
 	fail_unless(TOKEN_GET(&tok, scope) == NULL, "token string->scope");
 	fail_unless(TOKEN_GET(&tok, ival) == -1, "token string->ival");
 }
 END_TEST
 
 START_TEST (test_token_scope)
 {
 	struct scope *sc = (struct scope*)0xdeadbeef;
 	yystype tok;
 	memset(&tok, 0, sizeof(tok));
 
 	TOKEN_SET(&tok, scope, sc);
 	fail_unless(TOKEN_GET(&tok, string) == NULL, "token scope->string");
 	fail_unless(TOKEN_GET(&tok, cstring) == NULL, "token scope->cstring");
 	fail_unless(TOKEN_GET(&tok, scope) == sc, "token scope->scope");
 	fail_unless(TOKEN_GET(&tok, ival) == -1, "token scope->ival");
 }
 END_TEST
 
 START_TEST (test_token_ival)
 {
 	int val = 0x1234567;
 	yystype tok;
 	memset(&tok, 0, sizeof(tok));
 
 	TOKEN_SET(&tok, ival, val);
 	fail_unless(TOKEN_GET(&tok, string) == NULL, "token ival->string");
 	fail_unless(TOKEN_GET(&tok, cstring) == NULL, "token ival->cstring");
 	fail_unless(TOKEN_GET(&tok, scope) == NULL, "token ival->scope");
 	fail_unless(TOKEN_GET(&tok, dval) == -1, "token ival->dval");
 	fail_unless(TOKEN_GET(&tok, ival) == val, "token ival->ival");
 }
 END_TEST
 
 START_TEST (test_token_dval)
 {
 	int val = 0.12345;
 	yystype tok;
 	memset(&tok, 0, sizeof(tok));
 
 	TOKEN_SET(&tok, dval, val);
 	fail_unless(TOKEN_GET(&tok, string) == NULL, "token dval->string");
 	fail_unless(TOKEN_GET(&tok, cstring) == NULL, "token dval->cstring");
 	fail_unless(TOKEN_GET(&tok, scope) == NULL, "token dval->scope");
 	fail_unless(TOKEN_GET(&tok, dval) == val, "token dval->dval");
 	fail_unless(TOKEN_GET(&tok, ival) == -1, "token dval->ival");
 }
 END_TEST
 
 START_TEST (test_init_destroy)
 {
 	struct parser_state *state = cli_js_init();
 	fail_unless(!!state, "cli_js_init()");
 	cli_js_destroy(state);
 }
 END_TEST
 
 START_TEST (test_init_parse_destroy)
 {
 	const char buf[] = "function (p) { return \"anonymous\";}";
 	struct parser_state *state = cli_js_init();
 	fail_unless(!!state, "cli_js_init()");
 	cli_js_process_buffer(state, buf, strlen(buf));
 	cli_js_process_buffer(state, buf, strlen(buf));
 	cli_js_parse_done(state);
 	cli_js_destroy(state);
 }
 END_TEST
 
5be3029f
 START_TEST (js_begin_end)
 {
 	char buf[16384] = "</script>";
 	size_t p;
 	struct cli_dconf *dconf = cli_dconf_init();
 
 	fail_unless(!!dconf, "failed to init dconf");
 	for(p=strlen(buf); p < 8191; p++) {
 		buf[p++] = 'a';
 		buf[p] = ' ';
 	}
 	strncpy(buf + 8192, " stuff stuff <script language='javascript'> function () {}", 8192);
 	fail_unless(html_normalise_mem(buf, sizeof(buf), NULL, NULL, dconf) == 1, "normalise");
 }
 END_TEST
 
 START_TEST (multiple_scripts)
 {
 	const char buf[] = "</script> stuff"\
 			    "<script language='Javascript'> function foo() {} </script>"\
 			    "<script language='Javascript'> function bar() {} </script>";
 	m_area_t m_area;
 	size_t p;
 	struct cli_dconf *dconf = cli_dconf_init();
 
 	fail_unless(!!dconf, "failed to init dconf");
 	fail_unless(html_normalise_mem(buf, sizeof(buf), NULL, NULL, dconf) == 1, "normalise");
 	/* TODO: test that both had been normalized */
 }
 END_TEST
 
4a6ade44
 Suite *test_jsnorm_suite(void)
 {
     Suite *s = suite_create("jsnorm");
5be3029f
     TCase *tc_jsnorm_gperf, *tc_jsnorm_token, *tc_jsnorm_api, *tc_jsnorm_tokenizer, *tc_jsnorm_bugs;
4a6ade44
     tc_jsnorm_gperf = tcase_create("jsnorm gperf");
     suite_add_tcase (s, tc_jsnorm_gperf);
     tcase_add_loop_test(tc_jsnorm_gperf, test_keywords, 0, sizeof(kw_test)/sizeof(kw_test[0]));
     tcase_add_loop_test(tc_jsnorm_gperf, test_operators, 0, sizeof(op_test)/sizeof(op_test[0]));
 
     tc_jsnorm_token = tcase_create("jsnorm token functions");
37e64729
     suite_add_tcase (s, tc_jsnorm_token);
4a6ade44
     tcase_add_test(tc_jsnorm_token, test_token_string);
     tcase_add_test(tc_jsnorm_token, test_token_cstring);
     tcase_add_test(tc_jsnorm_token, test_token_scope);
     tcase_add_test(tc_jsnorm_token, test_token_ival);
     tcase_add_test(tc_jsnorm_token, test_token_dval);
 
     tc_jsnorm_api = tcase_create("jsnorm api functions");
37e64729
     suite_add_tcase (s, tc_jsnorm_api);
4a6ade44
     tcase_add_test(tc_jsnorm_api, test_init_destroy);
     tcase_add_test(tc_jsnorm_api, test_init_parse_destroy);
 
5be3029f
     tc_jsnorm_tokenizer = tcase_create("jsnorm tokenizer");
     suite_add_tcase (s, tc_jsnorm_tokenizer);
 
     tc_jsnorm_bugs = tcase_create("jsnorm bugs");
     suite_add_tcase (s, tc_jsnorm_bugs);
     tcase_add_test(tc_jsnorm_bugs, js_begin_end);
     tcase_add_test(tc_jsnorm_bugs, multiple_scripts);
 
4a6ade44
     return s;
 }
 
 #endif