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 + -
显示快捷键?