javascript.c

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

C
1,788
字号
					if(cp) { PR_Free(cp); cp = NULL; }				} else {					/* compare the strings */					if( !PORT_Strncasecmp(cp, "</script>", 9) ) {						/* This is the end of the script. Record the text. */						curOffset--;						if(curOffset >= textStart) {							if(FB_GetRange(fb, textStart, curOffset, &text) !=							  curOffset-textStart+1) {								PR_fprintf(errorFD,									"Unable to read from %s.\n", filename);								errorCount++;								goto loser;							}							curitem = CreateTextItem(text, startLine, linenum);							text = NULL;							if(tail == NULL) {								head = tail = curitem;							} else {								tail->next = curitem;								tail = curitem;							}						}												/* Now parse the /script tag and put it on the list */						tagp = ProcessTag(fb, &tagerr);						if(!tagp) {							if(tagerr) {								PR_fprintf(errorFD,									"Error in file %s: %s\n", filename, tagerr);							} else {								PR_fprintf(errorFD,									"Error in file %s, in tag starting at"									" line %d\n", filename, linenum);							}							errorCount++;							goto loser;						}						curitem = CreateTagItem(tagp, linenum,										FB_GetLineNum(fb));						if(tail == NULL) {							head = tail = curitem;						} else {							tail->next = curitem;							tail = curitem;						}						/* go back to text state */						state = TEXT_HTML_STATE;						textStart = FB_GetPointer(fb);						startLine = FB_GetLineNum(fb);					}				}			}			break;		}	}	/* End of the file.  Wrap up any remaining text */	if(state == SCRIPT_HTML_STATE) {		if(tail && tail->type==TAG_ITEM) {			PR_fprintf(errorFD, "ERROR: <SCRIPT> tag at %s:%d is not followed "			"by a </SCRIPT> tag.\n", filename, tail->startLine);		} else {			PR_fprintf(errorFD, "ERROR: <SCRIPT> tag in file %s is not followed"			" by a </SCRIPT tag.\n", filename);		}		errorCount++;		goto loser;	}	curOffset = FB_GetPointer(fb)-1;	if(curOffset >= textStart) {		text = NULL;		if( FB_GetRange(fb, textStart, curOffset, &text) !=			curOffset-textStart+1) {			PR_fprintf(errorFD, "Unable to read from %s.\n", filename);			errorCount++;			goto loser;		}		curitem = CreateTextItem(text, startLine, linenum);		text = NULL;		if(tail == NULL) {			head = tail = curitem;		} else  {			tail->next = curitem;			tail = curitem;		}	}	if(dumpParse) {		PrintHTMLStream(outputFD, head);	}	/*	 * Now we have a stream of tags and text.  Go through and deal with each.	 */	for(curitem = head; curitem; curitem = curitem->next) {		TagItem *tagp=NULL;		AVPair *pairp=NULL;		char *src=NULL, *id=NULL, *codebase=NULL;		PRBool hasEventHandler=PR_FALSE;		int i;		/* Reset archive directory for each tag */		if(archiveDir) {			PR_Free(archiveDir); archiveDir = NULL;		}		/* We only analyze tags */		if(curitem->type != TAG_ITEM) {			continue;		}		tagp = curitem->item.tag;		/* go through the attributes to get information */		for(pairp=tagp->attList; pairp; pairp=pairp->next) {			/* ARCHIVE= */			if( !PL_strcasecmp(pairp->attribute, "archive")) {				if(archiveDir) {						/* Duplicate attribute.  Print warning */					PR_fprintf(errorFD,					  "warning: \"%s\" attribute overwrites previous attribute"					  " in tag starting at %s:%d.\n",					  pairp->attribute, filename, curitem->startLine);					warningCount++;					PR_Free(archiveDir);				}				archiveDir = PL_strdup(pairp->value);				/* Substiture ".arc" for ".jar" */				if( (PL_strlen(archiveDir)<4) ||					PL_strcasecmp((archiveDir+strlen(archiveDir)-4), ".jar")){					PR_fprintf(errorFD,					  "warning: ARCHIVE attribute should end in \".jar\" in tag"					  " starting on %s:%d.\n", filename, curitem->startLine);					warningCount++;					PR_Free(archiveDir);					archiveDir = PR_smprintf("%s.arc", archiveDir);				} else {					PL_strcpy(archiveDir+strlen(archiveDir)-4, ".arc");				}				/* Record the first archive.  This will be used later if				 * the archive is not specified */				if(firstArchiveDir == NULL) {					firstArchiveDir = PL_strdup(archiveDir);				}			}			/* CODEBASE= */			else if( !PL_strcasecmp(pairp->attribute, "codebase")) {				if(codebase) {					/* Duplicate attribute.  Print warning */					PR_fprintf(errorFD,					  "warning: \"%s\" attribute overwrites previous attribute"					  " in tag staring at %s:%d.\n",					  pairp->attribute, filename, curitem->startLine);					warningCount++;				}				codebase = pairp->value;			}			/* SRC= and HREF= */			else if( !PORT_Strcasecmp(pairp->attribute, "src") ||				!PORT_Strcasecmp(pairp->attribute, "href") ) {				if(src) {					/* Duplicate attribute.  Print warning */					PR_fprintf(errorFD,					  "warning: \"%s\" attribute overwrites previous attribute"					  " in tag staring at %s:%d.\n",					  pairp->attribute, filename, curitem->startLine);					warningCount++;				}				src = pairp->value;			}			/* CODE= */			else if(!PORT_Strcasecmp(pairp->attribute, "code") ) {				/*!!!XXX Change PORT to PL all over this code !!! */				if(src) {					/* Duplicate attribute.  Print warning */					PR_fprintf(errorFD,					  "warning: \"%s\" attribute overwrites previous attribute"					  " ,in tag staring at %s:%d.\n",					  pairp->attribute, filename, curitem->startLine);					warningCount++;				}				src = pairp->value;				/* Append a .class if one is not already present */				if( (PL_strlen(src)<6) ||					PL_strcasecmp( (src + PL_strlen(src) - 6), ".class") ) {					src = PR_smprintf("%s.class", src);					/* Put this string back into the data structure so it					 * will be deallocated properly */					PR_Free(pairp->value);					pairp->value = src;				}			}			/* ID= */			else if (!PL_strcasecmp(pairp->attribute, "id") ) {				if(id) {					/* Duplicate attribute.  Print warning */					PR_fprintf(errorFD,					  "warning: \"%s\" attribute overwrites previous attribute"					  " in tag staring at %s:%d.\n",					  pairp->attribute, filename, curitem->startLine);					warningCount++;				}				id = pairp->value;			}			/* STYLE= */			/* style= attributes, along with JS entities, are stored into			 * files with dynamically generated names. The filenames are			 * based on the order in which the text is found in the file.			 * All JS entities on all lines up to and including the line			 * containing the end of the tag that has this style= attribute			 * will be processed before this style=attribute.  So we need			 * to record the line that this _tag_ (not the attribute) ends on.			 */			else if(!PL_strcasecmp(pairp->attribute, "style") && pairp->value) {				HTMLItem *styleItem;				/* Put this item on the style list */				styleItem = CreateTextItem(PL_strdup(pairp->value),										curitem->startLine, curitem->endLine);				if(styleListTail == NULL) {					styleList = styleListTail = styleItem;				} else {					styleListTail->next = styleItem;					styleListTail = styleItem;				}			}			/* Event handlers */			else {				for(i=0; i < num_handlers; i++) {					if(!PL_strcasecmp(event_handlers[i], pairp->attribute)) {						hasEventHandler = PR_TRUE;						break;					}				}			}			/* JS Entity */			{			char *entityStart, *entityEnd;			HTMLItem *entityItem;			/* go through each JavaScript entity ( &{...}; ) and store it			 * in the entityList.  The important thing is to record what			 * line number it's on, so we can get it in the right order			 * in relation to style= attributes.			 * Apparently, these can't flow across lines, so the start and			 * end line will be the same.  That helps matters.			 */			entityEnd = pairp->value;			while( entityEnd &&					(entityStart = PL_strstr(entityEnd, "&{")) != NULL) {				entityStart +=2; /* point at beginning of actual entity */				entityEnd = PL_strstr(entityStart, "}");				if(entityEnd) {					/* Put this item on the entity list */					*entityEnd = '\0';					entityItem = CreateTextItem(PL_strdup(entityStart),										pairp->valueLine, pairp->valueLine);					*entityEnd = '}';					if(entityListTail) {						entityListTail->next = entityItem;						entityListTail = entityItem;					} else {						entityList = entityListTail = entityItem;					}				}			}			}		}		/* If no archive was supplied, we use the first one of the file */		if(!archiveDir && firstArchiveDir) {			archiveDir = PL_strdup(firstArchiveDir);		}		/* If we have an event handler, we need to archive this tag */		if(hasEventHandler) {			if(!id) {				PR_fprintf(errorFD,					"warning: tag starting at %s:%d has event handler but"					" no ID attribute.  The tag will not be signed.\n",					filename, curitem->startLine);					warningCount++;			} else if(!archiveDir) {				PR_fprintf(errorFD,					"warning: tag starting at %s:%d has event handler but"					" no ARCHIVE attribute.  The tag will not be signed.\n",					filename, curitem->startLine);					warningCount++;			} else {				if(SaveInlineScript(tagp->text, id, basedir, archiveDir)) {					goto loser;				}			}		}		switch(tagp->type) {		case APPLET_TAG:			if(!src) {				PR_fprintf(errorFD,					"error: APPLET tag starting on %s:%d has no CODE "					"attribute.\n", filename, curitem->startLine);				errorCount++;				goto loser;			} else if(!archiveDir) {				PR_fprintf(errorFD,					"error: APPLET tag starting on %s:%d has no ARCHIVE "					"attribute.\n", filename, curitem->startLine);				errorCount++;				goto loser;			} else {				if(SaveSource(src, codebase, basedir, archiveDir)) {					goto loser;				}			}			break;		case SCRIPT_TAG:		case LINK_TAG:		case STYLE_TAG:			if(!archiveDir) {				PR_fprintf(errorFD,					"error: %s tag starting on %s:%d has no ARCHIVE "					"attribute.\n", TagTypeToString(tagp->type),					filename, curitem->startLine);				errorCount++;				goto loser;			} else if(src) {				if(SaveSource(src, codebase, basedir, archiveDir)) {					goto loser;				}			} else if(id) {				/* Save the next text item */				if(!curitem->next || (curitem->next->type != TEXT_ITEM)) {					PR_fprintf(errorFD,						"warning: %s tag starting on %s:%d is not followed"						" by script text.\n", TagTypeToString(tagp->type),						filename, curitem->startLine);					warningCount++;					/* just create empty file */					if(SaveInlineScript("", id, basedir, archiveDir)) {						goto loser;					}				} else {					curitem = curitem->next;					if(SaveInlineScript(curitem->item.text, id, basedir,					  archiveDir)){						goto loser;					}				}			} else {				/* No src or id tag--warning */				PR_fprintf(errorFD,					"warning: %s tag starting on %s:%d has no SRC or"					" ID attributes.  Will not sign.\n",					TagTypeToString(tagp->type), filename, curitem->startLine);				warningCount++;			}			break;		default:			/* do nothing for other tags */			break;		}	}	/* Now deal with all the unnamable scripts */	if(firstArchiveDir) {		HTMLItem *style, *entity;		/* Go through the lists of JS entities and style attributes.  Do them		 * in chronological order within a list.  Pick the list with the lower		 * endLine. In case of a tie, entities come first.		 */		style = styleList; entity = entityList;		while(style || entity) {			if(!entity || (style && (style->endLine < entity->endLine))) {				/* Process style */				SaveUnnamableScript(style->item.text, basedir, firstArchiveDir,					filename);				style=style->next;			} else {				/* Process entity */				SaveUnnamableScript(entity->item.text, basedir, firstArchiveDir,					filename);				entity=entity->next;			}		}	}	retval = 0;loser:	/* Blow away the stream */	while(head) {		curitem = head;		head = head->next;		DestroyHTMLItem(curitem);	}	while(styleList) {		curitem = styleList;		styleList = styleList->next;		DestroyHTMLItem(curitem);	}	while(entityList) {		curitem = entityList;		entityList = entityList->next;		DestroyHTMLItem(curitem);	}	if(text) {		PR_Free(text); text=NULL;	}	if(fb) {		FB_Destroy(fb); fb=NULL;	}	if(fd) {		PR_Close(fd);	}	if(tagerr) {		PR_smprintf_free(tagerr); tagerr=NULL;	}	if(archiveDir) {		PR_Free(archiveDir); archiveDir=NULL;	}	if(firstArchiveDir) {		PR_Free(firstArchiveDir); firstArchiveDir=NULL;	}	return retval;}/********************************************************************** * * e n s u r e E x i s t s * * Check for existence of indicated directory.  If it doesn't exist, * it will be created. * Returns PR_SUCCESS if the directory is present, PR_FAILURE otherwise. */static PRStatusensureExists (char *base, char *path){	char fn [FNSIZE];	PRDir *dir;	sprintf (fn, "%s/%s", base, path);	/*PR_fprintf(outputFD, "Trying to open directory %s.\n", fn);*/	if( (dir=PR_OpenDir(fn)) ) {		PR_CloseDir(dir);		return PR_SUCCESS;	}	return PR_MkDir(fn, 0777);}/*************************************************************************** * * m a k e _ d i r s * * Ensure that the directory portion of the path exists.  This may require * making the directory, and its parent, and its parent's parent, etc. */static intmake_dirs(char *path, int file_perms){	char *Path;	char *start;	char *sep;	int ret = 0;	PRFileInfo info;	if(!path) {		return 0;	}	Path = PL_strdup(path);	start = strpbrk(Path, "/\\");	if(!start) {		return 0;	}	start++; /* start right after first slash */	/* Each time through the loop add one more directory. */	while( (sep=strpbrk(start, "/\\")) ) {		*sep = '\0';		if( PR_GetFileInfo(Path, &info) != PR_SUCCESS) {			/* No such dir, we have to create it */			if( PR_MkDir(Path, file_perms) != PR_SUCCESS) {				PR_fprintf(errorFD, "ERROR: Unable to create directory %s.\n",					Path);				errorCount++;				ret = -1;				goto loser;			}		} else {			/* something exists by this name, make sure it's a directory */			if( info.type != PR_FILE_DIRECTORY ) {				PR_fprintf(errorFD, "ERROR: Unable to create directory %s.\n",					Path);				errorCount++;				ret = -1;				goto loser;			}		}		start = sep+1; /* start after the next slash */		*sep = '/';	}loser:	PR_Free(Path);	return ret;}/* *  c o p y i n t o * *  Function to copy file "from" to path "to". * */static intcopyinto (char *from, char *to){	PRInt32 num;	char buf [BUFSIZ];	PRFileDesc *infp=NULL, *outfp=NULL;	int retval = -1;	if ((infp = PR_Open(from, PR_RDONLY, 0777)) == NULL) {		PR_fprintf(errorFD, "ERROR: Unable to open \"%s\" for reading.\n",			from);		errorCount++;		goto finish;	}	/* If to already exists, print a warning before deleting it */	if(PR_Access(to, PR_ACCESS_EXISTS) == PR_SUCCESS) {		PR_fprintf(errorFD, "warning: %s already exists--will overwrite\n",			to);		warningCount++;		if(rm_dash_r(to)) {			PR_fprintf(errorFD,				"ERROR: Unable to remove %s.\n", to);			errorCount++;			goto finish;		}	}	if ((outfp = PR_Open(to, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0777))					== NULL) {		char *errBuf=NULL;		errBuf = PR_Malloc(PR_GetErrorTextLength());		PR_fprintf(errorFD, "ERROR: Unable to open \"%s\" for writing.\n",			to);		if(PR_GetErrorText(errBuf)) {			PR_fprintf(errorFD, "Cause: %s\n", errBuf);		}		if(errBuf) {			PR_Free(errBuf);		}		errorCount++;		goto finish;	}	while( (num = PR_Read(infp, buf, BUFSIZ)) >0) {		if(PR_Write(outfp, buf, num) != num) {			PR_fprintf(errorFD, "ERROR: Error writing to %s.\n", to);			errorCount++;			goto finish;		}    }	retval = 0;finish:	if(infp) PR_Close(infp); 	if(outfp) PR_Close(outfp);	return retval;}

⌨️ 快捷键说明

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