You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2316 lines
83 KiB

/* attrs.c -- recognize HTML attributes
(c) 1998-2009 (W3C) MIT, ERCIM, Keio University
See tidy.h for the copyright notice.
*/
#include "tidy-int.h"
#include "attrs.h"
#include "message.h"
#include "tmbstr.h"
#include "utf8.h"
/*
Bind attribute types to procedures to check values.
You can add new procedures for better validation
and each procedure has access to the node in which
the attribute occurred as well as the attribute name
and its value.
By default, attributes are checked without regard
to the element they are found on. You have the choice
of making the procedure test which element is involved
or in writing methods for each element which controls
exactly how the attributes of that element are checked.
This latter approach is best for detecting the absence
of required attributes.
*/
static AttrCheck CheckAction;
static AttrCheck CheckScript;
static AttrCheck CheckName;
static AttrCheck CheckId;
static AttrCheck CheckAlign;
static AttrCheck CheckValign;
static AttrCheck CheckBool;
static AttrCheck CheckLength;
static AttrCheck CheckTarget;
static AttrCheck CheckFsubmit;
static AttrCheck CheckClear;
static AttrCheck CheckShape;
static AttrCheck CheckNumber;
static AttrCheck CheckScope;
static AttrCheck CheckColor;
static AttrCheck CheckVType;
static AttrCheck CheckScroll;
static AttrCheck CheckTextDir;
static AttrCheck CheckLang;
static AttrCheck CheckType;
static AttrCheck CheckRDFaSafeCURIE;
static AttrCheck CheckRDFaTerm;
static AttrCheck CheckRDFaPrefix;
#define CH_PCDATA NULL
#define CH_CHARSET NULL
#define CH_TYPE CheckType
#define CH_XTYPE NULL
#define CH_CHARACTER NULL
#define CH_URLS NULL
#define CH_URL TY_(CheckUrl)
#define CH_SCRIPT CheckScript
#define CH_ALIGN CheckAlign
#define CH_VALIGN CheckValign
#define CH_COLOR CheckColor
#define CH_CLEAR CheckClear
#define CH_BORDER CheckBool /* kludge */
#define CH_LANG CheckLang
#define CH_BOOL CheckBool
#define CH_COLS NULL
#define CH_NUMBER CheckNumber
#define CH_LENGTH CheckLength
#define CH_COORDS NULL
#define CH_DATE NULL
#define CH_TEXTDIR CheckTextDir
#define CH_IDREFS NULL
#define CH_IDREF NULL
#define CH_IDDEF CheckId
#define CH_NAME CheckName
#define CH_TFRAME NULL
#define CH_FBORDER NULL
#define CH_MEDIA NULL
#define CH_FSUBMIT CheckFsubmit
#define CH_LINKTYPES NULL
#define CH_TRULES NULL
#define CH_SCOPE CheckScope
#define CH_SHAPE CheckShape
#define CH_SCROLL CheckScroll
#define CH_TARGET CheckTarget
#define CH_VTYPE CheckVType
#define CH_ACTION CheckAction
#define CH_RDFAPREFIX CheckRDFaPrefix
#define CH_RDFASCURIE CheckRDFaSafeCURIE
#define CH_RDFASCURIES CheckRDFaSafeCURIE
#define CH_RDFATERM CheckRDFaTerm
#define CH_RDFATERMS CheckRDFaTerm
static const Attribute attribute_defs [] =
{
5 years ago
{ TidyAttr_UNKNOWN, "unknown!", NULL },
{ TidyAttr_ABBR, "abbr", CH_PCDATA },
{ TidyAttr_ACCEPT, "accept", CH_XTYPE },
{ TidyAttr_ACCEPT_CHARSET, "accept-charset", CH_CHARSET },
{ TidyAttr_ACCESSKEY, "accesskey", CH_CHARACTER },
{ TidyAttr_ACTION, "action", CH_ACTION },
{ TidyAttr_ADD_DATE, "add_date", CH_PCDATA }, /* A */
{ TidyAttr_ALIGN, "align", CH_ALIGN }, /* varies by element */
5 years ago
{ TidyAttr_ALINK, "alink", CH_COLOR },
{ TidyAttr_ALLOWFULLSCREEN, "allowfullscreen", CH_BOOL },
{ TidyAttr_ALT, "alt", CH_PCDATA }, /* nowrap */
{ TidyAttr_ARCHIVE, "archive", CH_URLS }, /* space or comma separated list */
5 years ago
{ TidyAttr_AXIS, "axis", CH_PCDATA },
{ TidyAttr_BACKGROUND, "background", CH_URL },
{ TidyAttr_BGCOLOR, "bgcolor", CH_COLOR },
{ TidyAttr_BGPROPERTIES, "bgproperties", CH_PCDATA }, /* BODY "fixed" fixes background */
{ TidyAttr_BORDER, "border", CH_BORDER }, /* like LENGTH + "border" */
{ TidyAttr_BORDERCOLOR, "bordercolor", CH_COLOR }, /* used on TABLE */
{ TidyAttr_BOTTOMMARGIN, "bottommargin", CH_NUMBER }, /* used on BODY */
{ TidyAttr_CELLPADDING, "cellpadding", CH_LENGTH }, /* % or pixel values */
5 years ago
{ TidyAttr_CELLSPACING, "cellspacing", CH_LENGTH },
{ TidyAttr_CHAR, "char", CH_CHARACTER },
{ TidyAttr_CHAROFF, "charoff", CH_LENGTH },
{ TidyAttr_CHARSET, "charset", CH_CHARSET },
{ TidyAttr_CHECKED, "checked", CH_BOOL }, /* i.e. "checked" or absent */
5 years ago
{ TidyAttr_CITE, "cite", CH_URL },
{ TidyAttr_CLASS, "class", CH_PCDATA },
{ TidyAttr_CLASSID, "classid", CH_URL },
{ TidyAttr_CLEAR, "clear", CH_CLEAR }, /* BR: left, right, all */
{ TidyAttr_CODE, "code", CH_PCDATA }, /* APPLET */
{ TidyAttr_CODEBASE, "codebase", CH_URL }, /* OBJECT */
{ TidyAttr_CODETYPE, "codetype", CH_XTYPE }, /* OBJECT */
{ TidyAttr_COLOR, "color", CH_COLOR }, /* BASEFONT, FONT */
{ TidyAttr_COLS, "cols", CH_COLS }, /* TABLE & FRAMESET */
5 years ago
{ TidyAttr_COLSPAN, "colspan", CH_NUMBER },
{ TidyAttr_COMPACT, "compact", CH_BOOL }, /* lists */
5 years ago
{ TidyAttr_CONTENT, "content", CH_PCDATA },
{ TidyAttr_COORDS, "coords", CH_COORDS }, /* AREA, A */
{ TidyAttr_DATA, "data", CH_URL }, /* OBJECT */
{ TidyAttr_DATAFLD, "datafld", CH_PCDATA }, /* used on DIV, IMG */
{ TidyAttr_DATAFORMATAS, "dataformatas", CH_PCDATA }, /* used on DIV, IMG */
{ TidyAttr_DATAPAGESIZE, "datapagesize", CH_NUMBER }, /* used on DIV, IMG */
{ TidyAttr_DATASRC, "datasrc", CH_URL }, /* used on TABLE */
{ TidyAttr_DATETIME, "datetime", CH_DATE }, /* INS, DEL */
{ TidyAttr_DECLARE, "declare", CH_BOOL }, /* OBJECT */
{ TidyAttr_DEFER, "defer", CH_BOOL }, /* SCRIPT */
{ TidyAttr_DIR, "dir", CH_TEXTDIR }, /* ltr or rtl */
{ TidyAttr_DISABLED, "disabled", CH_BOOL }, /* form fields */
{ TidyAttr_ENCODING, "encoding", CH_PCDATA }, /* <?xml?> */
{ TidyAttr_ENCTYPE, "enctype", CH_XTYPE }, /* FORM */
{ TidyAttr_FACE, "face", CH_PCDATA }, /* BASEFONT, FONT */
{ TidyAttr_FOR, "for", CH_IDREF }, /* LABEL */
{ TidyAttr_FRAME, "frame", CH_TFRAME }, /* TABLE */
{ TidyAttr_FRAMEBORDER, "frameborder", CH_FBORDER }, /* 0 or 1 */
5 years ago
{ TidyAttr_FRAMESPACING, "framespacing", CH_NUMBER },
{ TidyAttr_GRIDX, "gridx", CH_NUMBER }, /* TABLE Adobe golive*/
{ TidyAttr_GRIDY, "gridy", CH_NUMBER }, /* TABLE Adobe golive */
{ TidyAttr_HEADERS, "headers", CH_IDREFS }, /* table cells */
{ TidyAttr_HEIGHT, "height", CH_LENGTH }, /* pixels only for TH/TD */
{ TidyAttr_HREF, "href", CH_URL }, /* A, AREA, LINK and BASE */
{ TidyAttr_HREFLANG, "hreflang", CH_LANG }, /* A, LINK */
{ TidyAttr_HSPACE, "hspace", CH_NUMBER }, /* APPLET, IMG, OBJECT */
{ TidyAttr_HTTP_EQUIV, "http-equiv", CH_PCDATA }, /* META */
5 years ago
{ TidyAttr_ID, "id", CH_IDDEF },
{ TidyAttr_ISMAP, "ismap", CH_BOOL }, /* IMG */
{ TidyAttr_ITEMID, "itemid", CH_PCDATA },
{ TidyAttr_ITEMPROP, "itemprop", CH_PCDATA },
{ TidyAttr_ITEMREF, "itemref", CH_PCDATA },
{ TidyAttr_ITEMSCOPE, "itemscope", CH_BOOL },
{ TidyAttr_ITEMTYPE, "itemtype", CH_URL },
{ TidyAttr_LABEL, "label", CH_PCDATA }, /* OPT, OPTGROUP */
5 years ago
{ TidyAttr_LANG, "lang", CH_LANG },
{ TidyAttr_LANGUAGE, "language", CH_PCDATA }, /* SCRIPT */
{ TidyAttr_LAST_MODIFIED, "last_modified", CH_PCDATA }, /* A */
{ TidyAttr_LAST_VISIT, "last_visit", CH_PCDATA }, /* A */
{ TidyAttr_LEFTMARGIN, "leftmargin", CH_NUMBER }, /* used on BODY */
{ TidyAttr_LINK, "link", CH_COLOR }, /* BODY */
{ TidyAttr_LONGDESC, "longdesc", CH_URL }, /* IMG */
{ TidyAttr_LOWSRC, "lowsrc", CH_URL }, /* IMG */
{ TidyAttr_MARGINHEIGHT, "marginheight", CH_NUMBER }, /* FRAME, IFRAME, BODY */
{ TidyAttr_MARGINWIDTH, "marginwidth", CH_NUMBER }, /* ditto */
{ TidyAttr_MAXLENGTH, "maxlength", CH_NUMBER }, /* INPUT */
{ TidyAttr_MEDIA, "media", CH_MEDIA }, /* STYLE, LINK */
{ TidyAttr_METHOD, "method", CH_FSUBMIT }, /* FORM: get or post */
{ TidyAttr_MULTIPLE, "multiple", CH_BOOL }, /* SELECT */
5 years ago
{ TidyAttr_NAME, "name", CH_NAME },
{ TidyAttr_NOHREF, "nohref", CH_BOOL }, /* AREA */
{ TidyAttr_NORESIZE, "noresize", CH_BOOL }, /* FRAME */
{ TidyAttr_NOSHADE, "noshade", CH_BOOL }, /* HR */
{ TidyAttr_NOWRAP, "nowrap", CH_BOOL }, /* table cells */
{ TidyAttr_OBJECT, "object", CH_PCDATA }, /* APPLET */
5 years ago
{ TidyAttr_OnAFTERUPDATE, "onafterupdate", CH_SCRIPT },
{ TidyAttr_OnBEFOREUNLOAD, "onbeforeunload", CH_SCRIPT },
{ TidyAttr_OnBEFOREUPDATE, "onbeforeupdate", CH_SCRIPT },
{ TidyAttr_OnBLUR, "onblur", CH_SCRIPT }, /* event */
{ TidyAttr_OnCHANGE, "onchange", CH_SCRIPT }, /* event */
{ TidyAttr_OnCLICK, "onclick", CH_SCRIPT }, /* event */
{ TidyAttr_OnDATAAVAILABLE, "ondataavailable", CH_SCRIPT }, /* object, applet */
{ TidyAttr_OnDATASETCHANGED, "ondatasetchanged", CH_SCRIPT }, /* object, applet */
5 years ago
{ TidyAttr_OnDATASETCOMPLETE, "ondatasetcomplete", CH_SCRIPT },
{ TidyAttr_OnDBLCLICK, "ondblclick", CH_SCRIPT }, /* event */
{ TidyAttr_OnERRORUPDATE, "onerrorupdate", CH_SCRIPT }, /* form fields */
{ TidyAttr_OnFOCUS, "onfocus", CH_SCRIPT }, /* event */
{ TidyAttr_OnKEYDOWN, "onkeydown", CH_SCRIPT }, /* event */
{ TidyAttr_OnKEYPRESS, "onkeypress", CH_SCRIPT }, /* event */
{ TidyAttr_OnKEYUP, "onkeyup", CH_SCRIPT }, /* event */
{ TidyAttr_OnLOAD, "onload", CH_SCRIPT }, /* event */
{ TidyAttr_OnMOUSEDOWN, "onmousedown", CH_SCRIPT }, /* event */
{ TidyAttr_OnMOUSEMOVE, "onmousemove", CH_SCRIPT }, /* event */
{ TidyAttr_OnMOUSEOUT, "onmouseout", CH_SCRIPT }, /* event */
{ TidyAttr_OnMOUSEOVER, "onmouseover", CH_SCRIPT }, /* event */
{ TidyAttr_OnMOUSEUP, "onmouseup", CH_SCRIPT }, /* event */
{ TidyAttr_OnRESET, "onreset", CH_SCRIPT }, /* event */
{ TidyAttr_OnROWENTER, "onrowenter", CH_SCRIPT }, /* form fields */
{ TidyAttr_OnROWEXIT, "onrowexit", CH_SCRIPT }, /* form fields */
{ TidyAttr_OnSELECT, "onselect", CH_SCRIPT }, /* event */
{ TidyAttr_OnSUBMIT, "onsubmit", CH_SCRIPT }, /* event */
{ TidyAttr_OnUNLOAD, "onunload", CH_SCRIPT }, /* event */
{ TidyAttr_PROFILE, "profile", CH_URL }, /* HEAD */
{ TidyAttr_PROMPT, "prompt", CH_PCDATA }, /* ISINDEX */
{ TidyAttr_RBSPAN, "rbspan", CH_NUMBER }, /* ruby markup */
{ TidyAttr_READONLY, "readonly", CH_BOOL }, /* form fields */
5 years ago
{ TidyAttr_REL, "rel", CH_LINKTYPES },
{ TidyAttr_REV, "rev", CH_LINKTYPES },
{ TidyAttr_RIGHTMARGIN, "rightmargin", CH_NUMBER }, /* used on BODY */
{ TidyAttr_ROLE, "role", CH_PCDATA },
{ TidyAttr_ROWS, "rows", CH_NUMBER }, /* TEXTAREA */
{ TidyAttr_ROWSPAN, "rowspan", CH_NUMBER }, /* table cells */
{ TidyAttr_RULES, "rules", CH_TRULES }, /* TABLE */
{ TidyAttr_SCHEME, "scheme", CH_PCDATA }, /* META */
{ TidyAttr_SCOPE, "scope", CH_SCOPE }, /* table cells */
5 years ago
{ TidyAttr_SCROLLING, "scrolling", CH_SCROLL }, /* aye, no or auto */
{ TidyAttr_SELECTED, "selected", CH_BOOL }, /* OPTION */
{ TidyAttr_SHAPE, "shape", CH_SHAPE }, /* AREA, A */
{ TidyAttr_SHOWGRID, "showgrid", CH_BOOL }, /* TABLE Adobe golive */
{ TidyAttr_SHOWGRIDX, "showgridx", CH_BOOL }, /* TABLE Adobe golive*/
{ TidyAttr_SHOWGRIDY, "showgridy", CH_BOOL }, /* TABLE Adobe golive*/
{ TidyAttr_SIZE, "size", CH_NUMBER }, /* HR, FONT, BASEFONT, SELECT */
{ TidyAttr_SPAN, "span", CH_NUMBER }, /* COL, COLGROUP */
{ TidyAttr_SRC, "src", CH_URL }, /* IMG, FRAME, IFRAME */
{ TidyAttr_SRCSET, "srcset", CH_PCDATA }, /* IMG (HTML5) */
{ TidyAttr_STANDBY, "standby", CH_PCDATA }, /* OBJECT */
{ TidyAttr_START, "start", CH_NUMBER }, /* OL */
5 years ago
{ TidyAttr_STYLE, "style", CH_PCDATA },
{ TidyAttr_SUMMARY, "summary", CH_PCDATA }, /* TABLE */
{ TidyAttr_TABINDEX, "tabindex", CH_NUMBER }, /* fields, OBJECT and A */
{ TidyAttr_TARGET, "target", CH_TARGET }, /* names a frame/window */
{ TidyAttr_TEXT, "text", CH_COLOR }, /* BODY */
{ TidyAttr_TITLE, "title", CH_PCDATA }, /* text tool tip */
{ TidyAttr_TOPMARGIN, "topmargin", CH_NUMBER }, /* used on BODY */
{ TidyAttr_TRANSLATE, "translate", CH_BOOL }, /* HTML5 global attribute */
{ TidyAttr_TYPE, "type", CH_TYPE }, /* also used by SPACER */
{ TidyAttr_USEMAP, "usemap", CH_URL }, /* things with images */
5 years ago
{ TidyAttr_VALIGN, "valign", CH_VALIGN },
{ TidyAttr_VALUE, "value", CH_PCDATA },
{ TidyAttr_VALUETYPE, "valuetype", CH_VTYPE }, /* PARAM: data, ref, object */
{ TidyAttr_VERSION, "version", CH_PCDATA }, /* HTML <?xml?> */
{ TidyAttr_VLINK, "vlink", CH_COLOR }, /* BODY */
{ TidyAttr_VSPACE, "vspace", CH_NUMBER }, /* IMG, OBJECT, APPLET */
{ TidyAttr_WIDTH, "width", CH_LENGTH }, /* pixels only for TD/TH */
{ TidyAttr_WRAP, "wrap", CH_PCDATA }, /* textarea */
{ TidyAttr_XML_LANG, "xml:lang", CH_LANG }, /* XML language */
{ TidyAttr_XML_SPACE, "xml:space", CH_PCDATA }, /* XML white space */
/* todo: VERS_ALL is wrong! */
{ TidyAttr_XMLNS, "xmlns", CH_PCDATA }, /* name space */
{ TidyAttr_EVENT, "event", CH_PCDATA }, /* reserved for <script> */
{ TidyAttr_METHODS, "methods", CH_PCDATA }, /* for <a>, never implemented */
{ TidyAttr_N, "n", CH_PCDATA }, /* for <nextid> */
{ TidyAttr_SDAFORM, "sdaform", CH_PCDATA }, /* SDATA attribute in HTML 2.0 */
{ TidyAttr_SDAPREF, "sdapref", CH_PCDATA }, /* SDATA attribute in HTML 2.0 */
{ TidyAttr_SDASUFF, "sdasuff", CH_PCDATA }, /* SDATA attribute in HTML 2.0 */
{ TidyAttr_URN, "urn", CH_PCDATA }, /* for <a>, never implemented */
/* HTML5 */
{ TidyAttr_ASYNC, "async", CH_BOOL }, /* <script src="..." async> */
{ TidyAttr_AUTOCOMPLETE, "autocomplete", CH_PCDATA },
{ TidyAttr_AUTOFOCUS, "autofocus", CH_PCDATA },
{ TidyAttr_AUTOPLAY, "autoplay", CH_PCDATA },
{ TidyAttr_CHALLENGE, "challenge", CH_PCDATA },
{ TidyAttr_CONTENTEDITABLE, "contenteditable", CH_PCDATA },
{ TidyAttr_CONTEXTMENU, "contextmenu", CH_PCDATA },
{ TidyAttr_CONTROLS, "controls", CH_PCDATA },
{ TidyAttr_CROSSORIGIN, "crossorigin", CH_PCDATA },
{ TidyAttr_DEFAULT, "default", CH_PCDATA },
{ TidyAttr_DIRNAME, "dirname", CH_PCDATA },
{ TidyAttr_DRAGGABLE, "draggable", CH_PCDATA },
{ TidyAttr_DROPZONE, "dropzone", CH_PCDATA },
{ TidyAttr_FORM, "form", CH_PCDATA },
{ TidyAttr_FORMACTION, "formaction", CH_PCDATA },
{ TidyAttr_FORMENCTYPE, "formenctype", CH_PCDATA },
{ TidyAttr_FORMMETHOD, "formmethod", CH_PCDATA },
{ TidyAttr_FORMNOVALIDATE, "formnovalidate", CH_PCDATA },
{ TidyAttr_FORMTARGET, "formtarget", CH_PCDATA },
{ TidyAttr_HIDDEN, "hidden", CH_PCDATA },
{ TidyAttr_HIGH, "high", CH_PCDATA },
{ TidyAttr_ICON, "icon", CH_PCDATA },
{ TidyAttr_KEYTYPE, "keytype", CH_PCDATA },
{ TidyAttr_KIND, "kind", CH_PCDATA },
{ TidyAttr_LIST, "list", CH_PCDATA },
{ TidyAttr_LOOP, "loop", CH_PCDATA },
{ TidyAttr_LOW, "low", CH_PCDATA },
{ TidyAttr_MANIFEST, "manifest", CH_PCDATA },
{ TidyAttr_MAX, "max", CH_PCDATA },
{ TidyAttr_MEDIAGROUP, "mediagroup", CH_PCDATA },
{ TidyAttr_MIN, "min", CH_PCDATA },
{ TidyAttr_NOVALIDATE, "novalidate", CH_PCDATA },
{ TidyAttr_OPEN, "open", CH_PCDATA },
{ TidyAttr_OPTIMUM, "optimum", CH_PCDATA },
{ TidyAttr_OnABORT, "onabort", CH_PCDATA },
{ TidyAttr_OnAFTERPRINT, "onafterprint", CH_PCDATA },
{ TidyAttr_OnBEFOREPRINT, "onbeforeprint", CH_PCDATA },
{ TidyAttr_OnCANPLAY, "oncanplay", CH_PCDATA },
{ TidyAttr_OnCANPLAYTHROUGH, "oncanplaythrough", CH_PCDATA },
{ TidyAttr_OnCONTEXTMENU, "oncontextmenu", CH_PCDATA },
{ TidyAttr_OnCUECHANGE, "oncuechange", CH_PCDATA },
{ TidyAttr_OnDRAG, "ondrag", CH_PCDATA },
{ TidyAttr_OnDRAGEND, "ondragend", CH_PCDATA },
{ TidyAttr_OnDRAGENTER, "ondragenter", CH_PCDATA },
{ TidyAttr_OnDRAGLEAVE, "ondragleave", CH_PCDATA },
{ TidyAttr_OnDRAGOVER, "ondragover", CH_PCDATA },
{ TidyAttr_OnDRAGSTART, "ondragstart", CH_PCDATA },
{ TidyAttr_OnDROP, "ondrop", CH_PCDATA },
{ TidyAttr_OnDURATIONCHANGE, "ondurationchange", CH_PCDATA },
{ TidyAttr_OnEMPTIED, "onemptied", CH_PCDATA },
{ TidyAttr_OnENDED, "onended", CH_PCDATA },
{ TidyAttr_OnERROR, "onerror", CH_PCDATA },
{ TidyAttr_OnHASHCHANGE, "onhashchange", CH_PCDATA },
{ TidyAttr_OnINPUT, "oninput", CH_PCDATA },
{ TidyAttr_OnINVALID, "oninvalid", CH_PCDATA },
{ TidyAttr_OnLOADEDDATA, "onloadeddata", CH_PCDATA },
{ TidyAttr_OnLOADEDMETADATA, "onloadedmetadata", CH_PCDATA },
{ TidyAttr_OnLOADSTART, "onloadstart", CH_PCDATA },
{ TidyAttr_OnMESSAGE, "onmessage", CH_PCDATA },
{ TidyAttr_OnMOUSEWHEEL, "onmousewheel", CH_PCDATA },
{ TidyAttr_OnOFFLINE, "onoffline", CH_PCDATA },
{ TidyAttr_OnONLINE, "ononline", CH_PCDATA },
{ TidyAttr_OnPAGEHIDE, "onpagehide", CH_PCDATA },
{ TidyAttr_OnPAGESHOW, "onpageshow", CH_PCDATA },
{ TidyAttr_OnPAUSE, "onpause", CH_PCDATA },
{ TidyAttr_OnPLAY, "onplay", CH_PCDATA },
{ TidyAttr_OnPLAYING, "onplaying", CH_PCDATA },
{ TidyAttr_OnPOPSTATE, "onpopstate", CH_PCDATA },
{ TidyAttr_OnPROGRESS, "onprogress", CH_PCDATA },
{ TidyAttr_OnRATECHANGE, "onratechange", CH_PCDATA },
{ TidyAttr_OnREADYSTATECHANGE, "onreadystatechange", CH_PCDATA },
{ TidyAttr_OnREDO, "onredo", CH_PCDATA },
{ TidyAttr_OnRESIZE, "onresize", CH_PCDATA },
{ TidyAttr_OnSCROLL, "onscroll", CH_PCDATA },
{ TidyAttr_OnSEEKED, "onseeked", CH_PCDATA },
{ TidyAttr_OnSEEKING, "onseeking", CH_PCDATA },
{ TidyAttr_OnSHOW, "onshow", CH_PCDATA },
{ TidyAttr_OnSTALLED, "onstalled", CH_PCDATA },
{ TidyAttr_OnSTORAGE, "onstorage", CH_PCDATA },
{ TidyAttr_OnSUSPEND, "onsuspend", CH_PCDATA },
{ TidyAttr_OnTIMEUPDATE, "ontimeupdate", CH_PCDATA },
{ TidyAttr_OnUNDO, "onundo", CH_PCDATA },
{ TidyAttr_OnVOLUMECHANGE, "onvolumechange", CH_PCDATA },
{ TidyAttr_OnWAITING, "onwaiting", CH_PCDATA },
{ TidyAttr_PATTERN, "pattern", CH_PCDATA },
{ TidyAttr_PLACEHOLDER, "placeholder", CH_PCDATA },
{ TidyAttr_POSTER, "poster", CH_PCDATA },
{ TidyAttr_PRELOAD, "preload", CH_PCDATA },
{ TidyAttr_PUBDATE, "pubdate", CH_PCDATA },
{ TidyAttr_RADIOGROUP, "radiogroup", CH_PCDATA },
{ TidyAttr_REQUIRED, "required", CH_PCDATA },
{ TidyAttr_REVERSED, "reversed", CH_PCDATA },
{ TidyAttr_SANDBOX, "sandbox", CH_PCDATA },
{ TidyAttr_SCOPED, "scoped", CH_PCDATA },
{ TidyAttr_SEAMLESS, "seamless", CH_PCDATA },
{ TidyAttr_SIZES, "sizes", CH_PCDATA },
{ TidyAttr_SPELLCHECK, "spellcheck", CH_PCDATA },
{ TidyAttr_SRCDOC, "srcdoc", CH_PCDATA },
{ TidyAttr_SRCLANG, "srclang", CH_PCDATA },
{ TidyAttr_STEP, "step", CH_PCDATA },
/* HTML5 Aria Attributes */
{ TidyAttr_ARIA_ACTIVEDESCENDANT, "aria-activedescendant", CH_PCDATA },
{ TidyAttr_ARIA_ATOMIC, "aria-atomic", CH_PCDATA },
{ TidyAttr_ARIA_AUTOCOMPLETE, "aria-autocomplete", CH_PCDATA },
{ TidyAttr_ARIA_BUSY, "aria-busy", CH_PCDATA },
{ TidyAttr_ARIA_CHECKED, "aria-checked", CH_PCDATA },
{ TidyAttr_ARIA_CONTROLS, "aria-controls", CH_PCDATA },
{ TidyAttr_ARIA_DESCRIBEDBY, "aria-describedby", CH_PCDATA },
{ TidyAttr_ARIA_DISABLED, "aria-disabled", CH_PCDATA },
{ TidyAttr_ARIA_DROPEFFECT, "aria-dropeffect", CH_PCDATA },
{ TidyAttr_ARIA_EXPANDED, "aria-expanded", CH_PCDATA },
{ TidyAttr_ARIA_FLOWTO, "aria-flowto", CH_PCDATA },
{ TidyAttr_ARIA_GRABBED, "aria-grabbed", CH_PCDATA },
{ TidyAttr_ARIA_HASPOPUP, "aria-haspopup", CH_PCDATA },
{ TidyAttr_ARIA_HIDDEN, "aria-hidden", CH_PCDATA },
{ TidyAttr_ARIA_INVALID, "aria-invalid", CH_PCDATA },
{ TidyAttr_ARIA_LABEL, "aria-label", CH_PCDATA },
{ TidyAttr_ARIA_LABELLEDBY, "aria-labelledby", CH_PCDATA },
{ TidyAttr_ARIA_LEVEL, "aria-level", CH_PCDATA },
{ TidyAttr_ARIA_LIVE, "aria-live", CH_PCDATA },
{ TidyAttr_ARIA_MULTILINE, "aria-multiline", CH_PCDATA },
{ TidyAttr_ARIA_MULTISELECTABLE, "aria-multiselectable", CH_PCDATA },
{ TidyAttr_ARIA_ORIENTATION, "aria-orientation", CH_PCDATA },
{ TidyAttr_ARIA_OWNS, "aria-owns", CH_PCDATA },
{ TidyAttr_ARIA_POSINSET, "aria-posinset", CH_PCDATA },
{ TidyAttr_ARIA_PRESSED, "aria-pressed", CH_PCDATA },
{ TidyAttr_ARIA_READONLY, "aria-readonly", CH_PCDATA },
{ TidyAttr_ARIA_RELEVANT, "aria-relevant", CH_PCDATA },
{ TidyAttr_ARIA_REQUIRED, "aria-required", CH_PCDATA },
{ TidyAttr_ARIA_SELECTED, "aria-selected", CH_PCDATA },
{ TidyAttr_ARIA_SETSIZE, "aria-setsize", CH_PCDATA },
{ TidyAttr_ARIA_SORT, "aria-sort", CH_PCDATA },
{ TidyAttr_ARIA_VALUEMAX, "aria-valuemax", CH_PCDATA },
{ TidyAttr_ARIA_VALUEMIN, "aria-valuemin", CH_PCDATA },
{ TidyAttr_ARIA_VALUENOW, "aria-valuenow", CH_PCDATA },
{ TidyAttr_ARIA_VALUETEXT, "aria-valuetext", CH_PCDATA },
{ TidyAttr_X, "x", CH_PCDATA }, /* for <svg> */
{ TidyAttr_Y, "y", CH_PCDATA }, /* for <svg> */
#if 0 /* with uppercase chars taken directly from W3C; are these case-insensitive everywhere? */
{ TidyAttr_VIEWBOX, "viewBox", VERS_INLINE_SVG, CH_PCDATA }, /* for <svg> */
{ TidyAttr_PRESERVEASPECTRATIO, "preserveAspectRatio", VERS_INLINE_SVG, CH_PCDATA }, /* for <svg> */
{ TidyAttr_ZOOMANDPAN, "zoomAndPan", VERS_INLINE_SVG, CH_PCDATA }, /* for <svg> */
{ TidyAttr_BASEPROFILE, "baseProfile", VERS_INLINE_SVG, CH_PCDATA }, /* for <svg> */
{ TidyAttr_CONTENTSCRIPTTYPE, "contentScriptType", VERS_INLINE_SVG, CH_PCDATA }, /* for <svg> */
{ TidyAttr_CONTENTSTYLETYPE, "contentStyleType", VERS_INLINE_SVG, CH_PCDATA }, /* for <svg> */
#else
{ TidyAttr_VIEWBOX, "viewbox", CH_PCDATA }, /* for <svg> */
{ TidyAttr_PRESERVEASPECTRATIO, "preserveaspectratio", CH_PCDATA }, /* for <svg> */
{ TidyAttr_ZOOMANDPAN, "zoomandpan", CH_PCDATA }, /* for <svg> */
{ TidyAttr_BASEPROFILE, "baseprofile", CH_PCDATA }, /* for <svg> */
{ TidyAttr_CONTENTSCRIPTTYPE, "contentscripttype", CH_PCDATA }, /* for <svg> */
{ TidyAttr_CONTENTSTYLETYPE, "contentstyletype", CH_PCDATA }, /* for <svg> */
#endif
{ TidyAttr_DISPLAY, "display", CH_PCDATA }, /* on MATH tag (html5) */
/* RDFa Attributes */
{ TidyAttr_ABOUT, "about", CH_RDFASCURIE },
{ TidyAttr_DATATYPE, "datatype", CH_RDFATERM },
{ TidyAttr_INLIST, "inlist", CH_BOOL },
{ TidyAttr_PREFIX, "prefix", CH_RDFAPREFIX },
{ TidyAttr_PROPERTY, "property", CH_RDFATERMS },
{ TidyAttr_RESOURCE, "resource", CH_RDFASCURIE },
{ TidyAttr_TYPEOF, "typeof", CH_RDFATERMS },
{ TidyAttr_VOCAB, "vocab", CH_URL },
{ TidyAttr_INTEGRITY, "integrity", CH_PCDATA },
/* this must be the final entry */
{ N_TIDY_ATTRIBS, NULL, NULL }
};
static uint AttributeVersions(Node* node, AttVal* attval)
{
uint i;
/* Override or add to items in attrdict.c */
if (attval && attval->attribute) {
/* HTML5 data-* attributes can't be added generically; handle here. */
if (TY_(tmbstrncmp)(attval->attribute, "data-", 5) == 0)
return (XH50 | HT50);
}
/* TODO: maybe this should return VERS_PROPRIETARY instead? */
if (!attval || !attval->dict)
return VERS_UNKNOWN;
if (!(!node || !node->tag || !node->tag->attrvers))
for (i = 0; node->tag->attrvers[i].attribute; ++i)
if (node->tag->attrvers[i].attribute == attval->dict->id)
return node->tag->attrvers[i].versions;
return VERS_PROPRIETARY;
}
/* return the version of the attribute "id" of element "node" */
uint TY_(NodeAttributeVersions)( Node* node, TidyAttrId id )
{
uint i;
if (!node || !node->tag || !node->tag->attrvers)
return VERS_UNKNOWN;
for (i = 0; node->tag->attrvers[i].attribute; ++i)
if (node->tag->attrvers[i].attribute == id)
return node->tag->attrvers[i].versions;
return VERS_UNKNOWN;
}
/* returns true if the element is a W3C defined element
* but the element/attribute combination is not. We're
* only defining as "proprietary" items that are not in
* the element's AttrVersion structure.
*/
Bool TY_(AttributeIsProprietary)(Node* node, AttVal* attval)
{
if (!node || !attval)
return no;
if (!node->tag)
return no;
if (!(node->tag->versions & VERS_ALL))
return no;
if (AttributeVersions(node, attval) & VERS_ALL)
return no;
5 years ago
return aye;
}
/* returns true if the element is a W3C defined element
* but the element/attribute combination is not. We're
* considering it a mismatch if the document version
* does not allow the attribute as called out in its
* AttrVersion structure.
*/
Bool TY_(AttributeIsMismatched)(Node* node, AttVal* attval, TidyDocImpl* doc)
{
uint doctype;
5 years ago
if (!node || !attval)
return no;
5 years ago
if (!node->tag)
return no;
5 years ago
if (!(node->tag->versions & VERS_ALL))
return no;
doctype = doc->lexer->versionEmitted == 0 ? doc->lexer->doctype : doc->lexer->versionEmitted;
if (AttributeVersions(node, attval) & doctype)
return no;
5 years ago
return aye;
}
/* used by CheckColor() */
struct _colors
{
ctmbstr name;
ctmbstr hex;
};
static const struct _colors colors[] =
{
{ "black", "#000000" },
{ "green", "#008000" },
{ "silver", "#C0C0C0" },
{ "lime", "#00FF00" },
{ "gray", "#808080" },
{ "olive", "#808000" },
{ "white", "#FFFFFF" },
{ "yellow", "#FFFF00" },
{ "maroon", "#800000" },
{ "navy", "#000080" },
{ "red", "#FF0000" },
{ "blue", "#0000FF" },
{ "purple", "#800080" },
{ "teal", "#008080" },
{ "fuchsia", "#FF00FF" },
{ "aqua", "#00FFFF" },
{ NULL, NULL }
};
static ctmbstr GetColorCode(ctmbstr name)
{
uint i;
for (i = 0; colors[i].name; ++i)
if (TY_(tmbstrcasecmp)(name, colors[i].name) == 0)
return colors[i].hex;
return NULL;
}
static ctmbstr GetColorName(ctmbstr code)
{
uint i;
for (i = 0; colors[i].name; ++i)
if (TY_(tmbstrcasecmp)(code, colors[i].hex) == 0)
return colors[i].name;
return NULL;
}
#if 0
static const struct _colors fancy_colors[] =
{
{ "darkgreen", "#006400" },
{ "antiquewhite", "#FAEBD7" },
{ "aqua", "#00FFFF" },
{ "aquamarine", "#7FFFD4" },
{ "azure", "#F0FFFF" },
{ "beige", "#F5F5DC" },
{ "bisque", "#FFE4C4" },
{ "black", "#000000" },
{ "blanchedalmond", "#FFEBCD" },
{ "blue", "#0000FF" },
{ "blueviolet", "#8A2BE2" },
{ "brown", "#A52A2A" },
{ "burlywood", "#DEB887" },
{ "cadetblue", "#5F9EA0" },
{ "chartreuse", "#7FFF00" },
{ "chocolate", "#D2691E" },
{ "coral", "#FF7F50" },
{ "cornflowerblue", "#6495ED" },
{ "cornsilk", "#FFF8DC" },
{ "crimson", "#DC143C" },
{ "cyan", "#00FFFF" },
{ "darkblue", "#00008B" },
{ "darkcyan", "#008B8B" },
{ "darkgoldenrod", "#B8860B" },
{ "darkgray", "#A9A9A9" },
{ "darkgreen", "#006400" },
{ "darkkhaki", "#BDB76B" },
{ "darkmagenta", "#8B008B" },
{ "darkolivegreen", "#556B2F" },
{ "darkorange", "#FF8C00" },
{ "darkorchid", "#9932CC" },
{ "darkred", "#8B0000" },
{ "darksalmon", "#E9967A" },
{ "darkseagreen", "#8FBC8F" },
{ "darkslateblue", "#483D8B" },
{ "darkslategray", "#2F4F4F" },
{ "darkturquoise", "#00CED1" },
{ "darkviolet", "#9400D3" },
{ "deeppink", "#FF1493" },
{ "deepskyblue", "#00BFFF" },
{ "dimgray", "#696969" },
{ "dodgerblue", "#1E90FF" },
{ "firebrick", "#B22222" },
{ "floralwhite", "#FFFAF0" },
{ "forestgreen", "#228B22" },
{ "fuchsia", "#FF00FF" },
{ "gainsboro", "#DCDCDC" },
{ "ghostwhite", "#F8F8FF" },
{ "gold", "#FFD700" },
{ "goldenrod", "#DAA520" },
{ "gray", "#808080" },
{ "green", "#008000" },
{ "greenyellow", "#ADFF2F" },
{ "honeydew", "#F0FFF0" },
{ "hotpink", "#FF69B4" },
{ "indianred", "#CD5C5C" },
{ "indigo", "#4B0082" },
{ "ivory", "#FFFFF0" },
{ "khaki", "#F0E68C" },
{ "lavender", "#E6E6FA" },
{ "lavenderblush", "#FFF0F5" },
{ "lawngreen", "#7CFC00" },
{ "lemonchiffon", "#FFFACD" },
{ "lightblue", "#ADD8E6" },
{ "lightcoral", "#F08080" },
{ "lightcyan", "#E0FFFF" },
{ "lightgoldenrodyellow", "#FAFAD2" },
{ "lightgreen", "#90EE90" },
{ "lightgrey", "#D3D3D3" },
{ "lightpink", "#FFB6C1" },
{ "lightsalmon", "#FFA07A" },
{ "lightseagreen", "#20B2AA" },
{ "lightskyblue", "#87CEFA" },
{ "lightslategray", "#778899" },
{ "lightsteelblue", "#B0C4DE" },
{ "lightyellow", "#FFFFE0" },
{ "lime", "#00FF00" },
{ "limegreen", "#32CD32" },
{ "linen", "#FAF0E6" },
{ "magenta", "#FF00FF" },
{ "maroon", "#800000" },
{ "mediumaquamarine", "#66CDAA" },
{ "mediumblue", "#0000CD" },
{ "mediumorchid", "#BA55D3" },
{ "mediumpurple", "#9370DB" },
{ "mediumseagreen", "#3CB371" },
{ "mediumslateblue", "#7B68EE" },
{ "mediumspringgreen", "#00FA9A" },
{ "mediumturquoise", "#48D1CC" },
{ "mediumvioletred", "#C71585" },
{ "midnightblue", "#191970" },
{ "mintcream", "#F5FFFA" },
{ "mistyrose", "#FFE4E1" },
{ "moccasin", "#FFE4B5" },
{ "navajowhite", "#FFDEAD" },
{ "navy", "#000080" },
{ "oldlace", "#FDF5E6" },
{ "olive", "#808000" },
{ "olivedrab", "#6B8E23" },
{ "orange", "#FFA500" },
{ "orangered", "#FF4500" },
{ "orchid", "#DA70D6" },
{ "palegoldenrod", "#EEE8AA" },
{ "palegreen", "#98FB98" },
{ "paleturquoise", "#AFEEEE" },
{ "palevioletred", "#DB7093" },
{ "papayawhip", "#FFEFD5" },
{ "peachpuff", "#FFDAB9" },
{ "peru", "#CD853F" },
{ "pink", "#FFC0CB" },
{ "plum", "#DDA0DD" },
{ "powderblue", "#B0E0E6" },
{ "purple", "#800080" },
{ "red", "#FF0000" },
{ "rosybrown", "#BC8F8F" },
{ "royalblue", "#4169E1" },
{ "saddlebrown", "#8B4513" },
{ "salmon", "#FA8072" },
{ "sandybrown", "#F4A460" },
{ "seagreen", "#2E8B57" },
{ "seashell", "#FFF5EE" },
{ "sienna", "#A0522D" },
{ "silver", "#C0C0C0" },
{ "skyblue", "#87CEEB" },
{ "slateblue", "#6A5ACD" },
{ "slategray", "#708090" },
{ "snow", "#FFFAFA" },
{ "springgreen", "#00FF7F" },
{ "steelblue", "#4682B4" },
{ "tan", "#D2B48C" },
{ "teal", "#008080" },
{ "thistle", "#D8BFD8" },
{ "tomato", "#FF6347" },
{ "turquoise", "#40E0D0" },
{ "violet", "#EE82EE" },
{ "wheat", "#F5DEB3" },
{ "white", "#FFFFFF" },
{ "whitesmoke", "#F5F5F5" },
{ "yellow", "#FFFF00" },
{ "yellowgreen", "#9ACD32" },
{ NULL, NULL }
};
#endif
#if ATTRIBUTE_HASH_LOOKUP
static uint attrsHash(ctmbstr s)
{
uint hashval;
for (hashval = 0; *s != '\0'; s++)
hashval = *s + 31*hashval;
return hashval % ATTRIBUTE_HASH_SIZE;
}
static const Attribute *attrsInstall(TidyDocImpl* doc, TidyAttribImpl * attribs,
const Attribute* old)
{
AttrHash *np;
uint hashval;
if (old)
{
np = (AttrHash *)TidyDocAlloc(doc, sizeof(*np));
np->attr = old;
hashval = attrsHash(old->name);
np->next = attribs->hashtab[hashval];
attribs->hashtab[hashval] = np;
}
return old;
}
static void attrsRemoveFromHash( TidyDocImpl* doc, TidyAttribImpl *attribs,
ctmbstr s )
{
uint h = attrsHash(s);
AttrHash *p, *prev = NULL;
for (p = attribs->hashtab[h]; p && p->attr; p = p->next)
{
if (TY_(tmbstrcmp)(s, p->attr->name) == 0)
{
AttrHash* next = p->next;
if ( prev )
5 years ago
prev->next = next;
else
attribs->hashtab[h] = next;
TidyDocFree(doc, p);
return;
}
prev = p;
}
}
static void attrsEmptyHash( TidyDocImpl* doc, TidyAttribImpl * attribs )
{
AttrHash *dict, *next;
uint i;
for (i = 0; i < ATTRIBUTE_HASH_SIZE; ++i)
{
dict = attribs->hashtab[i];
while(dict)
{
next = dict->next;
TidyDocFree(doc, dict);
dict = next;
}
attribs->hashtab[i] = NULL;
}
}
#endif
static const Attribute* attrsLookup(TidyDocImpl* doc,
TidyAttribImpl* ARG_UNUSED(attribs),
ctmbstr atnam)
{
const Attribute *np;
#if ATTRIBUTE_HASH_LOOKUP
const AttrHash *p;
#endif
if (!atnam)
return NULL;
#if ATTRIBUTE_HASH_LOOKUP
for (p = attribs->hashtab[attrsHash(atnam)]; p && p->attr; p = p->next)
if (TY_(tmbstrcmp)(atnam, p->attr->name) == 0)
return p->attr;
for (np = attribute_defs; np && np->name; ++np)
if (TY_(tmbstrcmp)(atnam, np->name) == 0)
return attrsInstall(doc, attribs, np);
#else
for (np = attribute_defs; np && np->name; ++np)
if (TY_(tmbstrcmp)(atnam, np->name) == 0)
return np;
#endif
return NULL;
}
/* Locate attributes by type */
AttVal* TY_(AttrGetById)( Node* node, TidyAttrId id )
{
AttVal* av;
for ( av = node->attributes; av; av = av->next )
{
if ( AttrIsId(av, id) )
return av;
}
return NULL;
}
/* public method for finding attribute definition by name */
const Attribute* TY_(FindAttribute)( TidyDocImpl* doc, AttVal *attval )
{
if ( attval )
return attrsLookup( doc, &doc->attribs, attval->attribute );
return NULL;
}
AttVal* TY_(GetAttrByName)( Node *node, ctmbstr name )
{
AttVal *attr;
for (attr = node->attributes; attr != NULL; attr = attr->next)
{
if (attr->attribute && TY_(tmbstrcmp)(attr->attribute, name) == 0)
break;
}
return attr;
}
void TY_(DropAttrByName)( TidyDocImpl* doc, Node *node, ctmbstr name )
{
AttVal *attr, *prev = NULL, *next;
for (attr = node->attributes; attr != NULL; prev = attr, attr = next)
{
next = attr->next;
if (attr->attribute && TY_(tmbstrcmp)(attr->attribute, name) == 0)
{
if (prev)
prev->next = next;
else
node->attributes = next;
5 years ago
TY_(FreeAttribute)( doc, attr );
break;
}
}
}
AttVal* TY_(AddAttribute)( TidyDocImpl* doc,
Node *node, ctmbstr name, ctmbstr value )
{
AttVal *av = TY_(NewAttribute)(doc);
av->delim = '"';
av->attribute = TY_(tmbstrdup)(doc->allocator, name);
if (value)
av->value = TY_(tmbstrdup)(doc->allocator, value);
else
av->value = NULL;
av->dict = attrsLookup(doc, &doc->attribs, name);
TY_(InsertAttributeAtEnd)(node, av);
return av;
}
AttVal* TY_(RepairAttrValue)(TidyDocImpl* doc, Node* node, ctmbstr name, ctmbstr value)
{
AttVal* old = TY_(GetAttrByName)(node, name);
if (old)
{
if (old->value)
TidyDocFree(doc, old->value);
if (value)
old->value = TY_(tmbstrdup)(doc->allocator, value);
else
old->value = NULL;
return old;
}
else
return TY_(AddAttribute)(doc, node, name, value);
}
static Bool CheckAttrType( TidyDocImpl* doc,
ctmbstr attrname, AttrCheck type )
{
const Attribute* np = attrsLookup( doc, &doc->attribs, attrname );
return (Bool)( np && np->attrchk == type );
}
Bool TY_(IsUrl)( TidyDocImpl* doc, ctmbstr attrname )
{
return CheckAttrType( doc, attrname, CH_URL );
}
/*
Bool IsBool( TidyDocImpl* doc, ctmbstr attrname )
{
return CheckAttrType( doc, attrname, CH_BOOL );
}
*/
Bool TY_(IsScript)( TidyDocImpl* doc, ctmbstr attrname )
{
return CheckAttrType( doc, attrname, CH_SCRIPT );
}
/* may id or name serve as anchor? */
Bool TY_(IsAnchorElement)( TidyDocImpl* ARG_UNUSED(doc), Node* node)
{
TidyTagId tid = TagId( node );
if ( tid == TidyTag_A ||
tid == TidyTag_APPLET ||
tid == TidyTag_FORM ||
tid == TidyTag_FRAME ||
tid == TidyTag_IFRAME ||
tid == TidyTag_IMG ||
tid == TidyTag_MAP )
5 years ago
return aye;
return no;
}
/*
In CSS1, selectors can contain only the characters A-Z, 0-9,
and Unicode characters 161-255, plus dash (-); they cannot start
with a dash or a digit; they can also contain escaped characters
and any Unicode character as a numeric code (see next item).
The backslash followed by at most four hexadecimal digits
(0..9A..F) stands for the Unicode character with that number.
Any character except a hexadecimal digit can be escaped to remove
its special meaning, by putting a backslash in front.
#508936 - CSS class naming for -clean option
*/
Bool TY_(IsCSS1Selector)( ctmbstr buf )
{
5 years ago
Bool valid = aye;
int esclen = 0;
byte c;
int pos;
for ( pos=0; valid && (c = *buf++); ++pos )
{
if ( c == '\\' )
{
esclen = 1; /* ab\555\444 is 4 chars {'a', 'b', \555, \444} */
}
else if ( isdigit( c ) )
{
/* Digit not 1st, unless escaped (Max length "\112F") */
if ( esclen > 0 )
valid = ( ++esclen < 6 );
if ( valid )
valid = ( pos>0 || esclen>0 );
}
else
{
valid = (
esclen > 0 /* Escaped? Anything goes. */
|| ( pos>0 && c == '-' ) /* Dash cannot be 1st char */
|| isalpha(c) /* a-z, A-Z anywhere */
|| ( c >= 161 ) /* Unicode 161-255 anywhere */
);
esclen = 0;
}
}
return valid;
}
/* free single anchor */
static void FreeAnchor(TidyDocImpl* doc, Anchor *a)
{
if ( a )
TidyDocFree( doc, a->name );
TidyDocFree( doc, a );
}
static uint anchorNameHash(ctmbstr s)
{
uint hashval = 0;
/* Issue #149 - an inferred name can be null. avoid crash */
5 years ago
if (s)
{
for ( ; *s != '\0'