示例#1
0
static void decode_de(yystype *params[], struct text_buffer *txtbuf)
{
	const char *p = TOKEN_GET(params[0], cstring);
	const long a = TOKEN_GET(params[1], ival);
	/*const char *c = params[2];*/
	char *k = TOKEN_GET(params[3], string);
	/*const char *r = params[5];*/

	unsigned val=0;
	unsigned nsplit = 0;
	const char* o;
	const char **tokens;

	memset(txtbuf, 0, sizeof(*txtbuf));
	if(!p || !k )
		return;
	for(o = k; *o; o++) if(*o == '|') nsplit++;
	nsplit++;
	tokens = malloc(sizeof(char*)*nsplit);
	if(!tokens) {
		return;
	}
	cli_strtokenize(k,'|',nsplit, tokens);

	do {
		while(*p && !isalnum(*p)) {
			if(*p=='\\' && (p[1] == '\'' || p[1] == '\"'))
				p++;
			else
				textbuffer_putc(txtbuf, *p++);
		}
		if(!*p) break;
		val = 0;
		o = p;
		while(*p && isalnum(*p)) {
			unsigned x;
			unsigned char v = *p++;
			/* TODO: use a table here */
			if(v >= 'a') x = 10+v-'a';
			else if(v >= 'A') x = 36+v-'A';
			else x = v-'0';
			val = val*a+x;
		}
		if(val >= nsplit || !tokens[val] || !tokens[val][0])
			while(o!=p)
				textbuffer_putc(txtbuf, *o++);
		else	textbuffer_append(txtbuf, tokens[val]);
	} while (*p);
	free(tokens);
	textbuffer_append(txtbuf, "\0");
}
示例#2
0
/* return class of last character */
static char output_token(const yystype *token, struct scope *scope, struct buf *out, char lastchar)
{
	char sbuf[128];
	const char *s = TOKEN_GET(token, cstring);
	/* TODO: use a local buffer, instead of FILE* */
	switch(token->type) {
		case TOK_StringLiteral:
			output_space(lastchar,'"', out);
			buf_outc('"', out);
			if(s) {
				buf_outs(s, out);
			}
			buf_outc('"', out);
			return '\"';
		case TOK_NumericInt:
			output_space(lastchar,'0', out);
			snprintf(sbuf, sizeof(sbuf), "%ld", TOKEN_GET(token, ival));
			buf_outs(sbuf, out);
			return '0';
		case TOK_NumericFloat:
			output_space(lastchar,'0', out);
			snprintf(sbuf, sizeof(sbuf), "%g", TOKEN_GET(token, dval));
			buf_outs(sbuf, out);
			return '0';
		case TOK_IDENTIFIER_NAME:
			output_space(lastchar,'a', out);
			if(s) {
				long id = scope_lookup(scope, s, strlen(s));
				if(id == -1) {
					/* identifier not normalized */
					buf_outs(s, out);
				} else {
					snprintf(sbuf, sizeof(sbuf), "n%03ld",id);
					buf_outs(sbuf, out);
				}
			}
			return 'a';
		case TOK_FUNCTION:
			output_space(lastchar,'a', out);
			buf_outs("function",out);
			return 'a';
		default:
			if(s) {
				const size_t len = strlen(s);
				output_space(lastchar,s[0], out);
				buf_outs(s, out);
				return len ? s[len-1] : '\0';
			}
			return '\0';
	}
}
示例#3
0
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");
}
示例#4
0
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");
}
示例#5
0
END_TEST
#endif /* CHECK_HAVE_LOOPS */

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");
}
示例#6
0
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 < 1e-9, "token dval->dval");
    fail_unless(TOKEN_GET(&tok, ival) == -1, "token dval->ival");
}
示例#7
0
/* scriptasylum dot com's JS encoder */
static void handle_df(const yystype *tokens, size_t start, struct decode_result *res)
{
	char *str, *s1;
	size_t len, s1_len, i;
	unsigned char clast;
	char *R;

	if(tokens[start].type != TOK_StringLiteral)
		return;
	str = TOKEN_GET(&tokens[start], string);
	if(!str)
		return;
	len = strlen(str);
	if(!len)
		return;
	clast = str[len-1] - '0';

	str[len-1] = '\0';
	s1 = cli_unescape(str);
	s1_len = strlen(s1);
	for(i=0;i<s1_len;i++) {
		s1[i] -= clast;
	}
	R = cli_unescape(s1);
	free(s1);
	res->pos_begin = start-2;
	res->pos_end = start+2;
	res->txtbuf.data = R;
	res->txtbuf.pos = strlen(R);
	res->append = 1;
}
示例#8
0
static void handle_eval(struct tokens *tokens, size_t start, struct decode_result *res)
{
	res->txtbuf.data = TOKEN_GET(&tokens->data[start], string);
	if(res->txtbuf.data && tokens->data[start+1].type == TOK_PAR_CLOSE) {
		TOKEN_SET(&tokens->data[start], string, NULL);
		res->txtbuf.pos = strlen(res->txtbuf.data);
		res->pos_begin = start-2;
		res->pos_end = start+2;
	}
}
示例#9
0
static void run_folders(struct tokens *tokens)
{
  size_t i;

  for(i = 0; i < tokens->cnt; i++) {
	  const char *cstring = TOKEN_GET(&tokens->data[i], cstring);
	  if(i+2 < tokens->cnt && tokens->data[i].type == TOK_IDENTIFIER_NAME &&
		    cstring &&
		    !strcmp("unescape", cstring) && tokens->data[i+1].type == TOK_PAR_OPEN) {

		  handle_unescape(tokens, i+2);
	  }
  }
}
示例#10
0
static inline int state_update_scope(struct parser_state *state, const yystype *token)
{
	if(token->type == TOK_FUNCTION) {
		struct scope *scope = TOKEN_GET(token, scope);
		if(scope) {
			state->current = scope;
		}
		else {
			/* dummy token marking function end */
			if(state->current->parent)
				state->current = state->current->parent;
			/* don't output this token, it is just a dummy marker */
			return 0;
		}
	}
	return 1;
}
示例#11
0
static int handle_unescape(struct tokens *tokens, size_t start)
{
	if(tokens->data[start].type == TOK_StringLiteral) {
		char *R;
		struct tokens new_tokens;
		yystype tok;

		R = cli_unescape(TOKEN_GET(&tokens->data[start], cstring));
		tok.type = TOK_StringLiteral;
		TOKEN_SET(&tok, string, R);
		new_tokens.capacity = new_tokens.cnt = 1;
		new_tokens.data = &tok;
		if(replace_token_range(tokens, start-2, start+2, &new_tokens) < 0)
			return CL_EMEM;
	}
	return CL_SUCCESS;
}
示例#12
0
static int match_parameters(const yystype *tokens, const char ** param_names, size_t count)
{
	size_t i,j=0;
	if(tokens[0].type != TOK_PAR_OPEN)
		return -1;
	i=1;
	while(count--) {
		const char *token_val = TOKEN_GET(&tokens[i], cstring);
		if(tokens[i].type != TOK_IDENTIFIER_NAME ||
		   !token_val ||
		   strcmp(token_val, param_names[j++]))
			return -1;
		++i;
		if((count && tokens[i].type != TOK_COMMA)
		   || (!count && tokens[i].type != TOK_PAR_CLOSE))
			return -1;
		++i;
	}
	return 0;
}
示例#13
0
/* buffer is html-normlike "chunk", if original file is bigger than buffer,
 * we rewind to a space, so we'll know that tokens won't be broken in half at
 * the end of a buffer. All tokens except string-literals of course.
 * So we can assume that after the buffer there is either a space, EOF, or a
 * chunk of text not containing whitespace at all (for which we care only if its
 * a stringliteral)*/
