lib/htmlPage.c File Reference

#include "common.h"
#include "errabort.h"
#include "errCatch.h"
#include "memalloc.h"
#include "linefile.h"
#include "hash.h"
#include "dystring.h"
#include "cheapcgi.h"
#include "obscure.h"
#include "filePath.h"
#include "net.h"
#include "htmlPage.h"

Include dependency graph for htmlPage.c:

Go to the source code of this file.

Data Structures

struct  htmlTableRow
struct  htmlTable

Defines

#define MIMEBUFSIZE   4096

Functions

void htmlStatusFree (struct htmlStatus **pStatus)
void htmlStatusFreeList (struct htmlStatus **pList)
void htmlCookieFree (struct htmlCookie **pCookie)
void htmlCookieFreeList (struct htmlCookie **pList)
htmlCookiehtmlCookieFileRead (char *fileName)
static void cookieOutput (struct dyString *dy, struct htmlCookie *cookieList)
void htmlAttributeFree (struct htmlAttribute **pAttribute)
void htmlAttributeFreeList (struct htmlAttribute **pList)
void htmlTagFree (struct htmlTag **pTag)
void htmlTagFreeList (struct htmlTag **pList)
void htmlFormVarFree (struct htmlFormVar **pVar)
void htmlFormVarFreeList (struct htmlFormVar **pList)
void htmlFormFree (struct htmlForm **pForm)
void htmlFormFreeList (struct htmlForm **pList)
void htmlPageFree (struct htmlPage **pPage)
void htmlPageFreeList (struct htmlPage **pList)
static int findLineNumber (char *start, char *pos)
static void tagVaWarn (struct htmlPage *page, struct htmlTag *tag, char *format, va_list args)
static void tagWarn (struct htmlPage *page, struct htmlTag *tag, char *format,...)
static void tagAbort (struct htmlPage *page, struct htmlTag *tag, char *format,...)
htmlStatushtmlStatusParse (char **pText)
char * htmlNextCrLfLine (char **pS)
static void cookieParseNameValuePair (char *s, char **retName, char **retVal)
static struct htmlCookieparseCookie (char *s)
static struct hashhtmlHeaderRead (char **pHtml, struct htmlCookie **pCookies)
static char * htmlAttributeFindVal (struct htmlAttribute *list, char *name)
char * htmlTagAttributeVal (struct htmlPage *page, struct htmlTag *tag, char *name, char *defaultVal)
char * htmlTagAttributeNeeded (struct htmlPage *page, struct htmlTag *tag, char *name)
static struct htmlTaghtmlTagScan (char *html, char *dupe)
static struct htmlFormVarfindOrMakeVar (struct htmlPage *page, char *name, struct hash *hash, struct htmlTag *tag, struct htmlFormVar **pVarList)
static boolean isMixableInputType (char *type)
static void htmlFormVarAddValue (struct htmlFormVar *var, char *value)
static struct htmlFormVarformParseVars (struct htmlPage *page, struct htmlForm *form)
static struct htmlFormhtmlParseForms (struct htmlPage *page, struct htmlTag *startTag, struct htmlTag *endTag)
htmlPagehtmlPageParse (char *url, char *fullText)
htmlPagehtmlPageParseNoHead (char *url, char *htmlText)
htmlPagehtmlPageParseOk (char *url, char *fullText)
char * htmlSlurpWithCookies (char *url, struct htmlCookie *cookies)
htmlPagehtmlPageGetWithCookies (char *url, struct htmlCookie *cookies)
htmlPagehtmlPageForwarded (char *url, struct htmlCookie *cookies)
htmlPagehtmlPageForwardedNoAbort (char *url, struct htmlCookie *cookies)
htmlPagehtmlPageGet (char *url)
void htmlFormVarPrint (struct htmlFormVar *var, FILE *f, char *prefix)
void htmlFormPrint (struct htmlForm *form, FILE *f)
htmlFormhtmlFormGet (struct htmlPage *page, char *name)
htmlFormVarhtmlFormVarGet (struct htmlForm *form, char *name)
void htmlFormVarSet (struct htmlForm *form, char *name, char *val)
htmlFormVarhtmlPageGetVar (struct htmlPage *page, struct htmlForm *form, char *name)
void htmlPageSetVar (struct htmlPage *page, struct htmlForm *form, char *name, char *val)
static void asciiEntityDecode (char *in, char *out, int inLength)
char * htmlExpandUrl (char *base, char *url)
static void appendCgiVar (struct dyString *dy, char *name, char *value)
static void appendMimeVar (struct dyString *dy, char *name, char *value, char *varType, char *boundary)
static void appendMimeTerminus (struct dyString *dy, char *boundary)
static int countOccurrences (char *needle, int nLen, char *haystack, int hLen)
static boolean isMimeEncoded (struct htmlForm *form)
char * htmlFormCgiVars (struct htmlPage *page, struct htmlForm *form, char *buttonName, char *buttonVal, struct dyString *dyHeader)
htmlPagehtmlPageFromForm (struct htmlPage *origPage, struct htmlForm *form, char *buttonName, char *buttonVal)
slNamehtmlPageScanAttribute (struct htmlPage *page, char *tagName, char *attribute)
slNamehtmlPageLinks (struct htmlPage *page)
static void validateTables (struct htmlPage *page, struct htmlTag *startTag, struct htmlTag *endTag)
static void checkTagIsInside (struct htmlPage *page, char *outsiders, char *insiders, struct htmlTag *startTag, struct htmlTag *endTag)
static void checkNest (struct htmlPage *page, char *type, struct htmlTag *startTag, struct htmlTag *endTag)
static void validateNestingTags (struct htmlPage *page, struct htmlTag *startTag, struct htmlTag *endTag, char *nesters[], int nesterCount)
static struct htmlTagvalidateBody (struct htmlPage *page, struct htmlTag *startTag)
static char * urlOkChars ()
static void validateCgiUrl (char *url)
static void validateCgiUrls (struct htmlPage *page)
static int countTagsOfType (struct htmlTag *tagList, char *type)
static void checkExactlyOne (struct htmlTag *tagList, char *type)
void htmlPageFormOrAbort (struct htmlPage *page)
void htmlPageValidateOrAbort (struct htmlPage *page)

Variables

static char const rcsid [] = "$Id: htmlPage.c,v 1.32 2006/07/29 00:17:28 galt Exp $"
static char * bodyNesters []
static char * headNesters []


Define Documentation

#define MIMEBUFSIZE   4096

Definition at line 1179 of file htmlPage.c.


Function Documentation

static void appendCgiVar ( struct dyString dy,
char *  name,
char *  value 
) [static]

Definition at line 1164 of file htmlPage.c.

References cgiEncode(), dyStringAppend(), dyStringAppendC(), freez(), and dyString::stringSize.

Referenced by htmlFormCgiVars().

