⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsint.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 5 页
字号:
/* jsint.c * (c) 2002 Mikulas Patocka (Vrxni Ideolog), Petr 'Brain' Kulhavy * This file is a part of the Links program, relased under GPL. *//*  * Ve vsech upcallech plati, ze pokud dostanu ID nejakeho objektu, tak * javascript ma k tomu objektu pristupova prava. Jinymi slovy pristupova prava * se testuji v upcallech jen, aby se neco neproneslo vratnici ven. Dovnitr se * muze donaset vsechno, co si javascript donese, na to ma prava. *  * Navic vsechny upcally dostanou pointer na f_data_c, kde bezi javascript, * takze se bude moci testovat, zda javascript nesaha na f_data_c, ke kteremu * nema pristupova prava. * *   Brain *//* Uctovani pameti: * js_mem_alloc/js_mem_free se bude pouzivat na struktury fax_me_tender * dale se bude pouzivat take ve funkcich pro praci s cookies, protoze string * cookies v javascript_context se tez alokuje pomoci js_mem_alloc/js_mem_free. */ /*   Retezce:   vsechny retezce v ramci javascriptu jsou predavany v kodovani f_data->cp   (tedy tak, jak prisly v dokumentu ze site) */#include "links.h" tcount jsint_execute_seq = 0;#ifdef JS#include "struct.h"#include "ipret.h"#include "builtin_keys.h"/*vypisuje to: jaky kod byl zarazen do fronty. jaky kod byl predan interpretu do js_execute_code. jaky kod byl vykonan a ukoncen intepretem jsint_done_execution#define TRACE_EXECUTE*/struct js_request {	struct js_request *next;	struct js_request *prev;	int onclick_submit;	/* >=0 (znamena cislo formulare) pokud tohle je request onclick handleru u submit tlacitka nebo onsubmit handleru */	int onsubmit;		/* dtto pro submit handler */	struct event ev;	/* event, ktery se ma poslat pri uspechu */	int write_pos;	/* document.write position from END of document. -1 if document.write cannot be used */	int wrote;	/* this request called document.write */	int len;	tcount seq;	unsigned char code[1];};/* set_cookies bude parsovat takhle: * +....=............;...............................+   <- tohle je strinzik *      ^            ^ * najdu 1. rovnase a za nim 1. strednik, najdu nasledujici rovnase a * nasledujici strednik, pokud to bude platne (&'='<&';') a 2. jmeno bude * "expires", tak to je furt jedna cookie -> poslu Mikulasovi. * * kdyz ne, tak je to jina susenka a poslu to 1. Mikulasovi * * pokud najdu ';' a za nim whitespace, za kterym neni rovnase, tak od toho * stredniku je to garbaz, kterou vratim do strinziku (fd->js->ctx->cookies) *//* sets all cookies in fd>js->ctx->cookies *//* final_flush means, that set_cookies was called from jsint_done_execution *//* JESTLI V TYHLE FUNKCI BUDE NEJAKA BUGA, tak za to muze PerM, Clock a pan GNU, * ktery tady kolem rusili, ze jsem se nemohl soustredit. Takze se s * pripadnejma reklamacema obratte na ne!  * *  Brain *//* prototypes */void jsint_send_event(struct f_data_c *fd, struct event *ev);int jsint_create(struct f_data_c *);void jsint_done_execution(struct f_data_c *);int jsint_can_access(struct f_data_c *, struct f_data_c *);struct f_data_c *jsint_find_recursive(struct f_data_c *, long);  /* line 89 */void *jsint_find_object(struct f_data_c *, long);long *add_id(long *, int *, long );long *add_fd_id(long *, int *, long, long, unsigned char *);void send_vodevri_v_novym_vokne(struct terminal *, void (*)(struct terminal *, unsigned char *, unsigned char *), struct session *);void add_all_recursive_in_fd(long **, int *, struct f_data_c *, struct f_data_c *);void jsint_set_cookies(struct f_data_c *fd, int final_flush){	unsigned char *str;	unsigned char *next;	unsigned char *eq1, *semic1, *eq2, *semic2;	if(!(fd->js)||!(fd->js->ctx))internal("jsint_set_cookies called with NULL context.\n");	if (!(fd->js->ctx->cookies)||!(fd->rq))return;  /* cookies string is empty, nothing to set */	str=fd->js->ctx->cookies;	a_znova:	eq1=strchr(str,'=');	semic1=strchr(str,';');		if (!*str||(!final_flush&&!semic1))  /* na konci neni strednik a skript jeste bezi, takze to musime vratit do stringu a vypadnout */	{		unsigned char *bla=NULL;		if (*str)bla=stracpy1(str);		js_mem_free(fd->js->ctx->cookies);		fd->js->ctx->cookies=bla;		return;	}	/* ted se v str bud vyskytuje strednik, nebo skript uz skoncil */	if (semic1&&eq1>semic1)	/* '=' je za ';' takze to pred strednikem a strednik skipnem */	{		str=semic1+1;		goto a_znova;	}	next=semic1?semic1+1:str+strlen(str);	if (!eq1)	/* neni tam '=', takze to preskocime */	{		str=next;		goto a_znova;	}	/* ted by to mela bejt regulerni susenka */		next_par:	eq2=NULL,semic2=NULL;	if (semic1!=NULL)	{		eq2=strchr(semic1+1,'=');		semic2=strchr(semic1+1,';');	}		if (eq2&&semic1&&(final_flush||semic2))	{		unsigned char *p=strstr(semic1+1,"expires");		if (!p)p=strstr(semic1+1,"Expires");		if (!p)p=strstr(semic1+1,"EXPIRES");		if (!p)p=strstr(semic1+1,"domain");		if (!p)p=strstr(semic1+1,"Domain");		if (!p)p=strstr(semic1+1,"DOMAIN");		if (!p)p=strstr(semic1+1,"path");		if (!p)p=strstr(semic1+1,"Path");		if (!p)p=strstr(semic1+1,"PATH");		if (!p)p=strstr(semic1+1,"comment");		if (!p)p=strstr(semic1+1,"Comment");		if (!p)p=strstr(semic1+1,"COMMENT");		if (!p)p=strstr(semic1+1,"max-age");		if (!p)p=strstr(semic1+1,"Max-age");		if (!p)p=strstr(semic1+1,"Max-Age");		if (!p)p=strstr(semic1+1,"MAX-AGE");		if (!p)p=strstr(semic1+1,"version");		if (!p)p=strstr(semic1+1,"Version");		if (!p)p=strstr(semic1+1,"VERSION");		if (p&&p>semic1&&p<eq2)  /* za 1. prirazenim nasleduje "expires=", takze to je porad jedna susenka */			{				next=semic2?semic2+1:str+strlen(str);				semic1=semic2;				goto next_par;			}	}	if (*next)next[-1]=0;		for (;*str&&WHITECHAR(*str);str++); /* skip whitechars */	/*debug("set_cookie: \"%s\"", str);*/	set_cookie(fd->ses->term, fd->rq->url, str);	str=next;	goto a_znova;}int jsint_object_type(long to_je_on_Padre){	return to_je_on_Padre&JS_OBJ_MASK;}int jsint_create(struct f_data_c *fd){	struct js_state *js;	if (fd->js) internal("javascript state present");	js = mem_calloc(sizeof(struct js_state));	if (!(js->ctx = js_create_context(fd, ((fd->id)<<JS_OBJ_MASK_SIZE)|JS_OBJ_T_DOCUMENT))) {		mem_free(js);		return 1;	}	init_list(js->queue);	fd->js = js;	return 0;}void jsint_destroy(struct f_data_c *fd){	struct js_state *js = fd->js;	fd->script_t = 0;	if (!js) return;	fd->js = NULL;	pr(js_destroy_context(js->ctx)) return;	if (js->src) mem_free(js->src);	if (js->active) mem_free(js->active);	js_zaflaknuto_pameti-=js->newdata;	free_list(js->queue);	mem_free(js);}/* for <a href="javascript:..."> */void javascript_func(struct session *ses, unsigned char *hlavne_ze_je_vecirek){	unsigned char *code=get_url_data(hlavne_ze_je_vecirek);	jsint_execute_code(current_frame(ses),code,strlen(code),-1,-1,-1, NULL);}void jsint_send_event(struct f_data_c *fd, struct event *ev){	if (!ev || !ev->b) return;	send_event(fd->ses, ev);}/* executes or queues javascript code in frame:	write_pos is number of bytes from the position where document.write should write to the end of document	write_pos == -1 if it is not from <SCRIPT> statement and cannot use document.write*//* data je cislo formulare pro onclick submit handler, jinak se nepouziva *//* ev je udalost, ktera se ma znovu poslat, pokud bylo vraceno true */void jsint_execute_code(struct f_data_c *fd, unsigned char *code, int len, int write_pos, int onclick_submit, int onsubmit, struct event *ev){	struct js_request *r, *q;	for (;code&&len&&*code&&((*code)==' '||(*code)==9||(*code)==13||(*code)==10);code++,len--);		/*	FUJ !!!!	if (!strncasecmp(code,"javascript:",strlen("javascript:")))code+=strlen("javascript:");	*/	if (len >= 11 && !casecmp(code, "javascript:", 11)) code += 11, len -= 11;		if (!js_enable) {		jsint_send_event(fd, ev);		return;	}#ifdef TRACE_EXECUTE	fprintf(stderr, "Submitted: ^^%.*s^^\n", len, code);#endif	if (!fd->js && jsint_create(fd)) {		jsint_send_event(fd, ev);		return;	}	if ((unsigned)len > MAXINT - sizeof(struct js_request)) overalloc();	r = mem_calloc(sizeof(struct js_request) + len);	r->seq = jsint_execute_seq++;	r->write_pos = write_pos;	r->len = len;	r->onclick_submit = onclick_submit;	r->onsubmit = onsubmit;	memcpy(r->code, code, len);	if (ev) memcpy(&r->ev, ev, sizeof(struct event));	if (write_pos == -1) {		struct list_head *l = (struct list_head *)fd->js->queue.prev;		add_to_list(*l, r);	} else {		/* add it beyond all <SCRIPT> requests but before non-<SCRIPT> ones */		foreach(q, fd->js->queue) if (q->write_pos == -1) break;		q = q->prev;		add_at_pos(q, r);	}	jsint_run_queue(fd);}void jsint_done_execution(struct f_data_c *fd){	struct js_request *r, *to_exec;	struct js_state *js = fd->js;	struct event ev = { 0, 0, 0, 0 };	if (!js) {		internal("no js in frame");		return;	}	if (!js->active) {		internal("jsint_done_execution: completion function called on inactive js");		return;	}#ifdef TRACE_EXECUTE	fprintf(stderr, "Done: ^^%.*s^^\n", js->active->len, js->active->code);#endif	/* accept all cookies set by the script */	jsint_set_cookies(fd,1);	/* js->active obsahuje request prave dobehnuteho skriptu */	/* dobehl onclick_handler a nezaplatil (vratil false), budou se dit veci */	if (js->active->ev.b && js->ctx->zaplatim)		memcpy(&ev, &js->active->ev, sizeof(struct event));	if (js->active->onclick_submit >=0 && !js->ctx->zaplatim)	{		/* pokud je handler od stejneho formulare, jako je defered, tak odlozeny skok znicime a zlikvidujem prislusny onsubmit handler z fronty */		if (js->active->onclick_submit == fd->ses->defered_data)		{			foreach (r,js->queue)				/* to je onsubmit od naseho formulare, tak ho smazem */				if (r->onsubmit == js->active->onclick_submit)				{					del_from_list(r);					mem_free(r);					break;	/* zadny dalsi onsubmit tohoto formulare uz nebude */				}			ses_destroy_defered_jump(fd->ses);		}	}	if (js->active->write_pos == -1) mem_free(js->active), js->active = NULL;	else {		r = js->active; js->active = NULL;		if (r->wrote) js->wrote = 1;		jsint_scan_script_tags(fd);		if (!f_is_finished(fd->f_data)) {			fd->done = 0;			fd->parsed_done = 0;		}		if (js->wrote && fd->script_t == -1) {			fd->done = 0;			fd->parsed_done = 0;			fd_loaded(NULL, fd);			js->wrote = 0;		}		mem_free(r);	}		to_exec = js->active;	if (!to_exec && !list_empty(fd->js->queue)) to_exec = fd->js->queue.next;	if (fd->ses->defered_url && (!to_exec || (to_exec->seq > fd->ses->defered_seq && to_exec->write_pos == -1)))	{		unsigned char *url, *target;				url=stracpy(fd->ses->defered_url);		target=stracpy(fd->ses->defered_url);				goto_url_f(fd->ses,NULL,url,target,fd->ses->defered_target_base,fd->ses->defered_data,0,0,0);		mem_free(url);		mem_free(target);	}	else		jsint_run_queue(fd);	jsint_send_event(fd, &ev);}void jsint_run_queue(struct f_data_c *fd){	struct js_request *r;	struct js_state *js = fd->js;	if ((!fd->done && fd->f_data) || !js || js->active || list_empty(js->queue)) return;	r = js->queue.next;	del_from_list(r);	js->active = r;#ifdef TRACE_EXECUTE	fprintf(stderr, "Executing: ^^%.*s^^\n", r->len, r->code);#endif	pr(js_execute_code(js->ctx, r->code, r->len, (void (*)(void *))jsint_done_execution)) {};}/* returns: 1 - source is modified by document.write	    0 - original source*/int jsint_get_source(struct f_data_c *fd, unsigned char **start, unsigned char **end){	struct js_state *js = fd->js;	if (!js || !js->src) return 0;	if (start) *start = js->src;	if (end) *end = js->src + js->srclen;	return 1;}/* * tests if script running in frame "running" can access document in frame "accessed" * 0=no permission, 1=permission OK */int jsint_can_access(struct f_data_c *running, struct f_data_c *accessed){	int a;	unsigned char *h1, *h2;	if (!running || !accessed || !running->rq || !accessed->rq) return 0;	h1 = get_host_name(running->rq->url);	h2 = get_host_name(accessed->rq->url);	a = !strcasecmp(h1, h2);	mem_free(h1);	mem_free(h2);	return a;}/* doc_id is real document id, whithout any type *//* fd must be a valid pointer */struct f_data_c *jsint_find_recursive(struct f_data_c *fd, long doc_id){	struct f_data_c *sub, *fdd;	if (fd->id == doc_id) return fd;	foreach(sub, fd->subframes) {		if ((fdd = jsint_find_recursive(sub, doc_id))) return fdd;	}	return NULL;}/* *	This function finds document that has given ID */struct f_data_c *jsint_find_document(long doc_id){	struct f_data_c *fd;	struct session *ses;	int type=jsint_object_type(doc_id);		if (type!=JS_OBJ_T_DOCUMENT&&type!=JS_OBJ_T_FRAME)		{unsigned char txt[256]; snprintf(txt,256,"jsint_find_document called with type=%d\n",type);internal(txt);}	doc_id>>=JS_OBJ_MASK_SIZE;	foreach(ses, sessions) if ((fd = jsint_find_recursive(ses->screen, doc_id))) return fd;	return NULL;}void jsint_destroy_document_description(struct f_data *f){	struct js_document_description *jsd;	if (!f)return;		jsd= f->js_doc;	if (!jsd) return;	f->js_doc = NULL;	/* Pro Martina: vsecky polozky vyrobene vyse se tady zase musi uvolnit (jak kurtizana v rimskejch laznich) */	/* -------------- */	mem_free(jsd);}/* Document has just loaded. Scan for <SCRIPT> tags and execute each of them */void jsint_scan_script_tags(struct f_data_c *fd){	unsigned char *name, *attr;

⌨️ 快捷键说明

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