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