void cli_js_process_buffer(struct parser_state *state, const char *buf, size_t n)
{
	struct scope* current = state->current;
	YYSTYPE val;
	int yv;
	YY_BUFFER_STATE yyb;

	if(!state->global) {
		/* this state has either not been initialized,
		 * or cli_js_parse_done() was already called on it */
		cli_warnmsg(MODULE "invalid state\n");
		return;
	}
	yyb = yy_scan_bytes(buf, n, state->scanner);
	memset(&val, 0, sizeof(val));
	val.vtype = vtype_undefined;
	/* on EOF yylex will return 0 */
	while( (yv=yylex(&val, state->scanner)) != 0)
	{
		const char *text;
		size_t leng;

		val.type = yv;
		switch(yv) {
			case TOK_VAR:
				current->fsm_state = InsideVar;
				break;
			case TOK_IDENTIFIER_NAME:
				text = yyget_text(state->scanner);
				leng = yyget_leng(state->scanner);
				if(current->last_token == TOK_DOT) {
					/* this is a member name, don't normalize
					*/
					TOKEN_SET(&val, string, cli_strdup(text));
					val.type = TOK_UNNORM_IDENTIFIER;
				} else {
					switch(current->fsm_state) {
						case WaitParameterList:
							state->syntax_errors++;
							/* fall through */
						case Base:
						case InsideInitializer:
							TOKEN_SET(&val, cstring, scope_use(current, text, leng));
							break;
						case InsideVar:
						case InsideFunctionDecl:
							TOKEN_SET(&val, cstring, scope_declare(current, text, leng, state));
							current->fsm_state = InsideInitializer;
							current->brackets = 0;
							break;
						case WaitFunctionName:
							TOKEN_SET(&val, cstring, scope_declare(current, text, leng, state));
							current->fsm_state = WaitParameterList;
							break;
					}
				}
				break;
			case TOK_PAR_OPEN:
				switch(current->fsm_state) {
					case WaitFunctionName:
						/* fallthrough */
					case WaitParameterList:
						current->fsm_state = InsideFunctionDecl;
						break;
					default:
						/* noop */
						break;
				}
				break;
			case TOK_PAR_CLOSE:
				switch(current->fsm_state) {
					case WaitFunctionName:
						state->syntax_errors++;
						break;
					case WaitParameterList:
						current->fsm_state = Base;
						break;
					default:
						/* noop */
						break;
				}
				break;
			case TOK_CURLY_BRACE_OPEN:
				switch(current->fsm_state) {
					case WaitFunctionName:
						/* fallthrough */
					case WaitParameterList:
					case InsideFunctionDecl:
						/* in a syntactically correct
						 * file, we would already be in
						 * the Base state when we see a {
						 */
						current->fsm_state = Base;
						/* fall-through */
					case InsideVar:
					case InsideInitializer:
						state->syntax_errors++;
						/* fall-through */
					case Base:
					default:
						current->blocks++;
						break;
				}
				break;
					case TOK_CURLY_BRACE_CLOSE:
				if(current->blocks > 0)
					current->blocks--;
				else
					state->syntax_errors++;
				if(!current->blocks) {
					if(current->parent) {
						/* add dummy FUNCTION token to
						 * mark function end */
						TOKEN_SET(&val, cstring, "}");
						add_token(state, &val);
						TOKEN_SET(&val, scope, NULL);
						val.type = TOK_FUNCTION;

						state->current = current = current->parent;
					} else{
						/* extra } */
						state->syntax_errors++;
				}
				}
				break;
			case TOK_BRACKET_OPEN:
				current->brackets++;
				break;
			case TOK_BRACKET_CLOSE:
				if(current->brackets > 0)
					current->brackets--;
				else
					state->syntax_errors++;
				break;
			case TOK_COMMA:
				if (current->fsm_state == InsideInitializer && current->brackets == 0 && current->blocks == 0) {
					/* initializer ended only if we
					 * encountered a comma, and [] are
					 * balanced.
					 * This avoids switching state on:
					 * var x = [4,y,u];*/
					current->fsm_state = InsideVar;
				}
				break;
			case TOK_SEMICOLON:
				if (current->brackets == 0 && current->blocks == 0) {
					/* avoid switching state on unbalanced []:
					 * var x = [test;testi]; */
					current->fsm_state = Base;
				}
				break;
			case TOK_FUNCTION:
				current = scope_new(state);
				current->fsm_state = WaitFunctionName;
				TOKEN_SET(&val, scope, state->current);
				break;
			case TOK_StringLiteral:
				if(state->tokens.cnt > 1 && state->tokens.data[state->tokens.cnt-1].type == TOK_PLUS) {
					/* see if can fold */
					yystype *prev_string = &state->tokens.data[state->tokens.cnt-2];
					if(prev_string->type == TOK_StringLiteral) {
						char *str = TOKEN_GET(prev_string, string);
						size_t str_len = strlen(str);

						text = yyget_text(state->scanner);
						leng = yyget_leng(state->scanner);


						/* delete TOK_PLUS */
						free_token(&state->tokens.data[--state->tokens.cnt]);

						str = cli_realloc(str, str_len + leng + 1);
						if (!str)
						    break;
						strncpy(str+str_len, text, leng);
						str[str_len + leng] = '\0';
						TOKEN_SET(prev_string, string, str);
						free(val.val.string);
						memset(&val, 0, sizeof(val));
						val.vtype = vtype_undefined;
						continue;
					}
				}
				break;
		}
		if(val.vtype == vtype_undefined) {
			text = yyget_text(state->scanner);
			TOKEN_SET(&val, string, cli_strdup(text));
			abort();
		}
		add_token(state, &val);
		current->last_token = yv;
		memset(&val, 0, sizeof(val));
		val.vtype = vtype_undefined;
	}
}
示例#14
0
static void run_decoders(struct parser_state *state)
{
  size_t i;
  const char* name;
  struct tokens *tokens = &state->tokens;

  for(i = 0; i < tokens->cnt; i++) {
	  const char *cstring = TOKEN_GET(&tokens->data[i], cstring);
	  struct decode_result res;
	  res.pos_begin = res.pos_end = 0;
	  res.append = 0;
	  if(tokens->data[i].type == TOK_FUNCTION && i+13 < tokens->cnt) {
		  name = NULL;
		  ++i;
		  if(tokens->data[i].type == TOK_IDENTIFIER_NAME) {
			  cstring = TOKEN_GET(&tokens->data[i], cstring);
			  name = cstring;
			  ++i;
		  }
		  if(match_parameters(&tokens->data[i], de_packer_3, sizeof(de_packer_3)/sizeof(de_packer_3[0])) != -1
		     || match_parameters(&tokens->data[i], de_packer_2, sizeof(de_packer_2)/sizeof(de_packer_2[0])) != -1)  {
			  /* find function decl. end */
			  handle_de(tokens->data, i, tokens->cnt, name, &res);
		  }
	  } else if(i+2 < tokens->cnt && tokens->data[i].type == TOK_IDENTIFIER_NAME &&
		    cstring &&
		    !strcmp("dF", cstring) && tokens->data[i+1].type == TOK_PAR_OPEN) {
		  /* TODO: also match signature of dF function (possibly
		   * declared using unescape */

		  handle_df(tokens->data, i+2, &res);
	  } else if(i+2 < tokens->cnt && tokens->data[i].type == TOK_IDENTIFIER_NAME &&
			  cstring &&
			  !strcmp("eval", cstring) && tokens->data[i+1].type == TOK_PAR_OPEN) {
		  handle_eval(tokens, i+2, &res);
	  }
	if(res.pos_end > res.pos_begin) {
		struct tokens parent_tokens;
		if(res.pos_end < tokens->cnt && tokens->data[res.pos_end].type == TOK_SEMICOLON)
			res.pos_end++;
		parent_tokens = state->tokens;/* save current tokens */
		/* initialize embedded context */
		memset(&state->tokens, 0, sizeof(state->tokens));
		if(++state->rec > 16)
			cli_dbgmsg(MODULE "recursion limit reached\n");
		else {
			cli_js_process_buffer(state, res.txtbuf.data, res.txtbuf.pos);
			--state->rec;
		}
		free(res.txtbuf.data);
		/* state->tokens still refers to the embedded/nested context
		 * here */
		if(!res.append) {
			replace_token_range(&parent_tokens, res.pos_begin, res.pos_end, &state->tokens);
		} else {
			/* delete tokens */
			replace_token_range(&parent_tokens, res.pos_begin, res.pos_end, NULL);
			append_tokens(&parent_tokens, &state->tokens);
		}
		/* end of embedded context, restore tokens state */
		free(state->tokens.data);
		state->tokens = parent_tokens;
	}
	  state_update_scope(state, &state->tokens.data[i]);
  }
}
示例#15
0
static void handle_de(yystype *tokens, size_t start, const size_t cnt, const char *name, struct decode_result *res)
{
	/* find function decl. end */
	size_t i, nesting = 1, j;
	yystype* parameters [6];
	const size_t parameters_cnt = 6;

	for(i=start;i < cnt; i++) {
		if(tokens[i].type == TOK_FUNCTION) {
			if(TOKEN_GET(&tokens[i], scope))
				nesting++;
			else
				nesting--;
			if(!nesting)
				break;
		}
	}
	if(nesting)
		return;
	memset(parameters, 0, sizeof(parameters));
	if(name) {
		/* find call to function */
		for(;i+2 < cnt; i++) {
			const char* token_val = TOKEN_GET(&tokens[i], cstring);
			if(tokens[i].type == TOK_IDENTIFIER_NAME &&
			   token_val &&
			   !strcmp(name, token_val) &&
			   tokens[i+1].type == TOK_PAR_OPEN) {

				i += 2;
				for(j = 0;j < parameters_cnt && i < cnt;j++) {
					parameters[j] = &tokens[i++];
					if(j != parameters_cnt-1)
						while (tokens[i].type != TOK_COMMA && i < cnt) i++;
					else
						while (tokens[i].type != TOK_PAR_CLOSE && i < cnt) i++;
					i++;
				}
				if(j == parameters_cnt)
					decode_de(parameters, &res->txtbuf);
			}
		}
	} else {
		while(i<cnt && tokens[i].type != TOK_PAR_OPEN) i++;
		++i;
		if(i >= cnt) return;
		/* TODO: move this v to another func */
				for(j = 0;j < parameters_cnt && i < cnt;j++) {
					parameters[j] = &tokens[i++];
					if(j != parameters_cnt-1)
						while (tokens[i].type != TOK_COMMA && i < cnt) i++;
					else
						while (tokens[i].type != TOK_PAR_CLOSE && i < cnt) i++;
					i++;
				}
				if(j == parameters_cnt)
					decode_de(parameters, &res->txtbuf);
	}
	if(parameters[0] && parameters[parameters_cnt-1]) {
		res->pos_begin = parameters[0] - tokens;
		res->pos_end = parameters[parameters_cnt-1] - tokens + 1;
		if(tokens[res->pos_end].type == TOK_BRACKET_OPEN &&
				tokens[res->pos_end+1].type == TOK_BRACKET_CLOSE &&
				tokens[res->pos_end+2].type == TOK_PAR_CLOSE)
			res->pos_end += 3; /* {}) */
		else
			res->pos_end++; /* ) */
	}
}
示例#16
0
文件: esil.c 项目: djpohly/radare2
static int emulate (RAnalEsil *c, char *buf, int *tkns) {
	ut64 num = 0;
	char *op = NULL;
	char *str;
	int i, type;
	c->opstack = r_list_new ();
	c->stack = r_list_new ();
	c->opsize = 0;
	c->rightside = 0;
	for (i=0; tkns[i]; i+=2) {
		TOKEN_GET (type, str);
		eprintf ("(%d) (%s)\n", type, str);

		switch (type) {
		// case 0 handled in for conditional
		case 1: /* special command */
			if (!strcmp (str, "[")) {
				int curstack = r_list_length (c->stack);
eprintf ("STACK POINTER %d\n", curstack);
				c->opsize = (int)num;
				// TODO: test for size
				// read tokens until ']'
				// TOKEN_UNTIL (1, "]");
				for (i+=2; tkns[i]; i+=2) {
					TOKEN_GET (type, str);
					eprintf ("--- %d (%s)\n", tkns[i], buf+tkns[i+1]);
					switch (tkns[i]) {
					case 1:
						if (!strcmp (str, "]")) {
							if (!c->opsize) c->opsize = 
								c->anal->bits==64?8:4;
							//int j, len = r_list_length (c->stack) - curstack;
							char *a;
							OPUSH (op);
							while ((a = OPOP ())) {
								// eprintf ("---> op %s\n", op);
								esil_commit (c, a);
							}
							//op = NULL;
							printf ("   %s (size %d)\n", c->rightside?"GET":"SET", (int)num);
							goto dungeon;
							// set destination for write
							// expect '='
						}
						break;
					case 2:
						op = str;
						OPUSH (op);
						break;
					case 3:
						PUSH (str);
						break;
					}
				}
				if (!tkns[i]) {
					printf ("Unexpected eof\n");
					return 1;
				}
			} else
			if (!strcmp (str, "?")) {
				printf ("   CONDITIONAL\n");
				i += 2;
				TOKEN_GET (type, str);
				if (!type) {
					eprintf ("   UNEXPECTED EOF\n");
					return 1;
				}
				if (type!=3) {
					printf ("   UNEXPECTED TOKEN\n");
					return 1;
				}
				//while () { i += 2; }
			}
			break;
		case 2:
			if (op) {
				//eprintf (" XXX Redefine op %s\n", op);
				if (!strcmp (op, "*")) { // prio
					esil_commit (c, op);
				} else OPUSH (op);
			}
			op = str;
			if (IS ("=")) {
				c->rightside = 1;
			}
			break;
		case 3:
			num = c->num (c, str); // 
	//		eprintf ("; push %s\n" , str);
			PUSH (str);
			break;
		case 4:
			esil_commit (c, op);
			op = NULL;
			break;
		case 5:
// newcontext();
			//esil_push_scope (c);
			eprintf ("OPEN SCOPE\n");
			break;
		case 6:
			{
			//char *res = esil_pop_scope (c);
			// if scope > 0 : 
			//PUSH (res);
			esil_commit (c, op);
			// free (res);
			// commit()
			// closecontext()
			// push result
			eprintf ("CLOSE SCOPE\n");
			}
			break;
		}
		dungeon:
		{/*trick*/int/*label*/x/*parsing*/=/*fix*/0;}
	}
	eprintf (";;; COMMIT (%s) (%s)\n", op, str);
	esil_commit (c, op);
	if (r_list_length (c->opstack)>0) {
		char *a;
		while ((a = OPOP ())) {
			esil_commit (c, a);
		}
	}
	op = NULL;
	return 0;
}