github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/html/template/attr.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package template
     6  
     7  import (
     8  	"github.com/x04/go/src/strings"
     9  )
    10  
    11  // attrTypeMap[n] describes the value of the given attribute.
    12  // If an attribute affects (or can mask) the encoding or interpretation of
    13  // other content, or affects the contents, idempotency, or credentials of a
    14  // network message, then the value in this map is contentTypeUnsafe.
    15  // This map is derived from HTML5, specifically
    16  // https://www.w3.org/TR/html5/Overview.html#attributes-1
    17  // as well as "%URI"-typed attributes from
    18  // https://www.w3.org/TR/html4/index/attributes.html
    19  var attrTypeMap = map[string]contentType{
    20  	"accept":		contentTypePlain,
    21  	"accept-charset":	contentTypeUnsafe,
    22  	"action":		contentTypeURL,
    23  	"alt":			contentTypePlain,
    24  	"archive":		contentTypeURL,
    25  	"async":		contentTypeUnsafe,
    26  	"autocomplete":		contentTypePlain,
    27  	"autofocus":		contentTypePlain,
    28  	"autoplay":		contentTypePlain,
    29  	"background":		contentTypeURL,
    30  	"border":		contentTypePlain,
    31  	"checked":		contentTypePlain,
    32  	"cite":			contentTypeURL,
    33  	"challenge":		contentTypeUnsafe,
    34  	"charset":		contentTypeUnsafe,
    35  	"class":		contentTypePlain,
    36  	"classid":		contentTypeURL,
    37  	"codebase":		contentTypeURL,
    38  	"cols":			contentTypePlain,
    39  	"colspan":		contentTypePlain,
    40  	"content":		contentTypeUnsafe,
    41  	"contenteditable":	contentTypePlain,
    42  	"contextmenu":		contentTypePlain,
    43  	"controls":		contentTypePlain,
    44  	"coords":		contentTypePlain,
    45  	"crossorigin":		contentTypeUnsafe,
    46  	"data":			contentTypeURL,
    47  	"datetime":		contentTypePlain,
    48  	"default":		contentTypePlain,
    49  	"defer":		contentTypeUnsafe,
    50  	"dir":			contentTypePlain,
    51  	"dirname":		contentTypePlain,
    52  	"disabled":		contentTypePlain,
    53  	"draggable":		contentTypePlain,
    54  	"dropzone":		contentTypePlain,
    55  	"enctype":		contentTypeUnsafe,
    56  	"for":			contentTypePlain,
    57  	"form":			contentTypeUnsafe,
    58  	"formaction":		contentTypeURL,
    59  	"formenctype":		contentTypeUnsafe,
    60  	"formmethod":		contentTypeUnsafe,
    61  	"formnovalidate":	contentTypeUnsafe,
    62  	"formtarget":		contentTypePlain,
    63  	"headers":		contentTypePlain,
    64  	"height":		contentTypePlain,
    65  	"hidden":		contentTypePlain,
    66  	"high":			contentTypePlain,
    67  	"href":			contentTypeURL,
    68  	"hreflang":		contentTypePlain,
    69  	"http-equiv":		contentTypeUnsafe,
    70  	"icon":			contentTypeURL,
    71  	"id":			contentTypePlain,
    72  	"ismap":		contentTypePlain,
    73  	"keytype":		contentTypeUnsafe,
    74  	"kind":			contentTypePlain,
    75  	"label":		contentTypePlain,
    76  	"lang":			contentTypePlain,
    77  	"language":		contentTypeUnsafe,
    78  	"list":			contentTypePlain,
    79  	"longdesc":		contentTypeURL,
    80  	"loop":			contentTypePlain,
    81  	"low":			contentTypePlain,
    82  	"manifest":		contentTypeURL,
    83  	"max":			contentTypePlain,
    84  	"maxlength":		contentTypePlain,
    85  	"media":		contentTypePlain,
    86  	"mediagroup":		contentTypePlain,
    87  	"method":		contentTypeUnsafe,
    88  	"min":			contentTypePlain,
    89  	"multiple":		contentTypePlain,
    90  	"name":			contentTypePlain,
    91  	"novalidate":		contentTypeUnsafe,
    92  	// Skip handler names from
    93  	// https://www.w3.org/TR/html5/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects
    94  	// since we have special handling in attrType.
    95  	"open":		contentTypePlain,
    96  	"optimum":	contentTypePlain,
    97  	"pattern":	contentTypeUnsafe,
    98  	"placeholder":	contentTypePlain,
    99  	"poster":	contentTypeURL,
   100  	"profile":	contentTypeURL,
   101  	"preload":	contentTypePlain,
   102  	"pubdate":	contentTypePlain,
   103  	"radiogroup":	contentTypePlain,
   104  	"readonly":	contentTypePlain,
   105  	"rel":		contentTypeUnsafe,
   106  	"required":	contentTypePlain,
   107  	"reversed":	contentTypePlain,
   108  	"rows":		contentTypePlain,
   109  	"rowspan":	contentTypePlain,
   110  	"sandbox":	contentTypeUnsafe,
   111  	"spellcheck":	contentTypePlain,
   112  	"scope":	contentTypePlain,
   113  	"scoped":	contentTypePlain,
   114  	"seamless":	contentTypePlain,
   115  	"selected":	contentTypePlain,
   116  	"shape":	contentTypePlain,
   117  	"size":		contentTypePlain,
   118  	"sizes":	contentTypePlain,
   119  	"span":		contentTypePlain,
   120  	"src":		contentTypeURL,
   121  	"srcdoc":	contentTypeHTML,
   122  	"srclang":	contentTypePlain,
   123  	"srcset":	contentTypeSrcset,
   124  	"start":	contentTypePlain,
   125  	"step":		contentTypePlain,
   126  	"style":	contentTypeCSS,
   127  	"tabindex":	contentTypePlain,
   128  	"target":	contentTypePlain,
   129  	"title":	contentTypePlain,
   130  	"type":		contentTypeUnsafe,
   131  	"usemap":	contentTypeURL,
   132  	"value":	contentTypeUnsafe,
   133  	"width":	contentTypePlain,
   134  	"wrap":		contentTypePlain,
   135  	"xmlns":	contentTypeURL,
   136  }
   137  
   138  // attrType returns a conservative (upper-bound on authority) guess at the
   139  // type of the lowercase named attribute.
   140  func attrType(name string) contentType {
   141  	if strings.HasPrefix(name, "data-") {
   142  		// Strip data- so that custom attribute heuristics below are
   143  		// widely applied.
   144  		// Treat data-action as URL below.
   145  		name = name[5:]
   146  	} else if colon := strings.IndexRune(name, ':'); colon != -1 {
   147  		if name[:colon] == "xmlns" {
   148  			return contentTypeURL
   149  		}
   150  		// Treat svg:href and xlink:href as href below.
   151  		name = name[colon+1:]
   152  	}
   153  	if t, ok := attrTypeMap[name]; ok {
   154  		return t
   155  	}
   156  	// Treat partial event handler names as script.
   157  	if strings.HasPrefix(name, "on") {
   158  		return contentTypeJS
   159  	}
   160  
   161  	// Heuristics to prevent "javascript:..." injection in custom
   162  	// data attributes and custom attributes like g:tweetUrl.
   163  	// https://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes
   164  	// "Custom data attributes are intended to store custom data
   165  	//  private to the page or application, for which there are no
   166  	//  more appropriate attributes or elements."
   167  	// Developers seem to store URL content in data URLs that start
   168  	// or end with "URI" or "URL".
   169  	if strings.Contains(name, "src") ||
   170  		strings.Contains(name, "uri") ||
   171  		strings.Contains(name, "url") {
   172  		return contentTypeURL
   173  	}
   174  	return contentTypePlain
   175  }