01166 {
01167 char *enc = NULL;
01168 if (value == NULL)
01169     value = "";
01170 enc = cgiEncode(value);
01171 if (dy->stringSize != 0)
01172     dyStringAppendC(dy, '&');
01173 dyStringAppend(dy, name);
01174 dyStringAppendC(dy, '=');
01175 dyStringAppend(dy, enc);
01176 freez(&enc);
01177 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void appendMimeTerminus ( struct dyString dy,
char *  boundary 
) [static]

Definition at line 1227 of file htmlPage.c.

References dyStringAppend().

01229 {
01230 dyStringAppend(dy, "\r\n--");
01231 dyStringAppend(dy, boundary);
01232 dyStringAppend(dy, "--\r\n");
01233 }

Here is the call graph for this function:

static void appendMimeVar ( struct dyString dy,
char *  name,
char *  value,
char *  varType,
char *  boundary 
) [static]

Definition at line 1181 of file htmlPage.c.

References carefulClose(), dyStringAppend(), dyStringAppendN(), errnoAbort(), MIMEBUFSIZE, mustOpen(), and sameWord.

Referenced by htmlFormCgiVars().

01183 {
01184 char *fileName = NULL;
01185 
01186 if (value == NULL)
01187     value = "";
01188 dyStringAppend(dy, "\r\n--");
01189 dyStringAppend(dy, boundary);
01190 dyStringAppend(dy, "\r\n");
01191 dyStringAppend(dy, "content-disposition: form-data; name=\"");
01192 dyStringAppend(dy, name);
01193 dyStringAppend(dy, "\"");
01194 
01195 if (varType && sameWord(varType, "FILE"))
01196     {
01197     fileName = strrchr(value,'/'); 
01198     if (fileName)
01199         ++fileName;
01200     else
01201         fileName = value;
01202     dyStringAppend(dy, "; filename=\"");
01203     dyStringAppend(dy, fileName);
01204     dyStringAppend(dy, "\"");
01205     }
01206 dyStringAppend(dy, "\r\n");
01207 dyStringAppend(dy, "\r\n");
01208 if (varType && sameWord(varType, "FILE") && !sameWord(value,""))
01209     {
01210     FILE *f = mustOpen(value, "r");
01211     char buf[MIMEBUFSIZE];
01212     int bytesRead = 0;
01213     do
01214         {
01215         bytesRead = fread(buf,1,MIMEBUFSIZE,f);
01216         if (bytesRead < 0)
01217             errnoAbort("error reading file to upload %s",value);
01218         dyStringAppendN(dy, buf, bytesRead);
01219         }
01220     while(bytesRead > 0);
01221     carefulClose(&f);
01222     }
01223 else    
01224     dyStringAppend(dy, value);
01225 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void asciiEntityDecode ( char *  in,
char *  out,
int  inLength 
) [static]

Definition at line 1048 of file htmlPage.c.

Referenced by htmlExpandUrl().

01052 {
01053 char c;
01054 int i;
01055 char *e;
01056 for (i=0; i<inLength;++i)
01057     {
01058     c = *in++;
01059     if ((c == '&') && (*in == '#'))
01060         {
01061         in++;
01062         if ((e = strchr(in,';')) == NULL  || (e - in) > 5)
01063             { /* probably a badly formatted string, just recover and continue */
01064             *out++ = '&';
01065             *out++ = '#';
01066             }
01067         else
01068             {
01069             int code;
01070             if (sscanf(in, "%d", &code) != 1)
01071                 {
01072                 code = '?';
01073                 }
01074             if (code > 255) 
01075                 {
01076                 code = '?';
01077                 }
01078             in = e;
01079             in++;
01080             *out++ = code;
01081             }
01082         }
01083     else
01084         *out++ = c;
01085     }
01086 *out++ = 0;
01087 }

Here is the caller graph for this function:

static void checkExactlyOne ( struct htmlTag tagList,
char *  type 
) [static]

Definition at line 1746 of file htmlPage.c.

References countTagsOfType(), and errAbort().

Referenced by htmlPageValidateOrAbort().

01748 {
01749 int count = countTagsOfType(tagList, type);
01750 if (count != 1)
01751     errAbort("Expecting exactly 1 <%s>, got %d", type, count);
01752 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void checkNest ( struct htmlPage page,
char *  type,
struct htmlTag startTag,
struct htmlTag endTag 
) [static]

Definition at line 1594 of file htmlPage.c.

References htmlTag::name, htmlTag::next, safef(), sameWord, and tagAbort().

Referenced by validateNestingTags().

01597 {
01598 struct htmlTag *tag;
01599 int depth = 0;
01600 char endType[256];
01601 safef(endType, sizeof(endType), "/%s", type);
01602 for (tag = startTag; tag != endTag; tag = tag->next)
01603     {
01604     if (sameWord(tag->name, type))
01605         ++depth;
01606     else if (sameWord(tag->name, endType))
01607         {
01608         --depth;
01609         if (depth < 0)
01610            tagAbort(page, tag, "<%s> without preceding <%s>", endType, type);
01611         }
01612     }
01613 if (depth != 0)
01614     errAbort("Missing <%s> tag", endType);
01615 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void checkTagIsInside ( struct htmlPage page,
char *  outsiders,
char *  insiders,
struct htmlTag startTag,
struct htmlTag endTag 
) [static]

Definition at line 1540 of file htmlPage.c.

References cloneString(), freeHash(), freeMem(), hashAdd(), hashLookup(), htmlTag::name, newHash(), htmlTag::next, nextWord(), safef(), tagAbort(), and touppers().

01543 {
01544 char *outDupe = cloneString(outsiders);
01545 char *inDupe = cloneString(insiders);
01546 char *line, *word;
01547 int depth = 0;
01548 struct htmlTag *tag;
01549 struct hash *outOpen = newHash(8);
01550 struct hash *outClose = newHash(8);
01551 struct hash *inHash = newHash(8);
01552 char buf[256];
01553 
01554 /* Create hashes of all insiders */
01555 line = inDupe;
01556 while ((word = nextWord(&line)) != NULL)
01557     {
01558     touppers(word);
01559     hashAdd(inHash, word, NULL);
01560     }
01561 
01562 /* Create hash of open and close outsiders. */
01563 line = outDupe;
01564 while ((word = nextWord(&line)) != NULL)
01565     {
01566     touppers(word);
01567     hashAdd(outOpen, word, NULL);
01568     safef(buf, sizeof(buf), "/%s", word);
01569     hashAdd(outClose, buf, NULL);
01570     }
01571 
01572 /* Stream through tags making sure that insiders are
01573  * at least one deep inside of outsiders. */
01574 for (tag = startTag; tag != NULL; tag = tag->next)
01575     {
01576     char *type = tag->name;
01577     if (hashLookup(outOpen, type ))
01578         ++depth;
01579     else if (hashLookup(outClose, type))
01580         --depth;
01581     else if (hashLookup(inHash, type))
01582         {
01583         if (depth <= 0)
01584             tagAbort(page, tag, "%s outside of any of %s", type, outsiders);
01585         }
01586     }
01587 freeHash(&inHash);
01588 freeHash(&outOpen);
01589 freeHash(&outClose);
01590 freeMem(outDupe);
01591 freeMem(inDupe);
01592 }

Here is the call graph for this function:

static void cookieOutput ( struct dyString dy,
struct htmlCookie cookieList 
) [static]

Definition at line 103 of file htmlPage.c.

References cookieList, dyStringAppend(), dyStringAppendC(), htmlCookie::name, htmlCookie::next, and htmlCookie::value.

Referenced by htmlPageFromForm(), and htmlSlurpWithCookies().

00105 {
00106 struct htmlCookie *cookie;
00107 if (cookieList != NULL)
00108     {
00109     dyStringAppend(dy, "Cookie:");
00110     for (cookie = cookieList; cookie != NULL; cookie = cookie->next)
00111         {
00112         if (cookie != cookieList)
00113             dyStringAppendC(dy, ';');
00114         dyStringAppendC(dy, ' ');
00115         dyStringAppend(dy, cookie->name);
00116         dyStringAppendC(dy, '=');
00117         dyStringAppend(dy, cookie->value);
00118         }
00119     dyStringAppend(dy, "\r\n");
00120     }
00121 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void cookieParseNameValuePair ( char *  s,
char **  retName,
char **  retVal 
) [static]

Definition at line 352 of file htmlPage.c.

Referenced by parseCookie().

00354 {
00355 char *val = strchr(s, '=');
00356 if (val == NULL)
00357     {
00358     val = s + strlen(s);
00359     }
00360 *val++ = 0;
00361 *retName = s;
00362 *retVal = val;
00363 }

Here is the caller graph for this function:

static int countOccurrences ( char *  needle,
int  nLen,
char *  haystack,
int  hLen 
) [static]

Definition at line 1236 of file htmlPage.c.

References memMatch().

01238 {
01239 int count = 0;
01240 char *match=NULL;
01241 while((match=memMatch(needle, nLen, haystack, hLen)) != NULL)
01242     {
01243     ++count;
01244     hLen -= (match - haystack) + nLen;
01245     if (hLen < 1)
01246         break;
01247     haystack=match+nLen;
01248     }
01249 return count;
01250 }

Here is the call graph for this function:

static int countTagsOfType ( struct htmlTag tagList,
char *  type 
) [static]

Definition at line 1735 of file htmlPage.c.

References htmlTag::name, htmlTag::next, and sameString.

Referenced by checkExactlyOne().

01737 {
01738 struct htmlTag *tag;
01739 int count = 0;
01740 for (tag = tagList; tag != NULL; tag = tag->next)
01741     if (sameString(tag->name, type))
01742         ++count;
01743 return count;
01744 }

Here is the caller graph for this function:

static int findLineNumber ( char *  start,
char *  pos 
) [static]

Definition at line 255 of file htmlPage.c.

Referenced by tagVaWarn().

00257 {
00258 char *s;
00259 int line = 1;
00260 for (s = start; s <= pos; ++s)
00261     {
00262     if (s[0] == '\n')
00263        ++line;
00264     }
00265 return line;
00266 }

Here is the caller graph for this function:

static struct htmlFormVar* findOrMakeVar ( struct htmlPage page,
char *  name,
struct hash hash,
struct htmlTag tag,
struct htmlFormVar **  pVarList 
) [static, read]

Definition at line 634 of file htmlPage.c.

References AllocVar, hashAdd(), hashFindVal(), htmlTag::name, refAdd(), sameWord, slAddHead, htmlFormVar::tagName, htmlFormVar::tags, and tagWarn().

Referenced by formParseVars().

00639 {
00640 struct htmlFormVar *var = hashFindVal(hash, name);
00641 if (var == NULL)
00642     {
00643     AllocVar(var);
00644     var->name = name;
00645     var->tagName = tag->name;
00646     hashAdd(hash, name, var);
00647     slAddHead(pVarList, var);
00648     }
00649 else
00650     {
00651     if (!sameWord(var->tagName, tag->name))
00652         {
00653         tagWarn(page, tag, "Mixing FORM variable tag types %s and %s", 
00654                 var->tagName, tag->name);
00655         var->tagName = tag->name;
00656         }
00657     }
00658 refAdd(&var->tags, tag);
00659 return var;
00660 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct htmlFormVar* formParseVars ( struct htmlPage page,
struct htmlForm form 
) [static, read]

Definition at line 678 of file htmlPage.c.

References cloneString(), cloneStringZ(), htmlTag::end, htmlForm::endTag, findOrMakeVar(), freeHash(), freez(), htmlFormVarAddValue(), htmlTagAttributeNeeded(), htmlTagAttributeVal(), isMixableInputType(), htmlTag::name, newHash(), htmlFormVar::next, htmlTag::next, sameWord, slReverse(), htmlForm::startTag, and tagWarn().

00684 {
00685 struct htmlTag *tag;
00686 struct htmlFormVar *varList = NULL, *var;
00687 struct hash *hash = newHash(0);
00688 for (tag = form->startTag->next; tag != form->endTag; tag = tag->next)
00689     {
00690     if (sameWord(tag->name, "INPUT"))
00691         {
00692         char *type = htmlTagAttributeVal(page, tag, "TYPE", NULL);
00693         char *varName = htmlTagAttributeVal(page, tag, "NAME", NULL);
00694         char *value = htmlTagAttributeVal(page, tag, "VALUE", NULL);
00695         if (type == NULL)
00696             type = "TEXT";
00697         if (varName == NULL)
00698             {
00699             if (!sameWord(type, "SUBMIT") && !sameWord(type, "CLEAR")
00700                 && !sameWord(type, "BUTTON") && !sameWord(type, "RESET")
00701                 && !sameWord(type, "IMAGE"))
00702                 tagWarn(page, tag, "Missing NAME attribute");
00703             varName = "n/a";
00704             }
00705         var = findOrMakeVar(page, varName, hash, tag, &varList); 
00706         if (var->type != NULL && !sameWord(var->type, type))
00707             {
00708             if (!isMixableInputType(var->type) || !isMixableInputType(type))
00709                 tagWarn(page, tag, "Mixing input types %s and %s", var->type, type);
00710             }
00711         var->type = type;
00712         if (sameWord(type, "TEXT") || sameWord(type, "PASSWORD") 
00713                 || sameWord(type, "FILE") || sameWord(type, "HIDDEN")
00714                 || sameWord(type, "IMAGE"))
00715             {
00716             var->curVal = cloneString(value);
00717             }
00718         else if (sameWord(type, "CHECKBOX"))
00719             {
00720             if (htmlTagAttributeVal(page, tag, "CHECKED", NULL) != NULL)
00721                 var->curVal = cloneString("on");
00722             }
00723         else if (sameWord(type, "RADIO"))
00724             {
00725             if (htmlTagAttributeVal(page, tag, "CHECKED", NULL) != NULL)
00726                 var->curVal = cloneString(value);
00727             htmlFormVarAddValue(var, value);
00728             }
00729         else if ( sameWord(type, "RESET") || sameWord(type, "BUTTON") ||
00730                 sameWord(type, "SUBMIT") || sameWord(type, "IMAGE") ||
00731                 sameWord(type, "n/a"))
00732             {
00733             /* Do nothing. */
00734             }
00735         else
00736             {
00737             tagWarn(page, tag, "Unrecognized INPUT TYPE %s", type);
00738             }
00739         }
00740     else if (sameWord(tag->name, "SELECT"))
00741         {
00742         char *varName = htmlTagAttributeNeeded(page, tag, "NAME");
00743         struct htmlTag *subTag;
00744         var = findOrMakeVar(page, varName, hash, tag, &varList); 
00745         for (subTag = tag->next; subTag != form->endTag; subTag = subTag->next)
00746             {
00747             if (sameWord(subTag->name, "/SELECT"))
00748                 {
00749                 if (var->curVal == NULL && var->values != NULL)
00750                     {
00751                     var->curVal = cloneString(var->values->name);
00752                     }
00753                 break;
00754                 }
00755             else if (sameWord(subTag->name, "OPTION"))
00756                 {
00757                 char *val = cloneString(htmlTagAttributeVal(page, subTag, "VALUE", NULL));
00758                 if (val == NULL)
00759                     {
00760                     char *e = strchr(subTag->end, '<');
00761                     if (e != NULL)
00762                         val = cloneStringZ(subTag->end, e - subTag->end);
00763                     }
00764                 if (val != NULL)
00765                     htmlFormVarAddValue(var, val);
00766                 if (htmlTagAttributeVal(page, subTag, "SELECTED", NULL) != NULL)
00767                     {
00768                     if (val != NULL)
00769                         var->curVal = cloneString(val);
00770                     }
00771                 freez(&val);
00772                 }
00773             }
00774         }
00775     else if (sameWord(tag->name, "TEXTAREA"))
00776         {
00777         char *varName = htmlTagAttributeNeeded(page, tag, "NAME");
00778         char *e = strchr(tag->end, '<');
00779         var = findOrMakeVar(page, varName, hash, tag, &varList); 
00780         if (e != NULL)
00781             var->curVal = cloneStringZ(tag->end, e - tag->end);
00782         }
00783     }
00784 freeHash(&hash);    
00785 slReverse(&varList);
00786 for (var = varList; var != NULL; var = var->next)
00787     {
00788     slReverse(&var->tags);
00789     }
00790 return varList;
00791 }

Here is the call graph for this function:

static char* htmlAttributeFindVal ( struct htmlAttribute list,
char *  name 
) [static]

Definition at line 442 of file htmlPage.c.

References htmlAttribute::name, htmlAttribute::next, sameWord, and htmlAttribute::val.

Referenced by htmlTagAttributeVal().

00444 {
00445 struct htmlAttribute *att;
00446 for (att = list; att != NULL; att = att->next)
00447     {
00448     if (sameWord(att->name, name))
00449         return att->val;
00450     }
00451 return NULL;
00452 }

Here is the caller graph for this function:

void htmlAttributeFree ( struct htmlAttribute **  pAttribute  ) 

Definition at line 124 of file htmlPage.c.

References freeMem(), freez(), htmlAttribute::name, and htmlAttribute::val.

Referenced by htmlAttributeFreeList().

00126 {
00127 struct htmlAttribute *att = *pAttribute;
00128 if (att != NULL)
00129     {
00130     freeMem(att->name);
00131     freeMem(att->val);
00132     freez(pAttribute);
00133     }
00134 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlAttributeFreeList ( struct htmlAttribute **  pList  ) 

Definition at line 136 of file htmlPage.c.

References htmlAttributeFree(), and htmlAttribute::next.

Referenced by htmlTagFree().

00138 {
00139 struct htmlAttribute *el, *next;
00140 
00141 for (el = *pList; el != NULL; el = next)
00142     {
00143     next = el->next;
00144     htmlAttributeFree(&el);
00145     }
00146 *pList = NULL;
00147 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlCookie* htmlCookieFileRead ( char *  fileName  )  [read]

Definition at line 80 of file htmlPage.c.

References AllocVar, cloneString(), errAbort(), lineFile::fileName, lineFileClose(), lineFileNextReal(), lineFileOpen(), lineFile::lineIx, nextWord(), skipLeadingSpaces(), slAddHead, slReverse(), and TRUE.

00083 {
00084 struct lineFile *lf = lineFileOpen(fileName, TRUE);
00085 struct htmlCookie *list = NULL, *cookie;
00086 char *line, *word;
00087 while (lineFileNextReal(lf, &line))
00088     {
00089     word = nextWord(&line);
00090     line = skipLeadingSpaces(line);
00091     if (line == NULL)
00092         errAbort("Missing cookie value line %d of %s", lf->lineIx, lf->fileName);
00093     AllocVar(cookie);
00094     cookie->name = cloneString(word);
00095     cookie->value = cloneString(line);
00096     slAddHead(&list, cookie);
00097     }
00098 lineFileClose(&lf);
00099 slReverse(&list);
00100 return list;
00101 }

Here is the call graph for this function:

void htmlCookieFree ( struct htmlCookie **  pCookie  ) 

Definition at line 52 of file htmlPage.c.

References htmlCookie::domain, htmlCookie::expires, freeMem(), freez(), htmlCookie::name, htmlCookie::path, and htmlCookie::value.

Referenced by htmlCookieFreeList().

00054 {
00055 struct htmlCookie *cookie = *pCookie;
00056 if (cookie != NULL)
00057     {
00058     freeMem(cookie->name);
00059     freeMem(cookie->value);
00060     freeMem(cookie->domain);
00061     freeMem(cookie->path);
00062     freeMem(cookie->expires);
00063     freez(pCookie);
00064     }
00065 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlCookieFreeList ( struct htmlCookie **  pList  ) 

Definition at line 67 of file htmlPage.c.

References htmlCookieFree(), and htmlCookie::next.

Referenced by htmlPageFree().

00069 {
00070 struct htmlCookie *el, *next;
00071 
00072 for (el = *pList; el != NULL; el = next)
00073     {
00074     next = el->next;
00075     htmlCookieFree(&el);
00076     }
00077 *pList = NULL;
00078 }

Here is the call graph for this function:

Here is the caller graph for this function:

char* htmlExpandUrl ( char *  base,
char *  url 
)

Definition at line 1090 of file htmlPage.c.

References asciiEntityDecode(), cloneString(), cloneStringZ(), dyStringAppend(), dyStringAppendC(), dyStringAppendN(), dyStringCannibalize(), dyStringNew, expandRelativePath(), freez(), lastChar(), startsWith(), and dyString::string.

Referenced by htmlPageFromForm().

01093 {
01094 struct dyString *dy = NULL;
01095 char *hostName, *pastHostName;
01096 
01097 /* some mailto: have SGML char encoding, e.g &#97; to hide from spambots */
01098 url = cloneString(url); /* Clone because asciiEntityDecode may modify it. */
01099 asciiEntityDecode(url, url, strlen(url));
01100 
01101 /* In easiest case URL is actually absolute and begins with
01102  * protocol.  Just return clone of url. */
01103 if (startsWith("http:", url) || startsWith("https:", url))
01104     return url;
01105 
01106 /* If it's got a colon, but no http or https, then it's some
01107  * protocol we don't understand, like a mailto.  Just return NULL. */
01108 if (strchr(url, ':') != NULL)
01109     {
01110     freez(&url);
01111     return NULL;
01112     }
01113 
01114 /* Figure out first character past host name. Load up
01115  * return string with protocol (if any) and host name. */
01116 dy = dyStringNew(256);
01117 if (startsWith("http:", base) || startsWith("https:", base))
01118     hostName = (strchr(base, ':') + 3);
01119 else
01120     hostName = base;
01121 pastHostName = strchr(hostName, '/');
01122 if (pastHostName == NULL)
01123     pastHostName = hostName + strlen(hostName);
01124 dyStringAppendN(dy, base, pastHostName - base);
01125 
01126 /* Add url to return string after host name. */
01127 if (startsWith("/", url))       /* New URL is absolute, just append to hostName */
01128     {
01129     dyStringAppend(dy, url);
01130     }
01131 else
01132     {
01133     char *curDir = pastHostName;
01134     char *endDir;
01135     if (curDir[0] == '/')
01136         curDir += 1;
01137     dyStringAppendC(dy, '/');
01138     endDir = strrchr(curDir, '/');
01139     if (endDir == NULL)
01140         endDir = curDir;
01141     if (startsWith("../", url))
01142         {
01143         char *dir = cloneStringZ(curDir, endDir-curDir);
01144         char *path = expandRelativePath(dir, url);
01145         if (path != NULL)
01146              {
01147              dyStringAppend(dy, path);
01148              }
01149         freez(&dir);
01150         freez(&path);
01151         }
01152     else
01153         {
01154         dyStringAppendN(dy, curDir, endDir-curDir);
01155         if (lastChar(dy->string) != '/')
01156             dyStringAppendC(dy, '/');
01157         dyStringAppend(dy, url);
01158         }
01159     }
01160 freez(&url);
01161 return dyStringCannibalize(&dy);
01162 }

Here is the call graph for this function:

Here is the caller graph for this function:

char* htmlFormCgiVars ( struct htmlPage page,
struct htmlForm form,
char *  buttonName,
char *  buttonVal,
struct dyString dyHeader 
)

Definition at line 1262 of file htmlPage.c.

References appendCgiVar(), appendMimeVar(), htmlFormVar::curVal, htmlPage::forms, isMimeEncoded(), htmlFormVar::name, newDyString(), htmlFormVar::next, safef(), sameWord, htmlFormVar::tagName, TRUE, htmlFormVar::type, and htmlForm::vars.

Referenced by htmlPageFromForm().

01266 {
01267 struct dyString *dy = newDyString(0);
01268 struct htmlFormVar *var;
01269 boolean isMime = isMimeEncoded(form);
01270 int mimeParts = 0;
01271 char boundary[256];
01272 
01273 while(TRUE)
01274     {
01275     if (isMime)
01276         {
01277         /* choose a new string for the boundary */
01278         /* Set initial seed */
01279         int i = 0;
01280         safef(boundary,sizeof(boundary),"%s", "---------");
01281         srand( (unsigned)time( NULL ) );
01282         for(i=strlen(boundary);i<41;++i)
01283             {
01284             int r = (int) 26 * (rand() / (RAND_MAX + 1.0));
01285             boundary[i] = r+'A';
01286             }
01287         boundary[i] = 0;
01288         }
01289 
01290     if (form == NULL)
01291         form = page->forms;
01292     if (buttonName != NULL && !isMime)
01293         appendCgiVar(dy, buttonName, buttonVal);
01294     for (var = form->vars; var != NULL; var = var->next)
01295         {
01296         if (sameWord(var->tagName, "SELECT") || 
01297             sameWord(var->tagName, "TEXTAREA") || 
01298             (var->type != NULL &&
01299             ((sameWord(var->type, "RADIO") || sameWord(var->type, "TEXTBOX")
01300             || sameWord(var->type, "PASSWORD") || sameWord(var->type, "HIDDEN")
01301             || sameWord(var->type, "TEXT") || sameWord(var->type, "FILE")))))
01302             {
01303             char *val = var->curVal;
01304             if (val == NULL)
01305                 val = "";
01306             if (isMime)
01307                 {
01308                 ++mimeParts;
01309                 appendMimeVar(dy, var->name, val, var->type, boundary);
01310                 }
01311             else            
01312                 appendCgiVar(dy, var->name, val);
01313             }
01314         else if (var->type != NULL && sameWord(var->type, "CHECKBOX"))
01315             {
01316             if (var->curVal != NULL)
01317                 {
01318                 if (isMime)         
01319                     {
01320                     ++mimeParts;
01321                     appendMimeVar(dy, var->name, var->curVal, var->type, boundary);
01322                     }
01323                 else        
01324                     appendCgiVar(dy, var->name, var->curVal);
01325                 }
01326             }
01327         else if (isMime && buttonName && sameWord(buttonName,var->name))
01328             {
01329             ++mimeParts;
01330             appendMimeVar(dy, buttonName, buttonVal, NULL, boundary);
01331             }
01332         }
01333     if (isMime) 
01334         {
01335         ++mimeParts;
01336         appendMimeTerminus(dy,boundary);
01337         if (countOccurrences(boundary,strlen(boundary),dy->string,dy->stringSize) != mimeParts)
01338             { /* boundary was found in input! # occurrences not as expected */
01339             dyStringClear(dy);
01340             continue;  /* if at first you don't succeed, try another boundary string */
01341             }
01342         dyStringPrintf(dyHeader, "Content-type: multipart/form-data, boundary=%s\r\n",boundary);
01343         if (isMime && verboseLevel() == 2)
01344             {
01345             mustWrite(stderr, dyHeader->string, dyHeader->stringSize);
01346             mustWrite(stderr, dy->string, dy->stringSize);
01347             }
01348         }
01349     break;
01350     }   
01351     
01352 return dyStringCannibalize(&dy);
01353 
01354 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlFormFree ( struct htmlForm **  pForm  ) 

Definition at line 201 of file htmlPage.c.

References freez(), htmlFormVarFreeList(), and htmlForm::vars.

Referenced by htmlFormFreeList().

00203 {
00204 struct htmlForm *form = *pForm;
00205 if (form != NULL)
00206     {
00207     htmlFormVarFreeList(&form->vars);
00208     freez(pForm);
00209     }
00210 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlFormFreeList ( struct htmlForm **  pList  ) 

Definition at line 212 of file htmlPage.c.

References htmlFormFree(), and htmlForm::next.

Referenced by htmlPageFree().

00214 {
00215 struct htmlForm *el, *next;
00216 
00217 for (el = *pList; el != NULL; el = next)
00218     {
00219     next = el->next;
00220     htmlFormFree(&el);
00221     }
00222 *pList = NULL;
00223 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlForm* htmlFormGet ( struct htmlPage page,
char *  name 
) [read]

Definition at line 986 of file htmlPage.c.

References htmlPage::forms, htmlForm::name, htmlForm::next, and sameWord.

00988 {
00989 struct htmlForm *form;
00990 for (form = page->forms; form != NULL; form = form->next)
00991     if (sameWord(form->name, name))
00992         break;
00993 return form;
00994 }

void htmlFormPrint ( struct htmlForm form,
FILE *  f 
)

Definition at line 977 of file htmlPage.c.

References htmlForm::action, htmlFormVarPrint(), htmlForm::method, htmlForm::name, htmlFormVar::next, and htmlForm::vars.

00979 {
00980 struct htmlFormVar *var;
00981 fprintf(f, "%s\t%s\t%s\n", form->name, form->method, form->action);
00982 for (var = form->vars; var != NULL; var = var->next)
00983     htmlFormVarPrint(var, f, "\t");
00984 }

Here is the call graph for this function:

static void htmlFormVarAddValue ( struct htmlFormVar var,
char *  value 
) [static]

Definition at line 670 of file htmlPage.c.

References name, slAddTail(), slNameNew, and htmlFormVar::values.

Referenced by formParseVars().

00672 {
00673 struct slName *name = slNameNew(value);
00674 slAddTail(&var->values, name);
00675 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlFormVarFree ( struct htmlFormVar **  pVar  ) 

Definition at line 174 of file htmlPage.c.

References htmlFormVar::curVal, freeMem(), freez(), slFreeList(), htmlFormVar::tags, and htmlFormVar::values.

Referenced by htmlFormVarFreeList().

00176 {
00177 struct htmlFormVar *var = *pVar;
00178 if (var != NULL)
00179     {
00180     freeMem(var->curVal);
00181     slFreeList(&var->values);
00182     slFreeList(&var->tags);
00183     freez(pVar);
00184     }
00185 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlFormVarFreeList ( struct htmlFormVar **  pList  ) 

Definition at line 187 of file htmlPage.c.

References htmlFormVarFree(), and htmlFormVar::next.

Referenced by htmlFormFree().

00189 {
00190 struct htmlFormVar *el, *next;
00191 
00192 for (el = *pList; el != NULL; el = next)
00193     {
00194     next = el->next;
00195     htmlFormVarFree(&el);
00196     }
00197 *pList = NULL;
00198 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlFormVar* htmlFormVarGet ( struct htmlForm form,
char *  name 
) [read]

Definition at line 996 of file htmlPage.c.

References errAbort(), htmlFormVar::name, htmlFormVar::next, sameWord, and htmlForm::vars.

Referenced by htmlFormVarSet(), and htmlPageGetVar().

00998 {
00999 struct htmlFormVar *var;
01000 if (form == NULL)
01001     errAbort("Null form passed to htmlFormVarGet");
01002 for (var = form->vars; var != NULL; var = var->next)
01003     if (sameWord(var->name, name))
01004         break;
01005 return var;
01006 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlFormVarPrint ( struct htmlFormVar var,
FILE *  f,
char *  prefix 
)

Definition at line 966 of file htmlPage.c.

References htmlFormVar::curVal, naForNull(), slName::name, htmlFormVar::name, slName::next, htmlFormVar::tagName, htmlFormVar::type, and htmlFormVar::values.

Referenced by htmlFormPrint().

00968 {
00969 struct slName *val;
00970 fprintf(f, "%s%s\t%s\t%s\t%s\n", prefix, var->name, var->tagName, 
00971         naForNull(var->type), 
00972         naForNull(var->curVal));
00973 for (val = var->values; val != NULL; val = val->next)
00974      fprintf(f, "%s\t%s\n", prefix, val->name);
00975 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlFormVarSet ( struct htmlForm form,
char *  name,
char *  val 
)

Definition at line 1008 of file htmlPage.c.

References AllocVar, cloneString(), htmlFormVar::curVal, errAbort(), freez(), htmlFormVarGet(), slAddHead, and htmlForm::vars.

Referenced by htmlPageSetVar().

01010 {
01011 struct htmlFormVar *var;
01012 if (form == NULL)
01013     errAbort("Null form passed to htmlFormVarSet");
01014 var = htmlFormVarGet(form, name);
01015 if (var == NULL)
01016     {
01017     AllocVar(var);
01018     var->type = "TEXT";
01019     var->tagName = "INPUT";
01020     var->name = name;
01021     slAddHead(&form->vars, var);
01022     }
01023 freez(&var->curVal);
01024 var->curVal = cloneString(val);
01025 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct hash* htmlHeaderRead ( char **  pHtml,
struct htmlCookie **  pCookies 
) [static, read]

Definition at line 413 of file htmlPage.c.

References cloneString(), hashAdd(), hashNew, htmlNextCrLfLine(), nextWord(), parseCookie(), sameString, skipLeadingSpaces(), slAddTail(), and warn().

Referenced by htmlPageParse().

00415                                                   : value. */
00416 {
00417 struct hash *hash = hashNew(6);
00418 for (;;)
00419     {
00420     char *line = htmlNextCrLfLine(pHtml);
00421     char *word;
00422     if (line == NULL)
00423         {
00424         warn("End of file in header");
00425         break;
00426         }
00427     word = nextWord(&line);
00428     if (word == NULL)
00429         break;
00430     line = skipLeadingSpaces(line);
00431     hashAdd(hash, word, cloneString(line));
00432     if (sameString(word, "Set-Cookie:"))
00433         {
00434         struct htmlCookie *cookie = parseCookie(line);
00435         if (cookie != NULL)
00436             slAddTail(pCookies, cookie);
00437         }
00438     }
00439 return hash;
00440 }

Here is the call graph for this function:

Here is the caller graph for this function:

char* htmlNextCrLfLine ( char **  pS  ) 

Definition at line 328 of file htmlPage.c.

References verbose().

Referenced by htmlHeaderRead().

00332 {
00333 char *s = *pS, *e;
00334 if (s == NULL || s[0] == 0)
00335     return NULL;
00336 e = strchr(s, '\n');
00337 if (e == NULL)
00338     verbose(1, "End of file in header\n");
00339 else 
00340     {
00341     *e = 0;
00342     if (e == s || e[-1] != '\r')
00343         verbose(1, "Missing <CR> in header line\n");
00344     else
00345        e[-1] = 0;
00346     e += 1;
00347     }
00348 *pS = e;
00349 return s;
00350 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlPageFormOrAbort ( struct htmlPage page  ) 

Definition at line 1755 of file htmlPage.c.

References errAbort(), and htmlPage::forms.

01757 {
01758 if (page == NULL)
01759     errAbort("Can't validate NULL page");
01760 if (page->forms == NULL)
01761     errAbort("No form found");
01762 }

Here is the call graph for this function:

struct htmlPage* htmlPageForwarded ( char *  url,
struct htmlCookie cookies 
) [read]

Definition at line 918 of file htmlPage.c.

References htmlPage::cookies, hashFindVal(), htmlPage::header, htmlPageFree(), and htmlPageGetWithCookies().

Referenced by htmlPageForwardedNoAbort().

00922 {
00923 struct htmlPage *page = htmlPageGetWithCookies(url, cookies);
00924 int level, maxLevels = 7;
00925 for (level = 0; level < maxLevels; ++level)
00926     {
00927     struct htmlPage *newPage;
00928     char *newUrl = hashFindVal(page->header, "Location:");
00929     if (newUrl == NULL)
00930         break;
00931     newPage = htmlPageGetWithCookies(newUrl, cookies);
00932     htmlPageFree(&page);
00933     page = newPage;
00934     }
00935 return page;
00936 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlPage* htmlPageForwardedNoAbort ( char *  url,
struct htmlCookie cookies 
) [read]

Definition at line 938 of file htmlPage.c.

References htmlPage::cookies, errCatchEnd(), errCatchFree(), errCatchNew(), errCatchStart, errCatch::gotError, htmlPageForwarded(), errCatch::message, dyString::string, and warn().

00940 {
00941 struct errCatch *errCatch = errCatchNew();
00942 struct htmlPage *page = NULL;
00943 if (errCatchStart(errCatch))
00944     page = htmlPageForwarded(url, cookies);
00945 errCatchEnd(errCatch);
00946 if (errCatch->gotError)
00947     warn(errCatch->message->string);
00948 errCatchFree(&errCatch);
00949 return page;
00950 }

Here is the call graph for this function:

void htmlPageFree ( struct htmlPage **  pPage  ) 

Definition at line 225 of file htmlPage.c.

References htmlPage::cookies, htmlPage::forms, freeHashAndVals(), freez(), htmlPage::fullText, htmlPage::header, htmlCookieFreeList(), htmlFormFreeList(), htmlStatusFree(), htmlTagFreeList(), htmlPage::status, htmlPage::tags, and htmlPage::url.

Referenced by htmlPageForwarded(), htmlPageFreeList(), qaPageFromForm(), qaPageGet(), and qaStatusOnPage().

00227 {
00228 struct htmlPage *page = *pPage;
00229 if (page != NULL)
00230     {
00231     freez(&page->url);
00232     htmlStatusFree(&page->status);
00233     freeHashAndVals(&page->header);
00234     htmlCookieFreeList(&page->cookies);
00235     freez(&page->fullText);
00236     htmlTagFreeList(&page->tags);
00237     htmlFormFreeList(&page->forms);
00238     freez(pPage);
00239     }
00240 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlPageFreeList ( struct htmlPage **  pList  ) 

Definition at line 242 of file htmlPage.c.

References htmlPageFree(), and htmlPage::next.

00244 {
00245 struct htmlPage *el, *next;
00246 
00247 for (el = *pList; el != NULL; el = next)
00248     {
00249     next = el->next;
00250     htmlPageFree(&el);
00251     }
00252 *pList = NULL;
00253 }

Here is the call graph for this function:

struct htmlPage* htmlPageFromForm ( struct htmlPage origPage,
struct htmlForm form,
char *  buttonName,
char *  buttonVal 
) [read]

Definition at line 1356 of file htmlPage.c.

References htmlForm::action, cookieOutput(), htmlPage::cookies, dyStringAppend(), dyStringCannibalize(), dyStringFree, dyStringNew, dyStringPrintf(), FALSE, freez(), htmlExpandUrl(), htmlFormCgiVars(), htmlPageParse(), htmlForm::method, netOpenHttpExt(), netSlurpFile(), sameWord, dyString::string, dyString::stringSize, htmlPage::url, and verbose().

Referenced by qaPageFromForm().

01360 {
01361 struct htmlPage *newPage = NULL;
01362 struct dyString *dyUrl = dyStringNew(0);
01363 struct dyString *dyHeader = dyStringNew(0);
01364 struct dyString *dyText = NULL;
01365 char *url = htmlExpandUrl(origPage->url, form->action);
01366 char *cgiVars = NULL;
01367 int contentLength = 0;
01368 int sd = -1;
01369 
01370 dyStringAppend(dyUrl, url);
01371 cookieOutput(dyHeader, origPage->cookies);
01372 if (sameWord(form->method, "GET"))
01373     {
01374     cgiVars = htmlFormCgiVars(origPage, form, buttonName, buttonVal, dyHeader);
01375     dyStringAppend(dyUrl, "?");
01376     dyStringAppend(dyUrl, cgiVars);
01377     verbose(3, "GET %s\n", dyUrl->string);
01378     sd = netOpenHttpExt(dyUrl->string, form->method, FALSE);
01379     dyStringAppend(dyHeader, "\r\n");
01380     write(sd, dyHeader->string, dyHeader->stringSize);
01381     }
01382 else if (sameWord(form->method, "POST"))
01383     {
01384     cgiVars = htmlFormCgiVars(origPage, form, buttonName, buttonVal, dyHeader);
01385     contentLength = strlen(cgiVars);
01386     verbose(3, "POST %s\n", dyUrl->string);
01387     sd = netOpenHttpExt(dyUrl->string, form->method, FALSE);
01388     dyStringPrintf(dyHeader, "Content-length: %d\r\n", contentLength);
01389     dyStringAppend(dyHeader, "\r\n");
01390     write(sd, dyHeader->string, dyHeader->stringSize);
01391     write(sd, cgiVars, contentLength);
01392     }
01393 dyText = netSlurpFile(sd);
01394 close(sd);
01395 newPage = htmlPageParse(url, dyStringCannibalize(&dyText));
01396 freez(&url);
01397 dyStringFree(&dyUrl);
01398 dyStringFree(&dyHeader);
01399 freez(&cgiVars);
01400 return newPage;
01401 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlPage* htmlPageGet ( char *  url  )  [read]

Definition at line 953 of file htmlPage.c.

References fileExists(), htmlPageGetWithCookies(), htmlPageParseNoHead(), and readInGulp().

Referenced by qaPageGet().

00955 {
00956 if (fileExists(url))
00957     {
00958     char *buf;
00959     readInGulp(url, &buf, NULL);
00960     return htmlPageParseNoHead(url, buf);
00961     }
00962 else
00963     return htmlPageGetWithCookies(url, NULL);
00964 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlFormVar* htmlPageGetVar ( struct htmlPage page,
struct htmlForm form,
char *  name 
) [read]

Definition at line 1028 of file htmlPage.c.

References htmlPage::forms, and htmlFormVarGet().

01030 {
01031 if (form == NULL)
01032     form = page->forms;
01033 return htmlFormVarGet(form, name);
01034 }

Here is the call graph for this function:

struct htmlPage* htmlPageGetWithCookies ( char *  url,
struct htmlCookie cookies 
) [read]

Definition at line 910 of file htmlPage.c.

References htmlPage::cookies, htmlPageParse(), and htmlSlurpWithCookies().

Referenced by htmlPageForwarded(), and htmlPageGet().

00913 {
00914 char *buf = htmlSlurpWithCookies(url, cookies);
00915 return htmlPageParse(url, buf);
00916 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct slName* htmlPageLinks ( struct htmlPage page  )  [read]

Definition at line 1430 of file htmlPage.c.

References htmlPageScanAttribute().

Referenced by validateCgiUrls().

01432 {
01433 return htmlPageScanAttribute(page, NULL, "HREF");
01434 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlPage* htmlPageParse ( char *  url,
char *  fullText 
) [read]

Definition at line 831 of file htmlPage.c.

References AllocVar, cloneLongString(), cloneString(), htmlPage::cookies, htmlPage::forms, freez(), htmlPage::fullText, hashAdd(), hashFindVal(), htmlPage::header, htmlHeaderRead(), htmlParseForms(), htmlStatusParse(), htmlTagScan(), htmlPage::htmlText, startsWith(), htmlPage::status, htmlStatus::status, htmlPage::tags, htmlPage::url, and warn().

Referenced by htmlPageFromForm(), htmlPageGetWithCookies(), and htmlPageParseOk().

00833 {
00834 struct htmlPage *page;
00835 char *dupe = cloneLongString(fullText);
00836 char *s = dupe;
00837 struct htmlStatus *status = htmlStatusParse(&s);
00838 char *contentType;
00839 
00840 if (status == NULL)
00841     return NULL;
00842 
00843 AllocVar(page);
00844 page->url = cloneString(url);
00845 page->fullText = fullText;
00846 page->status = status;
00847 page->header = htmlHeaderRead(&s, &page->cookies);
00848 contentType = hashFindVal(page->header, "Content-Type:");
00849 if (contentType == NULL)        
00850     {
00851     warn("No contentType, assuming text/html");
00852     contentType = cloneString("text/html");
00853     hashAdd(page->header, "Content-Type:", contentType);
00854     }
00855 page->htmlText = fullText + (s - dupe);
00856 if (startsWith("text/html", contentType))
00857     {
00858     page->tags = htmlTagScan(page->htmlText, s);
00859     page->forms = htmlParseForms(page, page->tags, NULL);
00860     }
00861 freez(&dupe);
00862 return page;
00863 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlPage* htmlPageParseNoHead ( char *  url,
char *  htmlText 
) [read]

Definition at line 865 of file htmlPage.c.

References AllocVar, cloneString(), htmlPage::forms, freez(), htmlPage::fullText, htmlParseForms(), htmlTagScan(), htmlPage::htmlText, htmlPage::tags, and htmlPage::url.

Referenced by htmlPageGet().

00867 {
00868 char *dupe = cloneString(htmlText);
00869 struct htmlPage *page;
00870 AllocVar(page);
00871 page->url = cloneString(url);
00872 page->fullText = page->htmlText = htmlText;
00873 page->tags = htmlTagScan(page->htmlText, dupe);
00874 page->forms = htmlParseForms(page, page->tags, NULL);
00875 freez(&dupe);
00876 return page;
00877 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct htmlPage* htmlPageParseOk ( char *  url,
char *  fullText 
) [read]

Definition at line 879 of file htmlPage.c.

References errAbort(), htmlPageParse(), noWarnAbort(), htmlStatus::status, and htmlPage::status.

00881 {
00882 struct htmlPage *page = htmlPageParse(url, fullText);
00883 if (page == NULL)
00884    noWarnAbort();
00885 if (page->status->status != 200)
00886    errAbort("%s returned with status code %d", url, page->status->status);
00887 return page;
00888 }

Here is the call graph for this function:

struct slName* htmlPageScanAttribute ( struct htmlPage page,
char *  tagName,
char *  attribute 
) [read]

Definition at line 1403 of file htmlPage.c.

References htmlTag::attributes, htmlAttribute::name, htmlTag::name, htmlAttribute::next, htmlTag::next, sameWord, slAddHead, slNameNew, slReverse(), htmlPage::tags, and htmlAttribute::val.

Referenced by htmlPageLinks().

01407 {
01408 struct htmlTag *tag;
01409 struct htmlAttribute *att;
01410 struct slName *list = NULL, *el;
01411 
01412 for (tag = page->tags; tag != NULL; tag = tag->next)
01413     {
01414     if (tagName == NULL || sameWord(tagName, tag->name))
01415         {
01416         for (att = tag->attributes; att != NULL; att = att->next)
01417             {
01418             if (sameWord(attribute, att->name))
01419                 {
01420                 el = slNameNew(att->val);
01421                 slAddHead(&list, el);
01422                 }
01423             }
01424         }
01425     }
01426 slReverse(&list);
01427 return list;
01428 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlPageSetVar ( struct htmlPage page,
struct htmlForm form,
char *  name,
char *  val 
)

Definition at line 1036 of file htmlPage.c.

References errAbort(), htmlPage::forms, and htmlFormVarSet().

01038 {
01039 if (page == NULL)
01040     errAbort("Null page passed to htmlPageSetVar");
01041 if (form == NULL)
01042     form = page->forms;
01043 if (form == NULL)
01044     errAbort("Null form in htmlPageSetVar");
01045 htmlFormVarSet(form, name, val);
01046 }

Here is the call graph for this function:

void htmlPageValidateOrAbort ( struct htmlPage page  ) 

Definition at line 1764 of file htmlPage.c.

References ArraySize, checkExactlyOne(), errAbort(), FALSE, hashFindVal(), htmlPage::header, htmlTag::name, htmlTag::next, sameWord, startsWith(), htmlPage::tags, touppers(), TRUE, validateBody(), validateCgiUrls(), validateNestingTags(), and warn().

Referenced by qaPageFromForm(), and qaPageGet().

01766 {
01767 struct htmlTag *tag;
01768 boolean gotTitle = FALSE;
01769 char *contentType = NULL;
01770 
01771 if (page == NULL)
01772     errAbort("Can't validate NULL page");
01773 if (page->header != NULL)
01774     contentType = hashFindVal(page->header, "Content-Type:");
01775 if (contentType == NULL || startsWith("text/html", contentType))
01776     {
01777     /* To simplify things upper case all tag names. */
01778     for (tag = page->tags; tag != NULL; tag = tag->next)
01779         touppers(tag->name);
01780 
01781     checkExactlyOne(page->tags, "BODY");
01782 
01783     /* Validate header, and make a suggestion or two */
01784     if ((tag = page->tags) == NULL)
01785         errAbort("No tags");
01786     if (!sameWord(tag->name, "HTML"))
01787         errAbort("Doesn't start with <HTML> tag");
01788     tag = tag->next;
01789     if (tag == NULL || !sameWord(tag->name, "HEAD"))
01790         warn("<HEAD> tag does not follow <HTML> tag");
01791     else
01792         {
01793         for (;;)
01794             {
01795             tag = tag->next;
01796             if (tag == NULL)
01797                 errAbort("Missing </HEAD>");
01798             if (sameWord(tag->name, "TITLE"))
01799                 gotTitle = TRUE;
01800             if (sameWord(tag->name, "/HEAD"))
01801                 break;
01802             }
01803         if (!gotTitle)
01804             warn("No title in <HEAD>");
01805         validateNestingTags(page, page->tags, tag, headNesters, ArraySize(headNesters));
01806         tag = tag->next;
01807         }
01808     if (tag == NULL || !sameWord(tag->name, "BODY"))
01809         errAbort("<BODY> tag does not follow <HTML> tag");
01810     tag = validateBody(page, tag->next);
01811     if (tag == NULL || !sameWord(tag->name, "/HTML"))
01812         errAbort("Missing </HTML>");
01813     validateCgiUrls(page);
01814     }
01815 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct htmlForm* htmlParseForms ( struct htmlPage page,
struct htmlTag startTag,
struct htmlTag endTag 
) [static, read]

Definition at line 793 of file htmlPage.c.

References AllocVar, htmlTagAttributeNeeded(), htmlTagAttributeVal(), htmlTag::name, htmlTag::next, sameWord, slAddHead, and tagWarn().

Referenced by htmlPageParse(), and htmlPageParseNoHead().

00796 {
00797 struct htmlForm *formList = NULL, *form = NULL;
00798 struct htmlTag *tag;
00799 for (tag = startTag; tag != endTag; tag = tag->next)
00800     {
00801     if (sameWord(tag->name, "FORM"))
00802         {
00803         if (form != NULL)
00804             tagWarn(page, tag, "FORM inside of FORM");
00805         AllocVar(form);
00806         form->startTag = tag;
00807         slAddHead(&formList, form);
00808         form->name = htmlTagAttributeVal(page, tag, "name", "n/a");
00809         form->action = htmlTagAttributeNeeded(page, tag, "action");
00810         form->method = htmlTagAttributeVal(page, tag, "method", "GET");
00811         }
00812     else if (sameWord(tag->name, "/FORM"))
00813         {
00814         if (form == NULL)
00815             tagWarn(page, tag, "/FORM outside of FORM");
00816         else
00817             {
00818             form->endTag = tag->next;
00819             form = NULL;
00820             }
00821         }
00822     }
00823 slReverse(&formList);
00824 for (form = formList; form != NULL; form = form->next)
00825     {
00826     form->vars = formParseVars(page, form);
00827     }
00828 return formList;
00829 }

Here is the call graph for this function:

Here is the caller graph for this function:

char* htmlSlurpWithCookies ( char *  url,
struct htmlCookie cookies 
)

Definition at line 890 of file htmlPage.c.

References cookieOutput(), dyStringAppend(), dyStringCannibalize(), dyStringFree, dyStringNew, FALSE, netOpenHttpExt(), netSlurpFile(), dyString::string, and dyString::stringSize.

Referenced by htmlPageGetWithCookies().

00895 {
00896 struct dyString *dyHeader = dyStringNew(0);
00897 struct dyString *dyText;
00898 int sd;
00899 
00900 cookieOutput(dyHeader, cookies);
00901 dyStringAppend(dyHeader, "\r\n");
00902 sd = netOpenHttpExt(url, "GET", FALSE);
00903 write(sd, dyHeader->string, dyHeader->stringSize);
00904 dyText = netSlurpFile(sd);
00905 close(sd);
00906 dyStringFree(&dyHeader);
00907 return dyStringCannibalize(&dyText);
00908 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlStatusFree ( struct htmlStatus **  pStatus  ) 

Definition at line 28 of file htmlPage.c.

References freeMem(), freez(), and htmlStatus::status.

Referenced by htmlPageFree(), and htmlStatusFreeList().

00030 {
00031 struct htmlStatus *status = *pStatus;
00032 if (status != NULL)
00033     {
00034     freeMem(status->version);
00035     freez(pStatus);
00036     }
00037 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlStatusFreeList ( struct htmlStatus **  pList  ) 

Definition at line 39 of file htmlPage.c.

References htmlStatusFree(), and htmlStatus::next.

00041 {
00042 struct htmlStatus *el, *next;
00043 
00044 for (el = *pList; el != NULL; el = next)
00045     {
00046     next = el->next;
00047     htmlStatusFree(&el);
00048     }
00049 *pList = NULL;
00050 }

Here is the call graph for this function:

struct htmlStatus* htmlStatusParse ( char **  pText  )  [read]

Definition at line 299 of file htmlPage.c.

References AllocVar, cloneStringZ(), skipLeadingSpaces(), skipToSpaces(), htmlStatus::status, and warn().

Referenced by htmlPageParse().

00302 {
00303 char *text = *pText;
00304 char *end = strchr(text, '\n');
00305 struct htmlStatus *status;
00306 if (end != NULL)
00307    *pText = end+1;
00308 else
00309    *pText = text + strlen(text);
00310 end = skipToSpaces(text);
00311 if (end == NULL)
00312     {
00313     warn("Short status line.");
00314     return NULL;
00315     }
00316 AllocVar(status);
00317 status->version = cloneStringZ(text, end-text);
00318 end = skipLeadingSpaces(end);
00319 if (!isdigit(end[0]))
00320     {
00321     warn("Not a number in status field");
00322     return NULL;
00323     }
00324 status->status = atoi(end);
00325 return status;
00326 }

Here is the call graph for this function:

Here is the caller graph for this function:

char* htmlTagAttributeNeeded ( struct htmlPage page,
struct htmlTag tag,
char *  name 
)

Definition at line 465 of file htmlPage.c.

References htmlTagAttributeVal(), tagWarn(), and htmlAttribute::val.

Referenced by formParseVars(), and htmlParseForms().

00468 {
00469 char *val = htmlTagAttributeVal(page, tag, name, NULL);
00470 if (val == NULL)
00471     {
00472     tagWarn(page, tag, "Missing %s attribute", name);
00473     val = "n/a";
00474     }
00475 return val;
00476 }

Here is the call graph for this function:

Here is the caller graph for this function:

char* htmlTagAttributeVal ( struct htmlPage page,
struct htmlTag tag,
char *  name,
char *  defaultVal 
)

Definition at line 455 of file htmlPage.c.

References htmlTag::attributes, htmlAttributeFindVal(), and htmlAttribute::val.

Referenced by formParseVars(), htmlParseForms(), and htmlTagAttributeNeeded().

00458 {
00459 char *val = htmlAttributeFindVal(tag->attributes, name);
00460 if (val == NULL)
00461     val = defaultVal;
00462 return val;
00463 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlTagFree ( struct htmlTag **  pTag  ) 

Definition at line 149 of file htmlPage.c.

References htmlTag::attributes, freeMem(), freez(), htmlAttributeFreeList(), and htmlTag::name.

Referenced by htmlTagFreeList().

00151 {
00152 struct htmlTag *tag = *pTag;
00153 if (tag != NULL)
00154     {
00155     htmlAttributeFreeList(&tag->attributes);
00156     freeMem(tag->name);
00157     freez(pTag);
00158     }
00159 }

Here is the call graph for this function:

Here is the caller graph for this function:

void htmlTagFreeList ( struct htmlTag **  pList  ) 

Definition at line 161 of file htmlPage.c.

References htmlTagFree(), and htmlTag::next.

Referenced by htmlPageFree().

00163 {
00164 struct htmlTag *el, *next;
00165 
00166 for (el = *pList; el != NULL; el = next)
00167     {
00168     next = el->next;
00169     htmlTagFree(&el);
00170     }
00171 *pList = NULL;
00172 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct htmlTag* htmlTagScan ( char *  html,
char *  dupe 
) [static, read]

Definition at line 478 of file htmlPage.c.

References AllocVar, cloneString(), eraseTrailingSpaces(), FALSE, htmlAttribute::name, name, parseQuotedString(), skipLeadingSpaces(), slAddHead, slAddTail(), slReverse(), stringIn, TRUE, htmlAttribute::val, and warn().

Referenced by htmlPageParse(), and htmlPageParseNoHead().

00483 {
00484 char *s = dupe, c, *e, *tagName;
00485 struct htmlTag *tagList = NULL, *tag;
00486 struct htmlAttribute *att;
00487 int pos;
00488 
00489 for (;;)
00490     {
00491     c = *s++;
00492     if (c == 0)
00493         break;
00494     if (c == '<')
00495         {
00496         if (*s == '!')  /* HTML comment. */
00497             {
00498             s += 1;
00499             if (s[0] == '-' && s[1] == '-')
00500                 s = stringIn("-->", s);
00501             else
00502                 s = strchr(s, '>');
00503             if (s == NULL)
00504                 {
00505                 warn("End of file in comment");
00506                 break;
00507                 }
00508             }
00509         else
00510             {
00511             /* Grab first word into tagName. */
00512             e = s;
00513             for (;;)
00514                 {
00515                 c = *e;
00516                 if (c == '>' || c == 0 || isspace(c))
00517                     break;
00518                 e += 1;
00519                 }
00520             if (c != 0)
00521                *e++ = 0;
00522             tagName = s;
00523             s = e;
00524             
00525             /* Allocate tag, fill in name, and stick it on list. */
00526             AllocVar(tag);
00527             tag->name = cloneString(tagName);
00528             slAddHead(&tagList, tag);
00529             pos = tagName - dupe - 1;
00530             tag->start = html+pos;
00531 
00532             /* If already got end tag (or EOF) stop processing tag. */
00533             if (c == '>' || c == 0)
00534                 {
00535                 tag->end = html + (e - dupe);
00536                 continue;
00537                 }
00538 
00539             /* Process name/value pairs until get end tag. */
00540             for (;;)
00541                 {
00542                 char *name, *val;
00543                 boolean gotEnd = FALSE;
00544 
00545                 /* Check for end tag. */
00546                 s = skipLeadingSpaces(s);
00547                 if (s[0] == '>' || s[0] == 0)
00548                     {
00549                     tag->end = html + (s - dupe);
00550                     if (s[0] == '>')
00551                         tag->end += 1;
00552                     break;
00553                     }
00554 
00555                 /* Get name - everything up to equals. */
00556                 e = s;
00557                 for (;;)
00558                     {
00559                     c = *e;
00560                     if (c == '=')
00561                         break;
00562                     else if (c == '>')
00563                         break;
00564                     else if (c == 0)
00565                         break;
00566                     else if (isspace(c))
00567                         break;
00568                     e += 1;
00569                     }
00570                 if (c == 0)
00571                     {
00572                     warn("End of file in tag");
00573                     break;
00574                     }
00575                 name = s;
00576                 *e++ = 0;
00577                 eraseTrailingSpaces(name);
00578                 if (c == '>')
00579                     {
00580                     val = "";
00581                     gotEnd = TRUE;
00582                     tag->end = html + (e - dupe);
00583                     }
00584                 else if (isspace(c))
00585                     {
00586                     val = "";
00587                     }
00588                 else
00589                     {
00590                     val = e = skipLeadingSpaces(e);
00591                     if (e[0] == '"')
00592                         {
00593                         if (!parseQuotedString(val, val, &e))
00594                             break;
00595                         }
00596                     else
00597                         {
00598                         for (;;)
00599                             {
00600                             c = *e;
00601                             if (c == '>')
00602                                 {
00603                                 gotEnd = TRUE;
00604                                 *e++ = 0;
00605                                 tag->end = html + (e - dupe);
00606                                 break;
00607                                 }
00608                             else if (isspace(c))
00609                                 {
00610                                 *e++ = 0;
00611                                 break;
00612                                 }
00613                             else if (c == 0)
00614                                 break;
00615                             ++e;
00616                             }
00617                         }
00618                     }
00619                 AllocVar(att);
00620                 att->name = cloneString(name);
00621                 att->val = cloneString(val);
00622                 slAddTail(&tag->attributes, att);
00623                 s = e;
00624                 if (gotEnd)
00625                     break;
00626                 }
00627             }
00628         }
00629     }
00630 slReverse(&tagList);
00631 return tagList;
00632 }

Here is the call graph for this function:

Here is the caller graph for this function:

static boolean isMimeEncoded ( struct htmlForm form  )  [static]

Definition at line 1252 of file htmlPage.c.

References htmlTag::attributes, FALSE, htmlAttribute::name, htmlAttribute::next, sameWord, htmlForm::startTag, TRUE, and htmlAttribute::val.

Referenced by htmlFormCgiVars().

01254 {
01255 struct htmlAttribute *a;
01256 for(a = form->startTag->attributes;a;a = a->next)
01257     if (sameWord(a->name,"ENCTYPE") && sameWord(a->val,"multipart/form-data"))
01258         return TRUE;
01259 return FALSE;
01260 }

Here is the caller graph for this function:

static boolean isMixableInputType ( char *  type  )  [static]

Definition at line 662 of file htmlPage.c.

References sameWord.

Referenced by formParseVars().

00665 {
00666 return sameWord(type, "BUTTON") || sameWord(type, "SUBMIT") 
00667         || sameWord(type, "IMAGE");
00668 }

Here is the caller graph for this function:

static struct htmlCookie* parseCookie ( char *  s  )  [static, read]

Definition at line 365 of file htmlPage.c.

References AllocVar, cloneString(), cookieParseNameValuePair(), htmlCookie::domain, htmlCookie::expires, htmlCookie::name, name, htmlCookie::path, sameString, htmlCookie::secure, skipLeadingSpaces(), TRUE, htmlCookie::value, and warn().

Referenced by htmlHeaderRead().

00367 {
00368 char *e, *name, *val;
00369 struct htmlCookie *cookie;
00370 
00371 /* Grab up to semicolon, which is the cookie name/value pair. */
00372 e = strchr(s, ';');
00373 if (e == NULL)
00374     {
00375     warn("Missing ';' in cookie");
00376     return NULL;
00377     }
00378 *e++ = 0;
00379 
00380 /* Allocate cookie and fill out name/value pair. */
00381 AllocVar(cookie);
00382 cookieParseNameValuePair(s, &name, &val);
00383 cookie->name = cloneString(name);
00384 cookie->value = cloneString(val);
00385 
00386 /* Loop through to grab the other info - domain and so forth. */
00387 s = e;
00388 for (;;)
00389     {
00390     /* Find next semicolon and zero-terminate it. */
00391     s = skipLeadingSpaces(s);
00392     e = strchr(s, ';');
00393     if (e == NULL)
00394         break;
00395     *e++ = 0;
00396 
00397     /* Parse out name/value pairs and save it away if it's one we know about. */
00398     cookieParseNameValuePair(s, &name, &val);
00399     if (sameString(name, "domain"))
00400         cookie->domain = cloneString(val);
00401     else if (sameString(name, "path"))
00402         cookie->path = cloneString(val);
00403     else if (sameString(name, "expires"))
00404         cookie->expires = cloneString(val);
00405     else if (sameString(name, "secure"))
00406         cookie->secure = TRUE;
00407 
00408     s = e;
00409     }
00410 return cookie;
00411 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void tagAbort ( struct htmlPage page,
struct htmlTag tag,
char *  format,
  ... 
) [static]

Definition at line 289 of file htmlPage.c.

References noWarnAbort(), and tagVaWarn().

Referenced by checkNest(), checkTagIsInside(), and validateTables().

00291 {
00292 va_list args;
00293 va_start(args, format);
00294 tagVaWarn(page, tag, format, args);
00295 va_end(args);
00296 noWarnAbort();
00297 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void tagVaWarn ( struct htmlPage page,
struct htmlTag tag,
char *  format,
va_list  args 
) [static]

Definition at line 268 of file htmlPage.c.

References findLineNumber(), htmlPage::htmlText, htmlTag::start, htmlPage::url, vaWarn(), and warn().

Referenced by tagAbort(), and tagWarn().

00271 {
00272 char context[80];
00273 strncpy(context, tag->start, sizeof(context));
00274 context[sizeof(context)-1] = 0;
00275 warn("Error near line %d of %s:\n %s", findLineNumber(page->htmlText, tag->start), 
00276         page->url, context);
00277 vaWarn(format, args);
00278 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void tagWarn ( struct htmlPage page,
struct htmlTag tag,
char *  format,
  ... 
) [static]

Definition at line 280 of file htmlPage.c.

References tagVaWarn().

Referenced by findOrMakeVar(), formParseVars(), htmlParseForms(), and htmlTagAttributeNeeded().

00282 {
00283 va_list args;
00284 va_start(args, format);
00285 tagVaWarn(page, tag, format, args);
00286 va_end(args);
00287 }

Here is the call graph for this function:

Here is the caller graph for this function:

static char* urlOkChars (  )  [static]

Definition at line 1673 of file htmlPage.c.

References AllocArray.

Referenced by validateCgiUrl().

01677 {
01678 char *okChars;
01679 int c;
01680 AllocArray(okChars, 256);
01681 for (c=0; c<256; ++c)
01682     if (isalnum(c))
01683         okChars[c] = 1;
01684 /* This list is a little more inclusive than W3's. */
01685 okChars['='] = 1;
01686 okChars['-'] = 1;
01687 okChars['/'] = 1;
01688 okChars['%'] = 1;
01689 okChars['.'] = 1;
01690 okChars[';'] = 1;
01691 okChars[':'] = 1;
01692 okChars['_'] = 1;
01693 okChars['&'] = 1;
01694 okChars['+'] = 1;
01695 return okChars;
01696 }

Here is the caller graph for this function:

static struct htmlTag* validateBody ( struct htmlPage page,
struct htmlTag startTag 
) [static, read]

Definition at line 1642 of file htmlPage.c.

References htmlTag::name, htmlTag::next, and sameWord.

Referenced by htmlPageValidateOrAbort().

01645 {
01646 struct htmlTag *tag, *endTag = NULL;
01647 
01648 /* First search for end tag. */
01649 for (tag = startTag; tag != NULL; tag = tag->next)
01650     {
01651     if (sameWord(tag->name, "/BODY"))
01652         {
01653         endTag = tag;
01654         break;
01655         }
01656     }
01657 if (endTag == NULL)
01658     errAbort("Missing </BODY>");
01659 validateTables(page, startTag, endTag);
01660 checkTagIsInside(page, "DIR MENU OL UL", "LI", startTag, endTag);
01661 checkTagIsInside(page, "DL", "DD DT", startTag, endTag);
01662 checkTagIsInside(page, "COLGROUP TABLE", "COL", startTag, endTag);
01663 checkTagIsInside(page, "MAP", "AREA", startTag, endTag);
01664 checkTagIsInside(page, "FORM", 
01665         "INPUT BUTTON /BUTTON OPTION SELECT /SELECT TEXTAREA /TEXTAREA"
01666         "FIELDSET /FIELDSET"
01667         , 
01668         startTag, endTag);
01669 validateNestingTags(page, startTag, endTag, bodyNesters, ArraySize(bodyNesters));
01670 return endTag->next;
01671 }

Here is the caller graph for this function:

static void validateCgiUrl ( char *  url  )  [static]

Definition at line 1698 of file htmlPage.c.

References errAbort(), startsWith(), UBYTE, and urlOkChars().

Referenced by validateCgiUrls().

01700 {
01701 if (startsWith("http:", url) || startsWith("https:", url))
01702     {
01703     static char *okChars = NULL;
01704     UBYTE c, *s;
01705     if (okChars == NULL)
01706         okChars = urlOkChars();
01707     url = strchr(url, '?');
01708     if (url != NULL)
01709         {
01710         s = (UBYTE*)url+1;
01711         while ((c = *s++) != 0)
01712             {
01713             if (!okChars[c])
01714                 {
01715                 errAbort("Character %c not allowed in URL %s", c, url);
01716                 }
01717             }
01718         }
01719     }
01720 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void validateCgiUrls ( struct htmlPage page  )  [static]

Definition at line 1722 of file htmlPage.c.

References htmlForm::action, htmlPage::forms, htmlPageLinks(), slName::next, htmlForm::next, slFreeList(), and validateCgiUrl().

Referenced by htmlPageValidateOrAbort().

01724 {
01725 struct htmlForm *form;
01726 struct slName *linkList = htmlPageLinks(page), *link;
01727 
01728 for (form = page->forms; form != NULL; form = form->next)
01729     validateCgiUrl(form->action);
01730 for (link = linkList; link != NULL; link = link->next)
01731     validateCgiUrl(link->name);
01732 slFreeList(&linkList);
01733 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void validateNestingTags ( struct htmlPage page,
struct htmlTag startTag,
struct htmlTag endTag,
char *  nesters[],
int  nesterCount 
) [static]

Definition at line 1617 of file htmlPage.c.

References checkNest().

Referenced by htmlPageValidateOrAbort().

01621 {
01622 int i;
01623 for (i=0; i<nesterCount; ++i)
01624     checkNest(page, nesters[i], startTag, endTag);
01625 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void validateTables ( struct htmlPage page,
struct htmlTag startTag,
struct htmlTag endTag 
) [static]

Definition at line 1452 of file htmlPage.c.

References AllocVar, FALSE, freez(), htmlTableRow::inTd, htmlTag::name, htmlTable::next, htmlTag::next, htmlTable::row, sameWord, slAddHead, tagAbort(), htmlTableRow::tdCount, and TRUE.

01456 {
01457 struct htmlTable *tableStack = NULL, *table;
01458 struct htmlTableRow *row;
01459 struct htmlTag *tag;
01460 
01461 for (tag = startTag; tag != endTag; tag = tag->next)
01462     {
01463     if (sameWord(tag->name, "TABLE"))
01464         {
01465         if (tableStack != NULL)
01466             {
01467             if (tableStack->row == NULL || !tableStack->row->inTd)
01468             tagAbort(page, tag, "TABLE inside of another table, but not inside of <TR><TD>\n");
01469             }
01470         AllocVar(table);
01471         slAddHead(&tableStack, table);
01472         }
01473     else if (sameWord(tag->name, "/TABLE"))
01474         {
01475         if ((table = tableStack) == NULL)
01476             tagAbort(page, tag, "Extra </TABLE> tag");
01477         if (table->rowCount == 0)
01478             tagAbort(page, tag, "<TABLE> with no <TR>'s");
01479         if (table->row != NULL)
01480             tagAbort(page, tag, "</TABLE> inside of a row");
01481         tableStack = table->next;
01482         freez(&table);
01483         }
01484     else if (sameWord(tag->name, "TR"))
01485         {
01486         if ((table = tableStack) == NULL)
01487             tagAbort(page, tag, "<TR> outside of TABLE");
01488         if (table->row != NULL)
01489             tagAbort(page, tag, "<TR>...<TR> with no </TR> in between");
01490         AllocVar(table->row);
01491         table->rowCount += 1;
01492         }
01493     else if (sameWord(tag->name, "/TR"))
01494         {
01495         if ((table = tableStack) == NULL)
01496             tagAbort(page, tag, "</TR> outside of TABLE");
01497         if (table->row == NULL)
01498             tagAbort(page, tag, "</TR> with no <TR>");
01499 #ifdef LEGAL_ACTUALLY
01500         if (table->row->inTd)
01501             {
01502             tagAbort(page, tag, "</TR> while <TD> is open");
01503             }
01504 #endif /* LEGAL_ACTUALLY */
01505         if (table->row->tdCount == 0)
01506             tagAbort(page, tag, "Empty row in <TABLE>");
01507         freez(&table->row);
01508         }
01509     else if (sameWord(tag->name, "TD") || sameWord(tag->name, "TH"))
01510         {
01511         if ((table = tableStack) == NULL)
01512             tagAbort(page, tag, "<%s> outside of <TABLE>", tag->name);
01513         if ((row = table->row) == NULL)
01514             tagAbort(page, tag, "<%s> outside of <TR>", tag->name);
01515 #ifdef LEGAL_ACTUALLY
01516         if (row->inTd)
01517             {
01518             tagAbort(page, tag, "<%s>...<%s> with no </%s> in between", 
01519                 tag->name, tag->name, tag->name);
01520             }
01521 #endif /* LEGAL_ACTUALLY */
01522         row->inTd = TRUE;
01523         row->tdCount += 1;
01524         }
01525     else if (sameWord(tag->name, "/TD") || sameWord(tag->name, "/TH"))
01526         {
01527         if ((table = tableStack) == NULL)
01528             tagAbort(page, tag, "<%s> outside of <TABLE>", tag->name);
01529         if ((row = table->row) == NULL)
01530             tagAbort(page, tag, "<%s> outside of <TR>", tag->name);
01531         if (!row->inTd)
01532             tagAbort(page, tag, "<%s> with no <%s>", tag->name, tag->name+1);
01533         row->inTd = FALSE;
01534         }
01535     }
01536 if (tableStack != NULL)
01537     tagAbort(page, tag, "Missing </TABLE>");
01538 }

Here is the call graph for this function:


Variable Documentation

char* bodyNesters[] [static]

Initial value:

 

{
    "ADDRESS", "DIV", "H1", "H2", "H3", "H4", "H5", "H6",
    "ACRONYM", "BLOCKQUOTE", "CITE", "CODE", "DEL", "DFN"
    "DIR", "DL", "MENU", "OL", "UL", "CAPTION", "TABLE", 
    "A", "MAP", "OBJECT", "FORM"
}

Definition at line 1627 of file htmlPage.c.

char* headNesters[] [static]

Initial value:


{
    "TITLE",
}

Definition at line 1636 of file htmlPage.c.

char const rcsid[] = "$Id: htmlPage.c,v 1.32 2006/07/29 00:17:28 galt Exp $" [static]

Definition at line 26 of file htmlPage.c.


Generated on Tue Dec 25 19:55:45 2007 for blat by  doxygen 1.5.2