javascript.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,788 行 · 第 1/3 页

C
1,788
字号
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "signtool.h"#include <prmem.h>#include <prio.h>#include <prenv.h>static int javascript_fn(char *relpath, char *basedir, char *reldir,	char *filename, void *arg);static int extract_js (char *filename);static int copyinto (char *from, char *to);static PRStatus ensureExists (char *base, char *path);static int make_dirs(char *path, PRInt32 file_perms);static char *jartree = NULL;static int idOrdinal;static PRBool dumpParse=PR_FALSE;static char *event_handlers[] = {"onAbort","onBlur","onChange","onClick","onDblClick","onDragDrop","onError","onFocus","onKeyDown","onKeyPress","onKeyUp","onLoad","onMouseDown","onMouseMove","onMouseOut","onMouseOver","onMouseUp","onMove","onReset","onResize","onSelect","onSubmit","onUnload"};static int num_handlers = 23;/* *  I n l i n e J a v a S c r i p t * *  Javascript signing. Instead of passing an archive to signtool, *  a directory containing html files is given. Archives are created *  from the archive= and src= tag attributes inside the html, *  as appropriate. Then the archives are signed. * */intInlineJavaScript(char *dir, PRBool recurse){	jartree = dir;	if(verbosity >= 0) {		PR_fprintf(outputFD, "\nGenerating inline signatures from HTML files in: %s\n", dir);	}	if(PR_GetEnv("SIGNTOOL_DUMP_PARSE")) {		dumpParse = PR_TRUE;	}	return foreach(dir, "", javascript_fn, recurse, PR_FALSE /*include dirs*/,		(void*)NULL);}/************************************************************************ * * j a v a s c r i p t _ f n */static int javascript_fn     (char *relpath, char *basedir, char *reldir, char *filename, void *arg){  char fullname [FNSIZE];  /* only process inline scripts from .htm, .html, and .shtml*/	if(! (PL_strcaserstr(filename, ".htm") == filename + strlen(filename) -4) &&	   ! (PL_strcaserstr(filename, ".html") == filename + strlen(filename) -5)&&	   ! (PL_strcaserstr(filename, ".shtml") == filename + strlen(filename)-6)){		return 0;	}  /* don't process scripts that signtool has already     extracted (those that are inside .arc directories) */  if(PL_strcaserstr(filename, ".arc") == filename + strlen(filename) - 4)    return 0;	if(verbosity >= 0) {		PR_fprintf(outputFD, "Processing HTML file: %s\n", relpath);	}  /* reset firstArchive at top of each HTML file */  /* skip directories that contain extracted scripts */  if(PL_strcaserstr(reldir, ".arc") == reldir + strlen(reldir) - 4)    return 0;  sprintf (fullname, "%s/%s", basedir, relpath);  return extract_js (fullname);}/*=========================================================================== = = D A T A   S T R U C T U R E S =*/typedef enum {	TEXT_HTML_STATE=0,	SCRIPT_HTML_STATE} HTML_STATE ;typedef enum {	/* we start in the start state */	START_STATE,	/* We are looking for or reading in an attribute */	GET_ATT_STATE,	/* We're burning ws before finding an attribute */	PRE_ATT_WS_STATE,	/* We're burning ws after an attribute.  Looking for an '='. */	POST_ATT_WS_STATE,	/* We're burning ws after an '=', waiting for a value */	PRE_VAL_WS_STATE,	/* We're reading in a value */	GET_VALUE_STATE,	/* We're reading in a value that's inside quotes */	GET_QUOTED_VAL_STATE,	/* We've encountered the closing '>' */	DONE_STATE,	/* Error state */	ERR_STATE} TAG_STATE ;typedef struct AVPair_Str {	char *attribute;	char *value;	unsigned int valueLine; /* the line that the value ends on */	struct AVPair_Str *next;} AVPair;typedef enum {	APPLET_TAG,	SCRIPT_TAG,	LINK_TAG,	STYLE_TAG,	COMMENT_TAG,	OTHER_TAG} TAG_TYPE ;typedef struct {	TAG_TYPE type;	AVPair *attList;	AVPair *attListTail;	char *text;} TagItem;typedef enum {	TAG_ITEM,	TEXT_ITEM} ITEM_TYPE ;typedef struct HTMLItem_Str{	unsigned int startLine;	unsigned int endLine;	ITEM_TYPE type;	union {		TagItem *tag;		char *text;	} item;	struct HTMLItem_Str *next;} HTMLItem;typedef struct {	PRFileDesc *fd;	PRInt32 curIndex;	PRBool IsEOF;#define FILE_BUFFER_BUFSIZE 512	char buf[FILE_BUFFER_BUFSIZE];	PRInt32 startOffset;	PRInt32 maxIndex;	unsigned int lineNum;} FileBuffer;/*=========================================================================== = = F U N C T I O N S =*/static HTMLItem* CreateTextItem(char *text, unsigned int startline,					unsigned int endline);static HTMLItem* CreateTagItem(TagItem* ti, unsigned int startline,					unsigned int endline);static TagItem* ProcessTag(FileBuffer* fb, char **errStr);static void DestroyHTMLItem(HTMLItem *item);static void DestroyTagItem(TagItem* ti);static TAG_TYPE GetTagType(char *att);static FileBuffer* FB_Create(PRFileDesc* fd);static int FB_GetChar(FileBuffer *fb);static PRInt32 FB_GetPointer(FileBuffer *fb);static PRInt32 FB_GetRange(FileBuffer *fb, PRInt32 start, PRInt32 end,															char **buf);static unsigned int FB_GetLineNum(FileBuffer *fb);static void FB_Destroy(FileBuffer *fb);static void PrintTagItem(PRFileDesc *fd, TagItem *ti);static void PrintHTMLStream(PRFileDesc *fd, HTMLItem *head);/************************************************************************ * * C r e a t e T e x t I t e m */static HTMLItem*CreateTextItem(char *text, unsigned int startline, unsigned int endline){	HTMLItem *item;	item = PR_Malloc(sizeof(HTMLItem));	if(!item) {		return NULL;	}	item->type = TEXT_ITEM;	item->item.text = text;	item->next = NULL;	item->startLine = startline;	item->endLine = endline;	return item;}/************************************************************************ * * C r e a t e T a g I t e m */static HTMLItem*CreateTagItem(TagItem* ti, unsigned int startline, unsigned int endline){	HTMLItem *item;	item = PR_Malloc(sizeof(HTMLItem));	if(!item) {		return NULL;	}	item->type = TAG_ITEM;	item->item.tag = ti;	item->next = NULL;	item->startLine = startline;	item->endLine = endline;	return item;}static PRBoolisAttChar(char c){	return (isalnum(c) || c=='/' || c=='-');}/************************************************************************ * * P r o c e s s T a g */static TagItem*ProcessTag(FileBuffer* fb, char **errStr){	TAG_STATE state;	PRInt32 startText, startID, curPos;	PRBool firstAtt;	int curchar;	TagItem *ti=NULL;	AVPair *curPair=NULL;	char quotechar;	unsigned int linenum;	unsigned int startline;	state = START_STATE;	startID = FB_GetPointer(fb);	startText = startID;	firstAtt = PR_TRUE;	ti = (TagItem*) PR_Malloc(sizeof(TagItem));	if(!ti) out_of_memory();	ti->type = OTHER_TAG;	ti->attList = NULL;	ti->attListTail = NULL;	ti->text = NULL;	startline = FB_GetLineNum(fb);	while(state != DONE_STATE && state != ERR_STATE) {		linenum = FB_GetLineNum(fb);		curchar = FB_GetChar(fb);		if(curchar == EOF) {			*errStr = PR_smprintf(				"line %d: Unexpected end-of-file while parsing tag starting at line %d.\n", linenum, startline);			state = ERR_STATE;			continue;		}		switch(state) {		case START_STATE:			if(curchar=='!') {				/*				 * SGML tag or comment				 * Here's the general rule for SGML tags.  Everything from				 * <! to > is the tag.  Inside the tag, comments are				 * delimited with --.  So we are looking for the first '>'				 * that is not commented out, that is, not inside a pair				 * of --: <!DOCTYPE --this is a comment >(psyche!)   -->				 */				PRBool inComment = PR_FALSE;				short hyphenCount = 0; /* number of consecutive hyphens */				while(1) {					linenum = FB_GetLineNum(fb);					curchar = FB_GetChar(fb);					if(curchar == EOF) {						/* Uh oh, EOF inside comment */						*errStr = PR_smprintf(							"line %d: Unexpected end-of-file inside comment starting at line %d.\n",							linenum, startline);						state = ERR_STATE;						break;					}					if(curchar=='-') {						if(hyphenCount==1) {							/* This is a comment delimiter */							inComment = !inComment;							hyphenCount=0;						} else {							/* beginning of a comment delimiter? */							hyphenCount=1;						}					} else if(curchar=='>') {						if(!inComment) {							/* This is the end of the tag */							state = DONE_STATE;							break;						} else {							/* The > is inside a comment, so it's not							 * really the end of the tag */							hyphenCount=0;						}					} else {						hyphenCount = 0;					}				}				ti->type = COMMENT_TAG;				break;			}			/* fall through */		case GET_ATT_STATE:			if(isspace(curchar) || curchar=='=' || curchar=='>') {				/* end of the current attribute */				curPos = FB_GetPointer(fb)-2;				if(curPos >= startID) {					/* We have an attribute */					curPair = (AVPair*)PR_Malloc(sizeof(AVPair));					if(!curPair) out_of_memory();					curPair->value = NULL;					curPair->next = NULL;					FB_GetRange(fb, startID, curPos, &curPair->attribute);					/* Stick this attribute on the list */					if(ti->attListTail) {						ti->attListTail->next = curPair;						ti->attListTail = curPair;					} else {						ti->attList = ti->attListTail = curPair;					}										/* If this is the first attribute, find the type of tag					 * based on it. Also, start saving the text of the tag. */					if(firstAtt) {						ti->type = GetTagType(curPair->attribute);						startText = FB_GetPointer(fb)-1;						firstAtt = PR_FALSE;					}				} else {					if(curchar=='=') {						/* If we don't have any attribute but we do have an						 * equal sign, that's an error */						*errStr = PR_smprintf("line %d: Malformed tag starting at line %d.\n", linenum, startline);						state = ERR_STATE;						break;					}				}				/* Compute next state */				if(curchar=='=') {					startID = FB_GetPointer(fb);					state = PRE_VAL_WS_STATE;				} else if(curchar=='>') {					state = DONE_STATE;				} else if(curPair) {					state = POST_ATT_WS_STATE;				} else {					state = PRE_ATT_WS_STATE;				}			} else if(isAttChar(curchar)) {				/* Just another char in the attribute. Do nothing */				state = GET_ATT_STATE;			} else {				/* bogus char */				*errStr= PR_smprintf("line %d: Bogus chararacter '%c' in tag.\n",					linenum, curchar);				state = ERR_STATE;				break;			}			break;		case PRE_ATT_WS_STATE:			if(curchar=='>') {				state = DONE_STATE;			} else if(isspace(curchar)) {				/* more whitespace, do nothing */			} else if(isAttChar(curchar)) {				/* starting another attribute */				startID = FB_GetPointer(fb)-1;				state = GET_ATT_STATE;			} else {				/* bogus char */				*errStr = PR_smprintf("line %d: Bogus character '%c' in tag.\n",					linenum, curchar);				state = ERR_STATE;				break;			}			break;		case POST_ATT_WS_STATE:			if(curchar=='>') {				state = DONE_STATE;			} else if(isspace(curchar)) {				/* more whitespace, do nothing */			} else if(isAttChar(curchar)) {				/* starting another attribute */				startID = FB_GetPointer(fb)-1;				state = GET_ATT_STATE;			} else if(curchar=='=') {				/* there was whitespace between the attribute and its equal				 * sign, which means there's a value coming up */				state = PRE_VAL_WS_STATE;			} else {				/* bogus char */				*errStr = PR_smprintf("line %d: Bogus character '%c' in tag.\n",					linenum, curchar);				state = ERR_STATE;				break;			}			break;		case PRE_VAL_WS_STATE:			if(curchar=='>') {				/* premature end-of-tag (sounds like a personal problem). */				*errStr = PR_smprintf(					"line %d: End of tag while waiting for value.\n", linenum);				state = ERR_STATE;				break;			} else if(isspace(curchar)) {				/* more whitespace, do nothing */				break;			} else {				/* this must be some sort of value. Fall through				 * to GET_VALUE_STATE */				startID=FB_GetPointer(fb)-1;				state = GET_VALUE_STATE;			}			/* Fall through if we didn't break on '>' or whitespace */		case GET_VALUE_STATE:			if(isspace(curchar) || curchar=='>') {				/* end of value */				curPos = FB_GetPointer(fb)-2;				if(curPos >= startID) {					/* Grab the value */					FB_GetRange(fb, startID, curPos, &curPair->value);					curPair->valueLine = linenum;				} else {					/* empty value, leave as NULL */				}				if(isspace(curchar)) {					state = PRE_ATT_WS_STATE;				} else {					state = DONE_STATE;				}			} else if(curchar=='\"' || curchar=='\'') {				/* quoted value.  Start recording the value inside the quote*/				startID = FB_GetPointer(fb);				state = GET_QUOTED_VAL_STATE;				quotechar = curchar; /* look for matching quote type */			} else {				/* just more value */			}			break;		case GET_QUOTED_VAL_STATE:			if(curchar == quotechar) {				/* end of quoted value */				curPos = FB_GetPointer(fb)-2;				if(curPos >= startID) {					/* Grab the value */					FB_GetRange(fb, startID, curPos, &curPair->value);					curPair->valueLine = linenum;				} else {					/* empty value, leave it as NULL */				}				state = GET_ATT_STATE;				startID = FB_GetPointer(fb);			} else {				/* more quoted value, continue */			}			break;		case DONE_STATE:		case ERR_STATE:		default:			; /* should never get here */		}	}	if(state == DONE_STATE) {		/* Get the text of the tag */		curPos = FB_GetPointer(fb)-1;		FB_GetRange(fb, startText, curPos, &ti->text);		/* Return the tag */		return ti;	}	/* Uh oh, an error.  Kill the tag item*/	DestroyTagItem(ti);	return NULL;}/************************************************************************ * * D e s t r o y H T M L I t e m */static voidDestroyHTMLItem(HTMLItem *item){	if(item->type == TAG_ITEM) {		DestroyTagItem(item->item.tag);	} else {		if(item->item.text) {			PR_Free(item->item.text);		}	}}/************************************************************************ * * D e s t r o y T a g I t e m */static void

⌨️ 快捷键说明

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