/* 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" #ifdef JS tcount jsint_execute_seq = 0; #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 { list_entry_1st 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 links_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; list_entry_last 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 */ static void jsint_send_event(struct f_data_c *fd, struct links_event *ev); static int jsint_create(struct f_data_c *); static void jsint_done_execution(void *); static int jsint_can_access(struct f_data_c *, struct f_data_c *); static struct f_data_c *jsint_find_recursive(struct f_data_c *, long); /* line 89 */ static void *jsint_find_object(struct f_data_c *, long); static long *add_id(long *, int *, long ); static long *add_fd_id(long *, int *, long, long, unsigned char *); static 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_error("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(cast_const_char 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&&prq->url, str); str=next; goto a_znova; } int jsint_object_type(long to_je_on_Padre) { return to_je_on_Padre&JS_OBJ_MASK; } static int jsint_create(struct f_data_c *fd) { struct js_state *js; if (fd->js) internal_error("javascript state present"); js = mem_calloc(sizeof(struct js_state)); if (!(js->ctx = js_create_context(fd, ((fd->id)<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(struct js_request, js->queue); mem_free(js); } /* for */ 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(cast_const_char code),-1,-1,-1, NULL); } static void jsint_send_event(struct f_data_c *fd, struct links_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