How to use Cite method of html Package

Best K6 code snippet using html.Cite

goqueryuse.go

Source:goqueryuse.go Github

copy

Full Screen

1package main2import (3 "errors"4 "fmt"5 "github.com/PuerkitoBio/goquery"6 "strings"7)8var html = `9<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">10<html xmlns="http://www.w3.org/1999/xhtml">11<head>12<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />13<title>高清有码 - 第2页 - 高清下载吧! - Powered by Discuz!</title>14<meta name="keywords" content="高清有码" />15<meta name="description" content="高清有码 ,高清下载吧!" />16<meta name="generator" content="Discuz! X3.4" />17<meta name="author" content="Discuz! Team and Comsenz UI Team" />18<meta name="copyright" content="2001-2017 Comsenz Inc." />19<meta name="MSSmartTagsPreventParsing" content="True" />20<meta http-equiv="MSThemeCompatible" content="Yes" />21<base href="https://www.kan224.com/" /><link rel="stylesheet" type="text/css" href="data/cache/style_1_common.css?vUs" /><link rel="stylesheet" type="text/css" href="data/cache/style_1_forum_forumdisplay.css?vUs" /><script type="text/javascript">var STYLEID = '1', STATICURL = 'static/', IMGDIR = 'static/image/common', VERHASH = 'vUs', charset = 'utf-8', discuz_uid = '0', cookiepre = 'b9GW_2132_', cookiedomain = '', cookiepath = '/', showusercard = '1', attackevasive = '0', disallowfloat = 'newthread', creditnotice = '1|威望|,2|金钱|,3|贡献|', defaultstyle = '', REPORTURL = 'aHR0cDovL3d3dy5rYW4yMjQuY29tL2ZvcnVtLTM2LTIuaHRtbA==', SITEURL = 'https://www.kan224.com/', JSPATH = 'static/js/', CSSPATH = 'data/cache/style_', DYNAMICURL = '';</script>22<script src="static/js/common.js?vUs" type="text/javascript"></script>23<meta name="application-name" content="高清下载吧!" />24<meta name="msapplication-tooltip" content="高清下载吧!" />25<meta name="msapplication-task" content="name=首页;action-uri=https://www.kan224.com/forum.php;icon-uri=https://www.kan224.com/static/image/common/bbs.ico" />26<link rel="archives" title="高清下载吧!" href="https://www.kan224.com/archiver/" />27<link rel="alternate" type="application/rss+xml" title="高清下载吧! - 高清有码 - 第2页" href="https://www.kan224.com/forum.php?mod=rss&fid=36&amp;auth=0" />28<script src="static/js/forum.js?vUs" type="text/javascript"></script>29</head>30<body id="nv_forum" class="pg_forumdisplay" onkeydown="if(event.keyCode==27) return false;">31<div id="append_parent"></div><div id="ajaxwaitid"></div>32<div id="toptb" class="cl">33<div class="wp">34<div class="z"><a href="javascript:;" onclick="setHomepage('https://www.vcke.xyz/');">设为首页</a><a href="https://www.vcke.xyz/" onclick="addFavorite(this.href, '高清下载吧!');return false;">收藏本站</a></div>35<div class="y">36<a id="switchblind" href="javascript:;" onclick="toggleBlind(this)" title="开启辅助访问" class="switchblind">开启辅助访问</a>37<a href="javascript:;" id="switchwidth" onclick="widthauto(this)" title="切换到宽版" class="switchwidth">切换到宽版</a>38</div>39</div>40</div>41<div id="qmenu_menu" class="p_pop blk" style="display: none;">42<div class="ptm pbw hm">43请 <a href="javascript:;" class="xi2" onclick="lsSubmit()"><strong>登录</strong></a> 后使用快捷导航<br />没有帐号?<a href="member.php?mod=zbucihd4k" class="xi2 xw1">立即注册</a>44</div>45<div id="fjump_menu" class="btda"></div></div><div class="wp a_h"><a href="https://cutt.ly/JgOQg3c"><img src="https://i.comss.pics/2020/12/03/960x80.gif" alt="960x80.gif" border="0" /></a></div><div id="hd">46<div class="wp">47<div class="hdc cl"><h2><a href="./" title="高清下载吧!"><img src="static/image/common/logo.png" alt="高清下载吧!" border="0" /></a></h2><script src="static/js/logging.js?vUs" type="text/javascript"></script>48<form method="post" autocomplete="off" id="lsform" action="member.php?mod=logging&amp;action=login&amp;loginsubmit=yes&amp;infloat=yes&amp;lssubmit=yes" onsubmit="return lsSubmit();">49<div class="fastlg cl">50<span id="return_ls" style="display:none"></span>51<div class="y pns">52<table cellspacing="0" cellpadding="0">53<tr>54<td>55<span class="ftid">56<select name="fastloginfield" id="ls_fastloginfield" width="40" tabindex="900">57<option value="username">用户名</option>58<option value="email">Email</option>59</select>60</span>61<script type="text/javascript">simulateSelect('ls_fastloginfield')</script>62</td>63<td><input type="text" name="username" id="ls_username" autocomplete="off" class="px vm" tabindex="901" /></td>64<td class="fastlg_l"><label for="ls_cookietime"><input type="checkbox" name="cookietime" id="ls_cookietime" class="pc" value="2592000" tabindex="903" />自动登录</label></td>65<td>&nbsp;<a href="javascript:;" onclick="showWindow('login', 'member.php?mod=logging&action=login&viewlostpw=1')">找回密码</a></td>66</tr>67<tr>68<td><label for="ls_password" class="z psw_w">密码</label></td>69<td><input type="password" name="password" id="ls_password" class="px vm" autocomplete="off" tabindex="902" /></td>70<td class="fastlg_l"><button type="submit" class="pn vm" tabindex="904" style="width: 75px;"><em>登录</em></button></td>71<td>&nbsp;<a href="member.php?mod=zbucihd4k" class="xi2 xw1">立即注册</a></td>72</tr>73</table>74<input type="hidden" name="quickforward" value="yes" />75<input type="hidden" name="handlekey" value="ls" />76</div>77</div>78</form>79</div>80<div id="nv">81<a href="javascript:;" id="qmenu" onmouseover="delayShow(this, function () {showMenu({'ctrlid':'qmenu','pos':'34!','ctrlclass':'a','duration':2});showForummenu(36);})">快捷导航</a>82<ul><li class="a" id="mn_forum" ><a href="forum.php" hidefocus="true" title="BBS" >首页<span>BBS</span></a></li><li id="mn_N68fc" onmouseover="showMenu({'ctrlid':this.id,'ctrlclass':'hover','duration':2})"><a href="#" hidefocus="true" target="_blank" style="font-weight: bold;">免费18禁手游</a></li><li id="mn_N0fd4" ><a href="https://3s.pw/9GMDY" hidefocus="true" target="_blank" style="font-weight: bold;">工口.R18 免費美少女遊戲</a></li></ul>83</div>84<ul class="p_pop h_pop" id="mn_N68fc_menu" style="display: none"><li><a href="https://dmmn17y868vex.cloudfront.net/?utm_source=17&utm_medium=CPC&utm_campaign=17&attributionid=17" hidefocus="true" target="_blank" >烽火玉乳</a></li><li><a href="https://d2uyxuo46plvr.cloudfront.net/?utm_source=17&utm_medium=CPC&utm_campaign=17&attributionid=17" hidefocus="true" target="_blank" >三国H传</a></li><li><a href="https://dpjoxi74vfy85.cloudfront.net/?utm_source=17&utm_medium=CPC&utm_campaign=17&attributionid=17" hidefocus="true" target="_blank">黑道總裁</a></li><li><a href="https://d25k6ubz7qa2u1.cloudfront.net/?utm_source=17&utm_medium=CPC&utm_campaign=17&attributionid=17" hidefocus="true" target="_blank">封神淫錄</a></li><li><a href="https://d1ezng1oppe03v.cloudfront.net/?utm_source=17&utm_medium=CPC&utm_campaign=17&attributionid=17" hidefocus="true" target="_blank" >爱爱学院</a></li><li><a href="https://d2z0vl0fubcyzw.cloudfront.net/?utm_source=17&utm_medium=CPC&utm_campaign=17&attributionid=17" hidefocus="true" target="_blank" >末世王者</a></li></ul><div id="mu" class="cl">85</div><div id="scbar" class="cl">86<form id="scbar_form" method="post" autocomplete="off" onsubmit="searchFocus($('scbar_txt'))" action="search.php?searchsubmit=yes" target="_blank">87<input type="hidden" name="mod" id="scbar_mod" value="search" />88<input type="hidden" name="formhash" value="b6acf023" />89<input type="hidden" name="srchtype" value="title" />90<input type="hidden" name="srhfid" value="36" />91<input type="hidden" name="srhlocality" value="forum::forumdisplay" />92<table cellspacing="0" cellpadding="0">93<tr>94<td class="scbar_icon_td"></td>95<td class="scbar_txt_td"><input type="text" name="srchtxt" id="scbar_txt" value="请输入搜索内容" autocomplete="off" x-webkit-speech speech /></td>96<td class="scbar_type_td"><a href="javascript:;" id="scbar_type" class="xg1" onclick="showMenu(this.id)" hidefocus="true">搜索</a></td>97<td class="scbar_btn_td"><button type="submit" name="searchsubmit" id="scbar_btn" sc="1" class="pn pnc" value="true"><strong class="xi2">搜索</strong></button></td>98<td class="scbar_hot_td">99<div id="scbar_hot">100<strong class="xw1">热搜: </strong>101<a href="search.php?mod=forum&amp;srchtxt=%E6%B4%BB%E5%8A%A8&amp;formhash=b6acf023&amp;searchsubmit=true&amp;source=hotsearch" target="_blank" class="xi2" sc="1">活动</a>102<a href="search.php?mod=forum&amp;srchtxt=%E4%BA%A4%E5%8F%8B&amp;formhash=b6acf023&amp;searchsubmit=true&amp;source=hotsearch" target="_blank" class="xi2" sc="1">交友</a>103<a href="search.php?mod=forum&amp;srchtxt=discuz&amp;formhash=b6acf023&amp;searchsubmit=true&amp;source=hotsearch" target="_blank" class="xi2" sc="1">discuz</a>104</div>105</td>106</tr>107</table>108</form>109</div>110<ul id="scbar_type_menu" class="p_pop" style="display: none;"><li><a href="javascript:;" rel="curforum" fid="36" >本版</a></li><li><a href="javascript:;" rel="forum" class="curtype">帖子</a></li><li><a href="javascript:;" rel="user">用户</a></li></ul>111<script type="text/javascript">112initSearchmenu('scbar', '');113</script>114</div>115</div>116<div id="wp" class="wp">117<style id="diy_style" type="text/css"></style>118<!--[diy=diynavtop]--><div id="diynavtop" class="area"></div><!--[/diy]-->119<div id="pt" class="bm cl">120<div class="z">121<a href="./" class="nvhm" title="首页">高清下载吧!</a><em>&raquo;</em><a href="forum.php">首页</a> <em>&rsaquo;</em> <a href="forum.php?gid=1">原创高清BT</a><em>&rsaquo;</em> <a href="forum-36-1.html">高清有码</a></div>122</div><div class="wp a_t"><table cellpadding="0" cellspacing="1"><tr><td width="100%"><!-- JuicyAds v3.1 -->123<script type="text/javascript" data-cfasync="false" async src="https://poweredby.jads.co/js/jads.js"></script>124<ins id="864492" data-width="728" data-height="102"></ins>125<script type="text/javascript" data-cfasync="false" async>(adsbyjuicy = window.adsbyjuicy || []).push({'adzone':864492});</script>126<!--JuicyAds END--></td></tr>127</table></div><div class="wp">128<!--[diy=diy1]--><div id="diy1" class="area"></div><!--[/diy]-->129</div>130<div class="boardnav">131<div id="ct" class="wp cl">132<div class="mn">133<div class="bm bml pbn">134<div class="bm_h cl">135<span class="y">136<a href="home.php?mod=spacecp&amp;ac=favorite&amp;type=forum&amp;id=36&amp;handlekey=favoriteforum&amp;formhash=b6acf023" id="a_favorite" class="fa_fav" onclick="showWindow(this.id, this.href, 'get', 0);">收藏本版 <strong class="xi1" id="number_favorite" >(<span id="number_favorite_num">12</span>)</strong></a>137<span class="pipe">|</span><a href="forum.php?mod=rss&amp;fid=36&amp;auth=0" class="fa_rss" target="_blank" title="RSS">订阅</a>138</span>139<h1 class="xs2">140<a href="forum-36-1.html">高清有码</a>141<span class="xs1 xw0 i">今日: <strong class="xi1">1</strong><b class="ico_increase">&nbsp;</b><span class="pipe">|</span>主题: <strong class="xi1">22572</strong><span class="pipe">|</span>排名: <strong class="xi1" title="上次排名:11">20</strong><b class="ico_fall">&nbsp;</b></span></h1>142</div>143</div>144<div class="drag">145<!--[diy=diy4]--><div id="diy4" class="area"><div id="frameWGX71I" class="frame move-span cl frame-1"><div id="frameWGX71I_left" class="column frame-1-c"><div id="frameWGX71I_left_temp" class="move-span temp"></div><div id="portal_block_8" class="block move-span"><div id="portal_block_8_content" class="dxb_bc"><div class="portal_block_summary"><table style="width:100%;" cellpadding="2" cellspacing="0" border="1" bordercolor="#000000">146 <tbody>147 <tr>148 <td>149 <p>150 <span style="font-family:KaiTi_GB2312;color:#009900;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="https://202900.com:2262?register=1" target="_blank"><span style="color:#009900;font-size:18px;"><strong>❤️一夜暴富 嫩模空姐任你选 ❤️</strong></span></a></span> 151 </p>152 </td>153 <td>154 <p>155 <span style="font-family:KaiTi_GB2312;color:#E56600;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<a href="https://aoluoluo.info/?u=UIJYhNvfICHU" target="_blank"><span style="color:#E56600;font-size:18px;"><strong>全国小姐 同城楼凤</strong></span></a></span> 156 </p>157 </td>158 <td>159 <p>160 <span style="font-family:KaiTi_GB2312;color:#009900;">&nbsp; &nbsp; &nbsp;&nbsp;<a href="https://cej.54647.blog/" target="_blank"><span style="color:#009900;font-size:18px;"><strong>免費18禁美少女手遊戲</strong></span></a></span> 161 </p>162 </td>163 <td>164 <p>165 <span style="font-family:KaiTi_GB2312;color:#E56600;">&nbsp; &nbsp; &nbsp;&nbsp;<a href="http://www.uut92.com/" target="_blank"><span style="color:#E56600;font-size:18px;"><strong>台湾uu裸聊直播</strong></span></a></span> 166 </p>167 </td>168 </tr>169 </tbody>170</table>171<br /></div></div></div></div></div></div><!--[/diy]-->172</div>173<div class="bm bmw">174<div class="bm_h cl">175<h2>推荐主题</h2>176</div>177<div class="bm_c cl"><div class="cl"><ul class="xl xl2 cl"><li>178<a href="thread-60267-1-1.html" target="_blank">[HD/3.41G]261ARA-376【絶対的美少女】22歳【最強SSS級】あかりちゃん5度目の参上!一つ歳を重ね、パテシエ見習いから店頭に商品を出せるように</a>179</li>180<li>181<a href="thread-27559-1-1.html" target="_blank">[HD/2.10G]SIRO-2571 素人AV体験撮影965 みずき 21歳 学生</a>182</li>183<li>184<a href="thread-65-1-1.html" target="_blank">[HD/5.45G]MIMK-020 母姉W相姦 木下あずみ 沖田杏梨</a>185</li>186<li>187<a href="thread-59564-1-1.html" target="_blank">[HD/2.42G]300MAAN-373 超ド級潮吹き13発超え!天然?ぶりっ子?不思議系巨乳美女はお酒が精力増強剤♪酒を飲んだら即発情!!蛇口のパッキンがぶ</a>188</li>189<li>190<a href="thread-48857-1-1.html" target="_blank">[HD/2.30G]SIRO-3710【初撮り】ネットでAV応募→AV体験撮影 875 るな 23歳 ガールズバースタッフ</a>191</li>192<li>193<a href="thread-125158-1-1.html" target="_blank">[HD/3.20G]DTT-026 雪肌Gカップピアノ講師人妻 一ノ瀬菫 中出し懇願濃厚セックス 清楚な雪肌巨乳美人妻に大量中出し3連発!!!</a>194</li>195<li>196<a href="thread-40261-1-1.html" target="_blank">[HD/3.75G]320MMGH-045 ひろみちゃん 修学旅行 マジックミラー号 修学旅行中にショートカットの女の子が処女卒業!</a>197</li>198<li>199<a href="thread-78050-1-1.html" target="_blank">[HD/4.58G]SSNI-432 ノーブラFカップおっぱいで全力アピールしてくる彼女の巨乳妹と、誘惑に負けちゃう最低な僕。 三上悠亜</a>200</li>201<li>202<a href="thread-57253-1-1.html" target="_blank">[HD/2.88G]259LUXU-1086 ラグジュTV 1072 快楽に貪欲すぎるニュースキャスター再び!天性のドM気質はガチ!透明感溢れる美しさとは対照に</a>203</li>204<li>205<a href="thread-21033-1-1.html" target="_blank">[HD/2.67G]259LUXU-734 ラグジュTV 724 鈴村涼子 34歳 ピアノ講師</a>206</li>207</ul>208</div></div>209</div>210<div id="pgt" class="bm bw0 pgs cl">211<span id="fd_page_top"><div class="pg"><a href="forum-36-1.html" class="prev">&nbsp;&nbsp;</a><a href="forum-36-1.html">1</a><strong>2</strong><a href="forum-36-3.html">3</a><a href="forum-36-4.html">4</a><a href="forum-36-5.html">5</a><a href="forum-36-6.html">6</a><a href="forum-36-7.html">7</a><a href="forum-36-8.html">8</a><a href="forum-36-9.html">9</a><a href="forum-36-10.html">10</a><a href="forum-36-1129.html" class="last">... 1129</a><label><input type="text" name="custompage" class="px" size="2" title="输入页码,按回车快速跳转" value="2" onkeydown="if(event.keyCode==13) {window.location='forum.php?mod=forumdisplay&fid=36&amp;page='+this.value;; doane(event);}" /><span title="共 1129 页"> / 1129 页</span></label><a href="forum-36-3.html" class="nxt">下一页</a></div></span>212<span class="pgb y" ><a href="forum.php">返&nbsp;回</a></span>213<a href="javascript:;" id="newspecial" onmouseover="$('newspecial').id = 'newspecialtmp';this.id = 'newspecial';showMenu({'ctrlid':this.id})" onclick="showWindow('newthread', 'forum.php?mod=post&action=newthread&fid=36')" title="发新帖"><img src="static/image/common/pn_post.png" alt="发新帖" /></a></div>214<div id="threadlist" class="tl bm bmw">215<div class="th">216<table cellspacing="0" cellpadding="0">217<tr>218<th colspan="2">219<div class="tf">220<span id="atarget" onclick="setatarget(1)" class="y" title="在新窗口中打开帖子">新窗</span>221<a id="filter_special" href="javascript:;" class="showmenu xi2" onclick="showMenu(this.id)">全部主题</a>&nbsp; 222<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=lastpost&amp;orderby=lastpost" class="xi2">最新</a>&nbsp;223<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=heat&amp;orderby=heats" class="xi2">热门</a>&nbsp;224<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=hot" class="xi2">热帖</a>&nbsp;225<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=digest&amp;digest=1" class="xi2">精华</a>&nbsp;226<a id="filter_dateline" href="javascript:;" class="showmenu xi2" onclick="showMenu(this.id)">更多</a>&nbsp;227<span id="clearstickthread" style="display: none;">228<span class="pipe">|</span>229<a href="javascript:;" onclick="clearStickThread()" class="xi2" title="显示置顶">显示置顶</a>230</span>231</div>232</th>233<td class="by">作者</td>234<td class="num">回复/查看</td>235<td class="by">最后发表</td>236</tr>237</table>238</div>239<div class="bm_c">240<script type="text/javascript">var lasttime = 1626005543;var listcolspan= '5';</script>241<div id="forumnew" style="display:none"></div>242<form method="post" autocomplete="off" name="moderate" id="moderate" action="forum.php?mod=topicadmin&amp;action=moderate&amp;fid=36&amp;infloat=yes&amp;nopost=yes">243<input type="hidden" name="formhash" value="b6acf023" />244<input type="hidden" name="listextra" value="page%3D2" />245<table summary="forum_36" cellspacing="0" cellpadding="0" id="threadlisttableid">246<tbody id="separatorline" class="emptb"><tr><td class="icn"></td><th></th><td class="by"></td><td class="num"></td><td class="by"></td></tr></tbody>247<tbody id="normalthread_334074">248<tr>249<td class="icn">250<a href="thread-334074-1-2.html" title="新窗口打开" target="_blank">251<img src="static/image/common/folder_common.gif" />252</a>253</td>254<th class="common">255<a href="javascript:;" id="content_334074" class="showcontent y" title="更多操作" onclick="CONTENT_TID='334074';CONTENT_ID='normalthread_334074';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>256 <a href="thread-334074-1-2.html" onclick="atarget(this)" class="s xst">[HD/2.33G]435MFC-116【萌袖ピンク乳首の美少女】あざとい仕草でお持ち帰りをご要望しちゃうミーハー女子と生ハメ中出し!スタイル抜群で魅惑的ボデ...</a>257<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />258</th>259<td class="by">260<cite>261<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>262<em><span><span title="2021-7-8">3&nbsp;天前</span></span></em>263</td>264<td class="num"><a href="thread-334074-1-2.html" class="xi2">0</a><em>596</em></td>265<td class="by">266<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>267<em><a href="forum.php?mod=redirect&tid=334074&goto=lastpost#lastpost"><span title="2021-7-8 10:43">3&nbsp;天前</span></a></em>268</td>269</tr>270</tbody>271<tbody id="normalthread_334072">272<tr>273<td class="icn">274<a href="thread-334072-1-2.html" title="新窗口打开" target="_blank">275<img src="static/image/common/folder_common.gif" />276</a>277</td>278<th class="common">279<a href="javascript:;" id="content_334072" class="showcontent y" title="更多操作" onclick="CONTENT_TID='334072';CONTENT_ID='normalthread_334072';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>280 <a href="thread-334072-1-2.html" onclick="atarget(this)" class="s xst">[HD/2.54G]406FTHT-016【ドM開花宣言!激ピスイラマ!ヨダレ!乳首バサミローター絶句】親の言いなり優等生がドMに豹変!親に内緒でパイパン!紅く染...</a>281<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />282</th>283<td class="by">284<cite>285<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>286<em><span><span title="2021-7-8">3&nbsp;天前</span></span></em>287</td>288<td class="num"><a href="thread-334072-1-2.html" class="xi2">0</a><em>417</em></td>289<td class="by">290<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>291<em><a href="forum.php?mod=redirect&tid=334072&goto=lastpost#lastpost"><span title="2021-7-8 10:40">3&nbsp;天前</span></a></em>292</td>293</tr>294</tbody>295<tbody id="normalthread_334071">296<tr>297<td class="icn">298<a href="thread-334071-1-2.html" title="新窗口打开" target="_blank">299<img src="static/image/common/folder_common.gif" />300</a>301</td>302<th class="common">303<a href="javascript:;" id="content_334071" class="showcontent y" title="更多操作" onclick="CONTENT_TID='334071';CONTENT_ID='normalthread_334071';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>304 <a href="thread-334071-1-2.html" onclick="atarget(this)" class="s xst">[HD/2.99G]300NTK-588 目指せ最強えちカワグラドル!!ムチ尻Fカップの欲情同時誘発ボディのエチエチ度満点の天然美少女のグラビア撮影会にAV男優を...</a>305<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />306</th>307<td class="by">308<cite>309<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>310<em><span><span title="2021-7-8">3&nbsp;天前</span></span></em>311</td>312<td class="num"><a href="thread-334071-1-2.html" class="xi2">0</a><em>482</em></td>313<td class="by">314<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>315<em><a href="forum.php?mod=redirect&tid=334071&goto=lastpost#lastpost"><span title="2021-7-8 10:37">3&nbsp;天前</span></a></em>316</td>317</tr>318</tbody>319<tbody id="normalthread_334070">320<tr>321<td class="icn">322<a href="thread-334070-1-2.html" title="新窗口打开" target="_blank">323<img src="static/image/common/folder_common.gif" />324</a>325</td>326<th class="common">327<a href="javascript:;" id="content_334070" class="showcontent y" title="更多操作" onclick="CONTENT_TID='334070';CONTENT_ID='normalthread_334070';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>328 <a href="thread-334070-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.74G]300MIUM-711【Jカップ116cm&amp;チ●コをまるっと絡め取る長~いエロ舌】に朝から晩まで迫り倒しハメ倒し!なかなかお目にかかれないレア巨乳を...</a>329<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />330</th>331<td class="by">332<cite>333<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>334<em><span><span title="2021-7-8">3&nbsp;天前</span></span></em>335</td>336<td class="num"><a href="thread-334070-1-2.html" class="xi2">0</a><em>486</em></td>337<td class="by">338<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>339<em><a href="forum.php?mod=redirect&tid=334070&goto=lastpost#lastpost"><span title="2021-7-8 10:35">3&nbsp;天前</span></a></em>340</td>341</tr>342</tbody>343<tbody id="normalthread_334069">344<tr>345<td class="icn">346<a href="thread-334069-1-2.html" title="新窗口打开" target="_blank">347<img src="static/image/common/folder_common.gif" />348</a>349</td>350<th class="common">351<a href="javascript:;" id="content_334069" class="showcontent y" title="更多操作" onclick="CONTENT_TID='334069';CONTENT_ID='normalthread_334069';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>352 <a href="thread-334069-1-2.html" onclick="atarget(this)" class="s xst">[HD/2.51G]200GANA-2511 マジ軟派、初撮。 1651 おっとりしてそうに見えてHな話にも意外と寛容!流されやすそうな性格に漬け込んで謝礼を提示すると…...</a>353<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />354</th>355<td class="by">356<cite>357<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>358<em><span><span title="2021-7-8">3&nbsp;天前</span></span></em>359</td>360<td class="num"><a href="thread-334069-1-2.html" class="xi2">0</a><em>408</em></td>361<td class="by">362<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>363<em><a href="forum.php?mod=redirect&tid=334069&goto=lastpost#lastpost"><span title="2021-7-8 10:30">3&nbsp;天前</span></a></em>364</td>365</tr>366</tbody>367<tbody id="normalthread_333692">368<tr>369<td class="icn">370<a href="thread-333692-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">371<img src="static/image/common/folder_lock.gif" />372</a>373</td>374<th class="lock">375<a href="javascript:;" id="content_333692" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333692';CONTENT_ID='normalthread_333692';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>376 <a href="thread-333692-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.18G]WAAA-067 「えっ!今、中に出したでしょ?」早漏をゴマかす暴発後の延長ピストンで抜かずの追撃中出し!! 白桃はな</a>377<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />378</th>379<td class="by">380<cite>381<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>382<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>383</td>384<td class="num"><a href="thread-333692-1-2.html" class="xi2">0</a><em>685</em></td>385<td class="by">386<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>387<em><a href="forum.php?mod=redirect&tid=333692&goto=lastpost#lastpost"><span title="2021-7-7 11:42">4&nbsp;天前</span></a></em>388</td>389</tr>390</tbody>391<tbody id="normalthread_333691">392<tr>393<td class="icn">394<a href="thread-333691-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">395<img src="static/image/common/folder_lock.gif" />396</a>397</td>398<th class="lock">399<a href="javascript:;" id="content_333691" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333691';CONTENT_ID='normalthread_333691';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>400 <a href="thread-333691-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.53G]STARS-415 『世界で1番エロいキスしてみない?』理性を忘れて舐めまくる感じる唇、終わらない接吻。 紗倉まな</a>401<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />402</th>403<td class="by">404<cite>405<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>406<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>407</td>408<td class="num"><a href="thread-333691-1-2.html" class="xi2">0</a><em>534</em></td>409<td class="by">410<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>411<em><a href="forum.php?mod=redirect&tid=333691&goto=lastpost#lastpost"><span title="2021-7-7 11:39">4&nbsp;天前</span></a></em>412</td>413</tr>414</tbody>415<tbody id="normalthread_333690">416<tr>417<td class="icn">418<a href="thread-333690-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">419<img src="static/image/common/folder_lock.gif" />420</a>421</td>422<th class="lock">423<a href="javascript:;" id="content_333690" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333690';CONTENT_ID='normalthread_333690';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>424 <a href="thread-333690-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.58G]STARS-389 死ぬほど嫌われている隣人のキモ親父が、新婚妻をメロメロ・アヘアへ肉便器に催●洗脳できちゃいました。 本庄鈴</a>425<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />426</th>427<td class="by">428<cite>429<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>430<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>431</td>432<td class="num"><a href="thread-333690-1-2.html" class="xi2">0</a><em>586</em></td>433<td class="by">434<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>435<em><a href="forum.php?mod=redirect&tid=333690&goto=lastpost#lastpost"><span title="2021-7-7 11:36">4&nbsp;天前</span></a></em>436</td>437</tr>438</tbody>439<tbody id="normalthread_333689">440<tr>441<td class="icn">442<a href="thread-333689-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">443<img src="static/image/common/folder_lock.gif" />444</a>445</td>446<th class="lock">447<a href="javascript:;" id="content_333689" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333689';CONTENT_ID='normalthread_333689';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>448 <a href="thread-333689-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.53G]SSIS-099 スク水マニアに狙われて… 粘着ストーカーの狂気的な盗撮に全てを晒され輪●された制服少女 山崎水愛</a>449<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />450</th>451<td class="by">452<cite>453<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>454<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>455</td>456<td class="num"><a href="thread-333689-1-2.html" class="xi2">0</a><em>567</em></td>457<td class="by">458<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>459<em><a href="forum.php?mod=redirect&tid=333689&goto=lastpost#lastpost"><span title="2021-7-7 11:31">4&nbsp;天前</span></a></em>460</td>461</tr>462</tbody>463<tbody id="normalthread_333688">464<tr>465<td class="icn">466<a href="thread-333688-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">467<img src="static/image/common/folder_lock.gif" />468</a>469</td>470<th class="lock">471<a href="javascript:;" id="content_333688" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333688';CONTENT_ID='normalthread_333688';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>472 <a href="thread-333688-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.14G]PPPD-937 神スレンダー巨乳お姉さんが時間無制限でぶっ通し射精させてくれる高級下着メーカー直営メンズエステ 夏希まろん</a>473<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />474</th>475<td class="by">476<cite>477<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>478<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>479</td>480<td class="num"><a href="thread-333688-1-2.html" class="xi2">0</a><em>636</em></td>481<td class="by">482<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>483<em><a href="forum.php?mod=redirect&tid=333688&goto=lastpost#lastpost"><span title="2021-7-7 11:28">4&nbsp;天前</span></a></em>484</td>485</tr>486</tbody>487<tbody id="normalthread_333687">488<tr>489<td class="icn">490<a href="thread-333687-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">491<img src="static/image/common/folder_lock.gif" />492</a>493</td>494<th class="lock">495<a href="javascript:;" id="content_333687" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333687';CONTENT_ID='normalthread_333687';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>496 <a href="thread-333687-1-2.html" onclick="atarget(this)" class="s xst">[HD/6.21G]HUNTB-049 高瀬りな・小梅えな・真田さな・辻さくら ノーブラ+キャミソール×地味隠れ巨乳義姉=乳首が透けるほどおっぱい舐め回していいっ...</a>497<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />498</th>499<td class="by">500<cite>501<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>502<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>503</td>504<td class="num"><a href="thread-333687-1-2.html" class="xi2">0</a><em>501</em></td>505<td class="by">506<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>507<em><a href="forum.php?mod=redirect&tid=333687&goto=lastpost#lastpost"><span title="2021-7-7 11:26">4&nbsp;天前</span></a></em>508</td>509</tr>510</tbody>511<tbody id="normalthread_333686">512<tr>513<td class="icn">514<a href="thread-333686-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">515<img src="static/image/common/folder_lock.gif" />516</a>517</td>518<th class="lock">519<a href="javascript:;" id="content_333686" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333686';CONTENT_ID='normalthread_333686';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>520 <a href="thread-333686-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.52G]DTT-081 8年間セックスレス シングルマザー 美巨乳中学校教師 百合原かおり 47歳 中出し3P AVデビュー!! 長年持て余した豊満ボディがカメラ...</a>521<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />522</th>523<td class="by">524<cite>525<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>526<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>527</td>528<td class="num"><a href="thread-333686-1-2.html" class="xi2">0</a><em>506</em></td>529<td class="by">530<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>531<em><a href="forum.php?mod=redirect&tid=333686&goto=lastpost#lastpost"><span title="2021-7-7 11:21">4&nbsp;天前</span></a></em>532</td>533</tr>534</tbody>535<tbody id="normalthread_333685">536<tr>537<td class="icn">538<a href="thread-333685-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">539<img src="static/image/common/folder_lock.gif" />540</a>541</td>542<th class="lock">543<a href="javascript:;" id="content_333685" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333685';CONTENT_ID='normalthread_333685';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>544 <a href="thread-333685-1-2.html" onclick="atarget(this)" class="s xst">[HD/4.77G]ABW-111 アオハル 制服美少女と完全主観で過ごす性春3SEX。 #06 エッチで甘酸っぱい青春グラフィティを全てあなた視点で体験する165分</a>545<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />546</th>547<td class="by">548<cite>549<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>550<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>551</td>552<td class="num"><a href="thread-333685-1-2.html" class="xi2">0</a><em>511</em></td>553<td class="by">554<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>555<em><a href="forum.php?mod=redirect&tid=333685&goto=lastpost#lastpost"><span title="2021-7-7 11:19">4&nbsp;天前</span></a></em>556</td>557</tr>558</tbody>559<tbody id="normalthread_333684">560<tr>561<td class="icn">562<a href="thread-333684-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">563<img src="static/image/common/folder_lock.gif" />564</a>565</td>566<th class="lock">567<a href="javascript:;" id="content_333684" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333684';CONTENT_ID='normalthread_333684';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>568 <a href="thread-333684-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.13G]WAAA-077 終電を逃した僕を泊めてくれたバイトの先輩… ノーブラ部屋着から弾け出たおっぱいブルンに我慢できず夜明けまでヤリまくった!...</a>569<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />570</th>571<td class="by">572<cite>573<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>574<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>575</td>576<td class="num"><a href="thread-333684-1-2.html" class="xi2">0</a><em>480</em></td>577<td class="by">578<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>579<em><a href="forum.php?mod=redirect&tid=333684&goto=lastpost#lastpost"><span title="2021-7-7 11:14">4&nbsp;天前</span></a></em>580</td>581</tr>582</tbody>583<tbody id="normalthread_333683">584<tr>585<td class="icn">586<a href="thread-333683-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">587<img src="static/image/common/folder_lock.gif" />588</a>589</td>590<th class="lock">591<a href="javascript:;" id="content_333683" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333683';CONTENT_ID='normalthread_333683';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>592 <a href="thread-333683-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.91G]WAAA-075 射精しても男潮吹いてもチ●ポしゃぶり続けてやるからな!! つぼみ</a>593<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />594</th>595<td class="by">596<cite>597<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>598<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>599</td>600<td class="num"><a href="thread-333683-1-2.html" class="xi2">0</a><em>450</em></td>601<td class="by">602<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>603<em><a href="forum.php?mod=redirect&tid=333683&goto=lastpost#lastpost"><span title="2021-7-7 11:11">4&nbsp;天前</span></a></em>604</td>605</tr>606</tbody>607<tbody id="normalthread_333682">608<tr>609<td class="icn">610<a href="thread-333682-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">611<img src="static/image/common/folder_lock.gif" />612</a>613</td>614<th class="lock">615<a href="javascript:;" id="content_333682" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333682';CONTENT_ID='normalthread_333682';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>616 <a href="thread-333682-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.13G]WAAA-074 「もうイッてるってばぁ!」状態で何度も中出し! 白川ゆず</a>617<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />618</th>619<td class="by">620<cite>621<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>622<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>623</td>624<td class="num"><a href="thread-333682-1-2.html" class="xi2">0</a><em>410</em></td>625<td class="by">626<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>627<em><a href="forum.php?mod=redirect&tid=333682&goto=lastpost#lastpost"><span title="2021-7-7 11:09">4&nbsp;天前</span></a></em>628</td>629</tr>630</tbody>631<tbody id="normalthread_333681">632<tr>633<td class="icn">634<a href="thread-333681-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">635<img src="static/image/common/folder_lock.gif" />636</a>637</td>638<th class="lock">639<a href="javascript:;" id="content_333681" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333681';CONTENT_ID='normalthread_333681';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>640 <a href="thread-333681-1-2.html" onclick="atarget(this)" class="s xst">[HD/2.04G]SIRO-4526【初撮り】【揺れる天然G乳】牛タン屋で働くGカップお姉さん。スケベな本性をさらけ出し、蕩けていく清楚顔は必見。 応募素人、...</a>641<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />642</th>643<td class="by">644<cite>645<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>646<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>647</td>648<td class="num"><a href="thread-333681-1-2.html" class="xi2">0</a><em>537</em></td>649<td class="by">650<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>651<em><a href="forum.php?mod=redirect&tid=333681&goto=lastpost#lastpost"><span title="2021-7-7 11:02">4&nbsp;天前</span></a></em>652</td>653</tr>654</tbody>655<tbody id="normalthread_333680">656<tr>657<td class="icn">658<a href="thread-333680-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">659<img src="static/image/common/folder_lock.gif" />660</a>661</td>662<th class="lock">663<a href="javascript:;" id="content_333680" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333680';CONTENT_ID='normalthread_333680';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>664 <a href="thread-333680-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.78G]MIDE-945 Hカップおっぱいパイズリ挟射フルコース 高画質揺れ乳ALLパイズリ挟射 中山ふみか</a>665<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />666</th>667<td class="by">668<cite>669<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>670<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>671</td>672<td class="num"><a href="thread-333680-1-2.html" class="xi2">0</a><em>474</em></td>673<td class="by">674<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>675<em><a href="forum.php?mod=redirect&tid=333680&goto=lastpost#lastpost"><span title="2021-7-7 10:59">4&nbsp;天前</span></a></em>676</td>677</tr>678</tbody>679<tbody id="normalthread_333679">680<tr>681<td class="icn">682<a href="thread-333679-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">683<img src="static/image/common/folder_lock.gif" />684</a>685</td>686<th class="lock">687<a href="javascript:;" id="content_333679" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333679';CONTENT_ID='normalthread_333679';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>688 <a href="thread-333679-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.07G]MIDE-944 巨根生徒の誘いに負けてしまった新任女教師 琴音華</a>689<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />690</th>691<td class="by">692<cite>693<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>694<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>695</td>696<td class="num"><a href="thread-333679-1-2.html" class="xi2">0</a><em>502</em></td>697<td class="by">698<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>699<em><a href="forum.php?mod=redirect&tid=333679&goto=lastpost#lastpost"><span title="2021-7-7 10:55">4&nbsp;天前</span></a></em>700</td>701</tr>702</tbody>703<tbody id="normalthread_333678">704<tr>705<td class="icn">706<a href="thread-333678-1-2.html" title="关闭的主题 - 新窗口打开" target="_blank">707<img src="static/image/common/folder_lock.gif" />708</a>709</td>710<th class="lock">711<a href="javascript:;" id="content_333678" class="showcontent y" title="更多操作" onclick="CONTENT_TID='333678';CONTENT_ID='normalthread_333678';showMenu({'ctrlid':this.id,'menuid':'content_menu'})"></a>712 <a href="thread-333678-1-2.html" onclick="atarget(this)" class="s xst">[HD/3.76G]MIDE-943 感度爆上がりボディを一日中ぶっ通しでハメまくる ノンストップ無限オーガズムキメセク潮吹き超絶頂 高橋しょう子</a>713<img src="static/image/filetype/common.gif" alt="attachment" title="附件" align="absmiddle" />714</th>715<td class="by">716<cite>717<a href="space-uid-14.html" c="1" style="color: #999900;">kindler</a></cite>718<em><span><span title="2021-7-7">4&nbsp;天前</span></span></em>719</td>720<td class="num"><a href="thread-333678-1-2.html" class="xi2">0</a><em>527</em></td>721<td class="by">722<cite><a href="space-username-kindler.html" c="1">kindler</a></cite>723<em><a href="forum.php?mod=redirect&tid=333678&goto=lastpost#lastpost"><span title="2021-7-7 10:53">4&nbsp;天前</span></a></em>724</td>725</tr>726</tbody>727</table><!-- end of table "forum_G[fid]" branch 1/3 -->728</form>729</div>730</div>731<div id="filter_special_menu" class="p_pop" style="display:none" change="location.href='forum.php?mod=forumdisplay&fid=36&filter='+$('filter_special').value">732<ul>733<li><a href="forum-36-1.html">全部主题</a></li>734<li><a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=specialtype&amp;specialtype=poll">投票</a></li></ul>735</div>736<div id="filter_reward_menu" class="p_pop" style="display:none" change="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=specialtype&amp;specialtype=reward&amp;rewardtype='+$('filter_reward').value">737<ul>738<li><a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=specialtype&amp;specialtype=reward">全部悬赏</a></li>739<li><a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=specialtype&amp;specialtype=reward&amp;rewardtype=1">进行中</a></li></ul>740</div>741<div id="filter_dateline_menu" class="p_pop" style="display:none">742<ul class="pop_moremenu">743<li>排序: 744<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=author&amp;orderby=dateline" class="xw1">发帖时间</a><span class="pipe">|</span>745<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=reply&amp;orderby=replies" >回复/查看</a><span class="pipe">|</span>746<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=reply&amp;orderby=views" >查看</a>747</li>748<li>时间: 749<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;orderby=dateline&amp;filter=dateline" class="xw1">全部时间</a><span class="pipe">|</span>750<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;orderby=dateline&amp;filter=dateline&amp;dateline=86400" >一天</a><span class="pipe">|</span>751<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;orderby=dateline&amp;filter=dateline&amp;dateline=172800" >两天</a><span class="pipe">|</span>752<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;orderby=dateline&amp;filter=dateline&amp;dateline=604800" >一周</a><span class="pipe">|</span>753<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;orderby=dateline&amp;filter=dateline&amp;dateline=2592000" >一个月</a><span class="pipe">|</span>754<a href="forum.php?mod=forumdisplay&amp;fid=36&amp;orderby=dateline&amp;filter=dateline&amp;dateline=7948800" >三个月</a>755</li>756</ul>757</div>758<div id="filter_orderby_menu" class="p_pop" style="display:none">759<ul>760<li><a href="forum-36-1.html">默认排序</a></li>761<li><a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=author&amp;orderby=dateline">发帖时间</a></li>762<li><a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=reply&amp;orderby=replies">回复/查看</a></li>763<li><a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=reply&amp;orderby=views">查看</a></li>764<li><a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=lastpost&amp;orderby=lastpost">最后发表</a></li>765<li><a href="forum.php?mod=forumdisplay&amp;fid=36&amp;filter=heat&amp;orderby=heats">热门</a></li>766</ul>767</div>768<a class="bm_h" href="javascript:;" rel="forum.php?mod=forumdisplay&fid=36&page=3" curpage="2" id="autopbn" totalpage="1129" picstyle="0" forumdefstyle="">下一页 &raquo;</a>769<script src="static/js/autoloadpage.js?vUs" type="text/javascript"></script>770<div class="bm bw0 pgs cl">771<span id="fd_page_bottom"><div class="pg"><a href="forum-36-1.html" class="prev">&nbsp;&nbsp;</a><a href="forum-36-1.html">1</a><strong>2</strong><a href="forum-36-3.html">3</a><a href="forum-36-4.html">4</a><a href="forum-36-5.html">5</a><a href="forum-36-6.html">6</a><a href="forum-36-7.html">7</a><a href="forum-36-8.html">8</a><a href="forum-36-9.html">9</a><a href="forum-36-10.html">10</a><a href="forum-36-1129.html" class="last">... 1129</a><label><input type="text" name="custompage" class="px" size="2" title="输入页码,按回车快速跳转" value="2" onkeydown="if(event.keyCode==13) {window.location='forum.php?mod=forumdisplay&fid=36&amp;page='+this.value;; doane(event);}" /><span title="共 1129 页"> / 1129 页</span></label><a href="forum-36-3.html" class="nxt">下一页</a></div></span>772<span class="pgb y"><a href="forum.php">返&nbsp;回</a></span>773<a href="javascript:;" id="newspecialtmp" onmouseover="$('newspecial').id = 'newspecialtmp';this.id = 'newspecial';showMenu({'ctrlid':this.id})" onclick="showWindow('newthread', 'forum.php?mod=post&action=newthread&fid=36')" title="发新帖"><img src="static/image/common/pn_post.png" alt="发新帖" /></a></div>774<!--[diy=diyfastposttop]--><div id="diyfastposttop" class="area"><div id="frameKrlJ6L" class="frame move-span cl frame-1"><div id="frameKrlJ6L_left" class="column frame-1-c"><div id="frameKrlJ6L_left_temp" class="move-span temp"></div><div id="portal_block_12" class="block move-span"><div id="portal_block_12_content" class="dxb_bc"><div class="portal_block_summary"><table style="width:100%;" cellpadding="2" cellspacing="0" border="1" bordercolor="#000000">775 <tbody>776 <tr>777 <td>778 <p>779 <span style="font-family:KaiTi_GB2312;color:#009900;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="https://202900.com:2262?register=1" target="_blank"><span style="color:#009900;font-size:18px;"><strong>❤️一夜暴富 嫩模空姐任你选 ❤️</strong></span></a></span> 780 </p>781 </td>782 <td>783 <p>784 <span style="font-family:KaiTi_GB2312;color:#E56600;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<a href="https://aoluoluo.info/?u=UIJYhNvfICHU" target="_blank"><span style="color:#E56600;font-size:18px;"><strong>全国小姐 同城楼凤</strong></span></a></span> 785 </p>786 </td>787 <td>788 <p>789 <span style="font-family:KaiTi_GB2312;color:#009900;">&nbsp; &nbsp; &nbsp;&nbsp;<a href="https://cej.54647.blog/" target="_blank"><span style="color:#009900;font-size:18px;"><strong>免費18禁美少女手遊戲</strong></span></a></span> 790 </p>791 </td>792 <td>793 <p>794 <span style="font-family:KaiTi_GB2312;color:#E56600;">&nbsp; &nbsp; &nbsp;&nbsp;<a href="http://www.uut92.com/" target="_blank"><span style="color:#E56600;font-size:18px;"><strong>台湾uu裸聊直播</strong></span></a></span> 795 </p>796 </td>797 </tr>798 </tbody>799</table>800<br /></div></div></div></div></div></div><!--[/diy]-->801<script type="text/javascript">802var postminchars = parseInt('10');803var postmaxchars = parseInt('200000');804var disablepostctrl = parseInt('0');805var fid = parseInt('36');806</script>807<div id="f_pst" class="bm">808<div class="bm_h">809<h2>快速发帖</h2>810</div>811<div class="bm_c">812<form method="post" autocomplete="off" id="fastpostform" action="forum.php?mod=post&amp;action=newthread&amp;fid=36&amp;topicsubmit=yes&amp;infloat=yes&amp;handlekey=fastnewpost" onSubmit="return fastpostvalidate(this)">813<div id="fastpostreturn" style="margin:-5px 0 5px"></div>814<div class="pbt cl">815<input type="text" id="subject" name="subject" class="px" value="" onkeyup="strLenCalc(this, 'checklen', 200);" tabindex="11" style="width: 25em" />816<span>还可输入 <strong id="checklen">200</strong> 个字符</span>817</div>818<div class="cl">819<div id="fastsmiliesdiv" class="y"><div id="fastsmiliesdiv_data"><div id="fastsmilies"></div></div></div><div class="hasfsl" id="fastposteditor">820<div class="tedt">821<div class="bar">822<span class="y">823<a href="forum.php?mod=post&amp;action=newthread&amp;fid=36" onclick="switchAdvanceMode(this.href);doane(event);">高级模式</a>824</span><script src="static/js/seditor.js?vUs" type="text/javascript"></script>825<div class="fpd">826<a href="javascript:;" title="文字加粗" class="fbld">B</a>827<a href="javascript:;" title="设置文字颜色" class="fclr" id="fastpostforecolor">Color</a>828<a id="fastpostimg" href="javascript:;" title="图片" class="fmg">Image</a>829<a id="fastposturl" href="javascript:;" title="添加链接" class="flnk">Link</a>830<a id="fastpostquote" href="javascript:;" title="引用" class="fqt">Quote</a>831<a id="fastpostcode" href="javascript:;" title="代码" class="fcd">Code</a>832<a href="javascript:;" class="fsml" id="fastpostsml">Smilies</a>833</div></div>834<div class="area">835<div class="pt hm">836您需要登录后才可以发帖 <a href="member.php?mod=logging&amp;action=login" onclick="showWindow('login', this.href)" class="xi2">登录</a> | <a href="member.php?mod=zbucihd4k" class="xi2">立即注册</a>837</div>838</div>839</div>840</div>841<div id="seccheck_fastpost">842</div>843<input type="hidden" name="formhash" value="b6acf023" />844<input type="hidden" name="usesig" value="" />845</div>846<p class="ptm pnpost">847<a href="home.php?mod=spacecp&amp;ac=credit&amp;op=rule&amp;fid=36" class="y" target="_blank">本版积分规则</a>848<button type="submit" onmouseover="checkpostrule('seccheck_fastpost', 'ac=newthread');this.onmouseover=null" name="topicsubmit" id="fastpostsubmit" value="topicsubmit" tabindex="13" class="pn pnc"><strong>发表帖子</strong></button>849</p>850</form>851</div>852</div>853<!--[diy=diyforumdisplaybottom]--><div id="diyforumdisplaybottom" class="area"></div><!--[/diy]-->854</div>855</div>856</div>857<div class="wp mtn">858<!--[diy=diy3]--><div id="diy3" class="area"></div><!--[/diy]-->859</div>860<script>fixed_top_nv();</script> </div>861<div id="ft" class="wp cl">862<div id="flk" class="y">863<p>864<a href="archiver/" >Archiver</a><span class="pipe">|</span><a href="forum.php?mobile=yes" >手机版</a><span class="pipe">|</span><a href="/cdn-cgi/l/email-protection#781e1714141f0d010a0f38080a170c171615191114561b10" style="font-weight: bold;color: red">DMCA</a><span class="pipe">|</span><strong><a href="https://www.889dog.com/" target="_blank">高清下载吧!</a></strong>865<!-- Global site tag (gtag.js) - Google Analytics -->866<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script async src="https://www.googletagmanager.com/gtag/js?id=UA-151112001-1"></script>867<script>868 window.dataLayer = window.dataLayer || [];869 function gtag(){dataLayer.push(arguments);}870 gtag('js', new Date());871 gtag('config', 'UA-151112001-1');872</script>873</p>874<p class="xs0">875GMT+8, 2021-7-11 20:12<span id="debuginfo">876, Processed in 0.258063 second(s), 18 queries877, Gzip On, Redis On.878</span>879</p>880</div>881<div id="frt">882<p>Powered by <strong><a href="http://www.discuz.net" target="_blank">Discuz!</a></strong> <em>X3.4</em></p>883<p class="xs0">&copy; 2001-2017 <a href="http://www.comsenz.com" target="_blank">Comsenz Inc.</a></p>884</div></div>885<script src="home.php?mod=misc&ac=sendmail&rand=1626005543" type="text/javascript"></script>886<div id="scrolltop">887<span hidefocus="true"><a title="返回顶部" onclick="window.scrollTo('0','0')" class="scrolltopa" ><b>返回顶部</b></a></span>888<span>889<a href="forum.php" hidefocus="true" class="returnboard" title="返回版块"><b>返回版块</b></a>890</span>891</div>892<script type="text/javascript">_attachEvent(window, 'scroll', function () { showTopLink(); });checkBlind();</script>893</body>894</html>895`896func main() {897 doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))898 if err != nil {899 msg := fmt.Sprintf("html 转换doc失败: %s", err.Error())900 panic(errors.New(msg))901 }902 //doc.Find("a[class$='s xst']").Each(func(i int, s *goquery.Selection) {903 doc.Find("a:contains(中山ふ)").Each(func(i int, s *goquery.Selection) {904 fmt.Println(s.Text())905 })906}...

Full Screen

Full Screen

sanitize_test.go

Source:sanitize_test.go Github

copy

Full Screen

1// Copyright 2011 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4package template5import (6 "bytes"7 "io/ioutil"8 "os"9 "path/filepath"10 "regexp"11 "strings"12 "testing"13 "github.com/google/safehtml"14 "github.com/google/safehtml/testconversions"15)16func TestDynamicElementNamePrefixEscaped(t *testing.T) {17 for _, test := range [...]struct {18 input, want string19 }{20 {21 `<{{if 1}}area{{else}}link{{end}} title="bar">`,22 `&lt;area title="bar">`,23 },24 {25 `<{{ "FOO" }} title="bar">`,26 `&lt;FOO title="bar">`,27 },28 {29 `<{{ "FOO" }}a title="bar">`,30 `&lt;FOOa title="bar">`,31 },32 {33 `<{{"script"}}>{{"doEvil()"}}</{{"script"}}>`,34 `&lt;script>doEvil()&lt;/script>`,35 },36 } {37 tmpl := Must(New(test.input).Parse(stringConstant(test.input)))38 var b bytes.Buffer39 err := tmpl.Execute(&b, nil)40 if err != nil {41 t.Errorf("%s : template execution failed:\n%s", test.input, err)42 continue43 }44 if got := b.String(); got != test.want {45 t.Errorf("%s : escaped output: got\n\t%s\nwant\n\t%s", test.input, got, test.want)46 }47 }48}49func TestConditionalElementOrAttributeAllowed(t *testing.T) {50 data := struct {51 A safehtml.Identifier52 B []string53 C, D bool54 X string55 }{56 A: safehtml.IdentifierFromConstant("id"),57 B: []string{"foo", "bar"},58 C: false,59 D: true,60 X: "hello",61 }62 for _, test := range [...]string{63 // Conditional element names that lead to the same element content sanitization64 // contexts are allowed.65 `{{if .C}}<object></object>{{end}}{{ .X }}`,66 `{{if .C}}<a>{{end}}{{ .X }}`,67 `{{if .C}}<a{{else}}<b{{end}}>{{ .X }}`,68 `{{if .C}}<a>{{else}}<b>{{end}}{{ .X }}`,69 `{{if .C}}<a>{{else if .D}}<b>{{else}}<h1>{{end}}{{ .X }}`,70 `{{range .B}}<object></object>{{end}}{{ .X }}`,71 `{{range .B}}<a>{{end}}{{ .X }}`,72 `{{range .B}}<a>{{else}}<b>{{end}}{{ .X }}`,73 `{{with .C}}<object></object>{{end}}{{ .X }}`,74 `{{with .C}}<a>{{end}}{{ .X }}`,75 `{{with .C}}<a{{else}}<b{{end}}>{{ .X }}`,76 `{{with .C}}<a>{{else}}<b>{{end}}{{ .X }}`,77 // Conditional element or attribute names that lead to the same attribute value sanitization78 // contexts are allowed.79 `<input{{if .C}} checked{{end}} name="foo">`,80 `{{if .C}}<img{{else}}<audio{{end}} src="{{ .X }}">`,81 `{{if .C}}<img{{else if .D}}<audio{{else}}<input{{end}} src="{{ .X }}">`,82 `<label {{if .C}}lang{{else}}translate{{end}}="{{ .A }}">`,83 `<label {{if .C}}lang{{else if .D}}translate{{else}}spellcheck{{end}}="{{ .A }}">`,84 `<label {{range .B}}lang{{else}}translate{{end}}="{{ .A }}">`,85 `{{with .C}}<img{{else}}<audio{{end}} src="{{ .A }}">`,86 `<label {{with .C}}lang{{else}}translate{{end}}="{{ .A }}">`,87 // Conditional insertion of an attribute-value pair with a fixed attribute name is allowed, even if the88 // attributes have different sanitization contexts.89 `<a {{if .C}}id="{{ .A }}"{{end}}>foo</a>`,90 `<a {{if .C}}id="{{ .A }}"{{else}}href="{{ .X }}"{{end}}>foo</a>`,91 `<a {{if .C}}id="{{ .A }}"{{else if .D}}href="{{ .X }}"{{else}}class="{{ .X }}"{{end}}>foo</a>`,92 `<a {{with .C}}id="{{ .A }}"{{end}}>foo</a>`,93 `<a {{with .C}}id="{{ .A }}"{{else}}href="{{ .X }}"{{end}}>foo</a>`,94 } {95 tmpl := Must(New(test).Parse(stringConstant(test)))96 var b bytes.Buffer97 err := tmpl.Execute(&b, data)98 if err != nil {99 t.Errorf("unexpected an error for template %s :\n\t%s", test, err)100 continue101 }102 }103}104func TestConditionalElementOrAttributeErrorMessage(t *testing.T) {105 // The conditional branch error message prefix should only be emitted for templates with106 // a conditional branching error.107 conditionalBranchMsgPattern := regexp.MustCompile(`conditional branch with .* results in sanitization error: `)108 for _, test := range [...]struct {109 in, err string110 hasConditionalBranchMsg bool111 }{112 {113 `<option foo="{{ . }}">`,114 `actions must not occur in the "foo" attribute value context of a "option" element`,115 false,116 },117 {118 `<option {{if .X}}foo{{else}}bar{{end}}="{{ . }}">`,119 `actions must not occur in the "foo" attribute value context of a "option" element`,120 true,121 },122 {123 `<foo>{{ . }}</foo>`,124 `actions must not occur in the element content context of a "foo" element`,125 false,126 },127 {128 `{{if .X}}<foo>{{else}}<bar>{{end}}{{ . }}</imaginaryelement>`,129 `actions must not occur in the element content context of a "foo" element`,130 true,131 },132 } {133 tmpl := Must(New("").Parse(stringConstant(test.in)))134 var b bytes.Buffer135 err := tmpl.Execute(&b, nil)136 if err == nil {137 t.Fatalf("expected an error")138 }139 got := err.Error()140 hasConditionalBranchMsg := conditionalBranchMsgPattern.MatchString(got)141 if hasConditionalBranchMsg && !test.hasConditionalBranchMsg {142 t.Errorf("%s : error message unexpectedly reports conditional branching failure:\n\t%q", test.in, got)143 } else if !hasConditionalBranchMsg && test.hasConditionalBranchMsg {144 t.Errorf("%s : error message does not report conditional branching failure:\n\t%q", test.in, got)145 }146 if !strings.Contains(got, test.err) {147 t.Errorf("error\n\t%s\ndoes not contain expected string\n\t%s", got, test.err)148 }149 }150}151// TestNilEmptySliceData test that nil and empty slice data is rendered sensibly and without error.152func TestNilEmptySliceData(t *testing.T) {153 tt := Must(New("").Parse(`<b>{{ . }}</b>`))154 for _, test := range [...]struct {155 desc string156 in interface{}157 want string158 }{159 {"nil", nil, testNilEmptySliceDataNilWant},160 {"zero-length slice", []string{}, "<b>[]</b>"},161 {"slice containing nil", []interface{}{nil}, "<b>[&lt;nil&gt;]</b>"},162 } {163 var b bytes.Buffer164 err := tt.Execute(&b, test.in)165 if err != nil {166 t.Fatalf("%s: unexpected error: %s", test.desc, err)167 }168 if got := b.String(); got != test.want {169 t.Errorf("%s: got %q, want %q", test.desc, got, test.want)170 }171 }172}173var testConversionFuncs = FuncMap{174 "makeHTMLForTest": func(s string) safehtml.HTML { return testconversions.MakeHTMLForTest(s) },175 "makeURLForTest": func(s string) safehtml.URL { return testconversions.MakeURLForTest(s) },176 "makeTrustedResourceURLForTest": func(s string) safehtml.TrustedResourceURL { return testconversions.MakeTrustedResourceURLForTest(s) },177 "makeStyleForTest": func(s string) safehtml.Style { return testconversions.MakeStyleForTest(s) },178 "makeStyleSheetForTest": func(s string) safehtml.StyleSheet { return testconversions.MakeStyleSheetForTest(s) },179 "makeScriptForTest": func(s string) safehtml.Script { return testconversions.MakeScriptForTest(s) },180 "makeIdentifierForTest": func(s string) safehtml.Identifier { return testconversions.MakeIdentifierForTest(s) },181}182func TestSanitize(t *testing.T) {183 data := struct {184 T bool185 A, E []string186 QueryParams map[string]string187 }{188 T: true,189 A: []string{"<a>", "<b>"},190 E: []string{},191 QueryParams: map[string]string{"k1": "v1", "k2": "v2", "k3": "v3"},192 }193 for _, test := range [...]struct {194 input string195 output string196 err string197 }{198 // Overescaping.199 {200 input: `Hello, {{"<Cincinnati>" | html}}!`,201 output: "Hello, &lt;Cincinnati&gt;!",202 err: ``,203 },204 {205 input: `Hello, {{html "<Cincinnati>"}}!`,206 output: "Hello, &lt;Cincinnati&gt;!",207 err: ``,208 },209 {210 input: `{{with "<Cincinnati>"}}{{$msg := .}}Hello, {{$msg}}!{{end}}`,211 output: "Hello, &lt;Cincinnati&gt;!",212 err: ``,213 },214 // Assignment.215 {216 input: `{{if $x := "<Hello>"}}{{$x}}{{end}}`,217 output: "&lt;Hello&gt;",218 err: ``,219 },220 // if else.221 {222 input: `{{if 1}}Hello{{end}}, {{"<Cincinnati>"}}!`,223 output: `Hello, &lt;Cincinnati&gt;!`,224 err: ``,225 },226 {227 input: `{{if 0}}{{"<Hello>"}}{{else}}{{"<Goodbye>"}}{{end}}!`,228 output: `&lt;Goodbye&gt;!`,229 err: ``,230 },231 // with body.232 {233 input: `{{with "<Hello>"}}{{.}}{{end}}`,234 output: "&lt;Hello&gt;",235 err: ``,236 },237 // with-else.238 {239 input: `{{with .E}}{{.}}{{else}}{{"<Hello>"}}{{end}}`,240 output: "&lt;Hello&gt;",241 err: ``,242 },243 // range body.244 {245 input: "{{range .A}}{{.}}{{end}}",246 output: "&lt;a&gt;&lt;b&gt;",247 err: ``,248 },249 // range-else.250 {251 input: `{{range .E}}{{.}}{{else}}{{"<Hello>"}}{{end}}`,252 output: "&lt;Hello&gt;",253 err: ``,254 },255 // Non-string value.256 {257 input: "{{.T}}",258 output: "true",259 err: ``,260 },261 // Multiple attributes.262 {263 input: `<a width="1" value="{{"<Hello>"}}">`,264 output: `<a width="1" value="&lt;Hello&gt;">`,265 err: ``,266 },267 // HTML comment ignored.268 {269 input: `<b>Hello, <!-- name of world -->{{"<Cincinnati>"}}</b>`,270 output: "<b>Hello, &lt;Cincinnati&gt;</b>",271 err: ``,272 },273 {274 input: `<!-- -{{""}}-> <script -->{{"doEvil()//"}}<!-- -{{""}}-> </script -->`,275 output: `doEvil()//`,276 err: ``,277 },278 // HTML comment not first < in text node.279 {280 input: "<<!-- -->!--",281 output: "&lt;!--",282 err: ``,283 },284 {285 input: `<<!-- -->script>{{"doEvil()"}}<<!-- -->/script>`,286 output: `&lt;script>doEvil()&lt;/script>`,287 err: ``,288 },289 // Split HTML comment.290 {291 input: `<b>Hello, <!-- name of {{if 1}}city -->{{"<Cincinnati>"}}{{else}}world -->{{"<Boston>"}}{{end}}</b>`,292 output: "<b>Hello, &lt;Cincinnati&gt;</b>",293 err: ``,294 },295 // No comment injection.296 {297 input: `<{{"!--"}}`,298 output: `&lt;!--`,299 err: ``,300 },301 // No RCDATA end tag injection.302 {303 input: `<textarea><{{"/textarea "}}...</textarea>`,304 output: `<textarea>&lt;/textarea ...</textarea>`,305 err: ``,306 },307 // Template-author-controlled '<' <script> body not overescaped.308 {309 input: `<script>var b = 1 < 2</script>`,310 output: `<script>var b = 1 < 2</script>`,311 err: ``,312 },313 // Template-author controlled HTML metacharacters in <style>.314 {315 input: `<style>a[href=~"<"] > b { color: blue }</style>`,316 output: `<style>a[href=~"<"] > b { color: blue }</style>`,317 err: ``,318 },319 // HTML substitution commented out.320 {321 input: `<p><!-- {{"<Hello>"}} --></p>`,322 output: "<p></p>",323 err: ``,324 },325 // Comment ends flush with start.326 {327 input: `<!--{{.}}--><p>Hello</p>`,328 output: "<p>Hello</p>",329 err: ``,330 },331 // HTML normalization.332 {333 input: "a < b",334 output: "a &lt; b",335 err: ``,336 },337 {338 input: "a << b",339 output: "a &lt;&lt; b",340 err: ``,341 },342 {343 input: "a<<!-- --><!-- -->b",344 output: "a&lt;b",345 err: ``,346 },347 // HTML doctype not normalized.348 {349 input: "<!DOCTYPE html>Hello, World!",350 output: "<!DOCTYPE html>Hello, World!",351 err: ``,352 },353 // HTML doctype not case-insensitive.354 {355 input: "<!doCtYPE htMl>Hello, World!",356 output: "<!doCtYPE htMl>Hello, World!",357 err: ``,358 },359 // No doctype injection.360 {361 input: `<!{{"DOCTYPE"}}`,362 output: "&lt;!DOCTYPE",363 err: ``,364 },365 // range values sanitized.366 {367 input: "<textarea>{{range .A}}{{.}}{{end}}</textarea>",368 output: "<textarea>&lt;a&gt;&lt;b&gt;</textarea>",369 err: ``,370 },371 // Actions outside of HTML element expect HTML.372 {373 input: `<head>title</head>{{ "<b>foo</b>" }}`,374 output: `<head>title</head>&lt;b&gt;foo&lt;/b&gt;`,375 err: ``,376 },377 {378 input: `<head>title</head>{{ makeHTMLForTest "<b>foo</b>" }}`,379 output: `<head>title</head><b>foo</b>`,380 err: ``,381 },382 {383 input: `{{ "<b>foo</b>" }}`,384 output: `&lt;b&gt;foo&lt;/b&gt;`,385 err: ``,386 },387 {388 input: `{{ makeHTMLForTest "<b>foo</b>" }}`,389 output: `<b>foo</b>`,390 err: ``,391 },392 // Attribute value contexts that allow untrusted strings.393 {394 input: `<link media="{{ "print" }}">`,395 output: `<link media="print">`,396 err: ``,397 },398 {399 input: `<form method="{{ "get<" }}"></form>`,400 output: `<form method="get&lt;"></form>`, // untrusted string is still HTML-escaped401 err: ``,402 },403 // Element content contexts that expect HTML.404 {405 input: `<span>{{ "<b>foo</b>" }}</span>`,406 output: `<span>&lt;b&gt;foo&lt;/b&gt;</span>`,407 err: ``,408 },409 {410 input: `<span>{{ makeHTMLForTest "<b>foo</b>" }}</span>`,411 output: `<span><b>foo</b></span>`,412 err: ``,413 },414 // Attribute value contexts that expect HTML.415 {416 input: `<iframe srcdoc="{{ "<a href=\"https://www.foo.com\">foo</a>" }}">{{ "<b>bar</b>" }}</iframe>`,417 output: ``,418 err: `expected a safehtml.HTML value`,419 },420 {421 input: `<iframe srcdoc="{{ makeHTMLForTest "<a href=\"https://www.foo.com\">foo</a>" }}">{{ makeHTMLForTest "<b>bar</b>" }}</iframe>`,422 output: `<iframe srcdoc="&lt;a href=&#34;https://www.foo.com&#34;&gt;foo&lt;/a&gt;"><b>bar</b></iframe>`,423 err: ``,424 },425 // Attribute value contexts that expect URL.426 // safehtml.URL values should still be HTML-escaped even after bypassing URL sanitization.427 {428 input: `<q cite="{{ "data:,\"><script>alert('pwned!')</script>" }}">foo</q>`,429 output: `<q cite="about:invalid#zGoSafez">foo</q>`,430 err: ``,431 },432 {433 input: `<q cite="{{ makeURLForTest "data:,\"><script>alert('pwned!')</script>" }}">foo</q>`,434 output: `<q cite="data:,%22%3e%3cscript%3ealert%28%27pwned!%27%29%3c/script%3e">foo</q>`,435 err: ``,436 },437 {438 input: `<link rel="alternate" href="{{ "data:,\"><script>alert('pwned!')</script>" }}">`,439 output: `<link rel="alternate" href="about:invalid#zGoSafez">`,440 err: ``,441 },442 {443 input: `<link rel="alternate" href="{{ makeURLForTest "data:,\"><script>alert('pwned!')</script>" }}">`,444 output: `<link rel="alternate" href="data:,%22%3e%3cscript%3ealert%28%27pwned!%27%29%3c/script%3e">`,445 err: ``,446 },447 {448 input: `<q cite="{{ "data:,\"><script>alert('pwned!')</script>" }}my/path">foo</q>`,449 output: `<q cite="about:invalid#zGoSafezmy/path">foo</q>`,450 err: ``,451 },452 {453 input: `<q cite="{{ makeURLForTest "http://www.foo.com/" }}my/path">foo</q>`,454 output: `<q cite="http://www.foo.com/my/path">foo</q>`,455 err: ``,456 },457 {458 input: `<q cite="{{ makeURLForTest "http://www.foo.com/" }}main?a={{ "b&c=d" }}">foo</q>`,459 output: `<q cite="http://www.foo.com/main?a=b%26c%3dd">foo</q>`,460 err: ``,461 },462 {463 input: `<q cite="{{ makeURLForTest "http://www.foo.com/" }}main?a={{ "w&x" }}&b={{ "y#z" }}">foo</q>`,464 output: `<q cite="http://www.foo.com/main?a=w%26x&b=y%23z">foo</q>`,465 err: ``,466 },467 {468 input: `<q cite="http://www.foo.com/{{ "multiple/path/segments" }}">foo</q>`,469 output: `<q cite="http://www.foo.com/multiple/path/segments">foo</q>`,470 err: ``,471 },472 {473 input: `<q cite="/foo?q={{ "bar&x=baz" }}">foo</q>`,474 output: `<q cite="/foo?q=bar%26x%3dbaz">foo</q>`,475 err: ``,476 },477 {478 input: `<q cite="/foo?q={{ "bar&x=baz" }}&j={{ "bar&x=baz" }}">foo</q>`,479 output: `<q cite="/foo?q=bar%26x%3dbaz&j=bar%26x%3dbaz">foo</q>`,480 err: ``,481 },482 {483 input: `<q cite="http://www.foo.com/{{ "multiple/path/segments" }}?q={{ "bar&x=baz" }}">foo</q>`,484 output: `<q cite="http://www.foo.com/multiple/path/segments?q=bar%26x%3dbaz">foo</q>`,485 err: ``,486 },487 {488 input: `<q cite="?q={{ "myQuery" }}&hl={{ "en" }}">foo</q>`,489 output: `<q cite="?q=myQuery&hl=en">foo</q>`,490 err: ``,491 },492 {493 input: `<q cite="j{{ "avascript:alert(1)" }}">foo</q>`,494 output: ``,495 err: `action cannot be interpolated into the "cite" URL attribute value of this "q" element: URL prefix "j" is unsafe; it might be interpreted as part of a scheme`,496 },497 {498 input: `<q cite="javascript:{{ "alert(1)" }}">foo</q>`,499 output: ``,500 err: `action cannot be interpolated into the "cite" URL attribute value of this "q" element: URL prefix "javascript:" contains an unsafe scheme`,501 },502 {503 input: `<q cite=" {{ "not interpreted as a URL prefix" }}">foo</q>`,504 output: ``,505 err: `action cannot be interpolated into the "cite" URL attribute value of this "q" element: URL prefix " " contains whitespace or control characters`,506 },507 {508 input: `<q cite="{{ "http://www.foo.com/?q=hello\\.world" }}">foo</q>`,509 output: `<q cite="http://www.foo.com/?q=hello%5c.world">foo</q>`,510 err: ``,511 },512 {513 input: `<q cite="/path/{{ ".." }}/{{ "foo" }}?n1=v1">foo</q>`,514 output: `<q cite="/path/../foo?n1=v1">foo</q>`,515 err: ``,516 },517 {518 input: `<q cite="/foo?a=b{{range $k, $v := .QueryParams}}&amp;{{$k}}={{$v}}{{end}}">foo</q>`,519 output: `<q cite="/foo?a=b&amp;k1=v1&amp;k2=v2&amp;k3=v3">foo</q>`,520 err: ``,521 },522 // Safe type values that are inappropriate for the HTML context get523 // unpacked into string and sanitized at run-time.524 {525 input: `<span>{{ makeScriptForTest "alert(\"foo\");" }}</span>`,526 output: `<span>alert(&#34;foo&#34;);</span>`,527 err: ``,528 },529 {530 input: `<q cite="{{ makeStyleForTest "width: 1em;height: 1em;" }}">foo</q>`,531 output: `<q cite="about:invalid#zGoSafez">foo</q>`,532 err: ``,533 },534 // Attribute value contexts that expect TrustedResouceURL.535 {536 input: `<link href="{{ "data:,foo" }}">`,537 output: ``,538 err: `expected a safehtml.TrustedResourceURL value`,539 },540 {541 input: `<link href="{{ makeTrustedResourceURLForTest "data:,foo" }}">`,542 output: `<link href="data:,foo">`,543 err: ``,544 },545 {546 input: `<iframe src="{{ "data:,foo" }}"></iframe>`,547 output: ``,548 err: `expected a safehtml.TrustedResourceURL value`,549 },550 {551 input: `<iframe src="{{ makeTrustedResourceURLForTest "data:,foo" }}"></iframe>`,552 output: `<iframe src="data:,foo"></iframe>`,553 err: ``,554 },555 {556 input: `<link href="{{ "data:,foo" }}my/path">`,557 output: ``,558 err: `expected a safehtml.TrustedResourceURL value`,559 },560 {561 input: `<link href="{{ makeTrustedResourceURLForTest "https://www.foo.com/" }}my/path">`,562 output: `<link href="https://www.foo.com/my/path">`,563 err: ``,564 },565 {566 input: `<link href=" {{ "not interpreted as a URL prefix" }}">`,567 output: ``,568 err: `action cannot be interpolated into the "href" URL attribute value of this "link" element: URL prefix " " contains whitespace or control characters`,569 },570 {571 // Note: the error message here is confusing, since "main?a=" isn't actually the prefix of the URL.572 // However, having a URL with a dynamic prefix and suffix and a static middle portion is probably573 // never a valid use case, so we are ok with this failing confusingly.574 input: `<link href="{{ makeTrustedResourceURLForTest "https://www.foo.com/" }}main?a={{ "b&c=d" }}">`,575 output: ``,576 err: `action cannot be interpolated into the "href" URL attribute value of this "link" element: "main?a=" is a disallowed TrustedResourceURL prefix`,577 },578 {579 input: `<link href="/foo?q={{ "myQuery" }}&hl={{ "en" }}">`,580 output: `<link href="/foo?q=myQuery&hl=en">`,581 err: ``,582 },583 {584 input: `<link href="/path/{{ ".." }}/{{ "foo" }}?n1=v1">`,585 output: ``,586 err: `cannot substitute ".." after TrustedResourceURL prefix: ".." is disallowed`,587 },588 {589 // Invalid UTF-8.590 input: `<link href="/foo?{{ "\xFF\xFE\xFD" }}">`,591 output: `<link href="/foo?%ff%fe%fd">`,592 err: ``,593 },594 {595 // Supplementary codepoints.596 input: `<link href="/foo?{{ "\U00012345" }}">`,597 output: `<link href="/foo?%f0%92%8d%85">`,598 err: ``,599 },600 {601 input: `<link href="https://www.foo.com/{{ "main.html" }}">`,602 output: `<link href="https://www.foo.com/main.html">`,603 err: ``,604 },605 {606 input: `<link href="https://www.foo.com/{{ "multiple/path/segments" }}">`,607 output: `<link href="https://www.foo.com/multiple%2fpath%2fsegments">`,608 err: ``,609 },610 {611 input: `<link href="/foo?q={{ "bar&x=baz" }}">`,612 output: `<link href="/foo?q=bar%26x%3dbaz">`,613 err: ``,614 },615 {616 input: `<link href="https://www.foo.com/{{ "multiple/path/segments" }}?q={{ "bar&x=baz" }}">`,617 output: `<link href="https://www.foo.com/multiple%2fpath%2fsegments?q=bar%26x%3dbaz">`,618 err: ``,619 },620 {621 input: `<link href="http://www.foo.com/{{ "main.html" }}">`,622 output: ``,623 err: `action cannot be interpolated into the "href" URL attribute value of this "link" element: "http://www.foo.com/" is a disallowed TrustedResourceURL prefix`,624 },625 {626 input: `<link href="j{{ "avascript:alert(1)" }}">`,627 output: ``,628 err: `action cannot be interpolated into the "href" URL attribute value of this "link" element: "j" is a disallowed TrustedResourceURL prefix`,629 },630 {631 input: `<link href="javascript:{{ "alert(1)" }}">`,632 output: ``,633 err: `action cannot be interpolated into the "href" URL attribute value of this "link" element: "javascript:" is a disallowed TrustedResourceURL prefix`,634 },635 // Attribute value contexts that accept both URL and TrustedResouceURL.636 {637 // URL sanitization applied to untrusted string.638 input: `<source src="{{ "data:,\"><script>alert('pwned!')</script>" }}">`,639 output: `<source src="about:invalid#zGoSafez">`,640 err: ``,641 },642 {643 input: `<source src="{{ makeURLForTest "data:,\"><script>alert('pwned!')</script>" }}"> <source src="{{ makeTrustedResourceURLForTest "data:,foo" }}">`,644 output: `<source src="data:,%22%3e%3cscript%3ealert%28%27pwned!%27%29%3c/script%3e"> <source src="data:,foo">`,645 err: ``,646 },647 {648 input: `<source src="{{ "data:,\"><script>alert('pwned!')</script>" }}my/path">`,649 output: `<source src="about:invalid#zGoSafezmy/path">`,650 err: ``,651 },652 {653 input: `<source src="{{ makeURLForTest "http://www.foo.com/" }}my/path">`,654 output: `<source src="http://www.foo.com/my/path">`,655 err: ``,656 },657 {658 input: `<source src="{{ makeURLForTest "http://www.foo.com/" }}main?a={{ "b&c=d" }}">`,659 output: `<source src="http://www.foo.com/main?a=b%26c%3dd">`,660 err: ``,661 },662 {663 input: `<source src="{{ makeURLForTest "http://www.foo.com/" }}main?a={{ "w&x" }}&b={{ "y#z" }}">`,664 output: `<source src="http://www.foo.com/main?a=w%26x&b=y%23z">`,665 err: ``,666 },667 {668 input: `<source src="http://www.foo.com/{{ "multiple/path/segments" }}">`,669 output: `<source src="http://www.foo.com/multiple/path/segments">`,670 err: ``,671 },672 {673 input: `<source src="/foo?q={{ "bar&x=baz" }}">`,674 output: `<source src="/foo?q=bar%26x%3dbaz">`,675 err: ``,676 },677 {678 input: `<source src="/foo?q={{ "bar&x=baz" }}&j={{ "bar&x=baz" }}">`,679 output: `<source src="/foo?q=bar%26x%3dbaz&j=bar%26x%3dbaz">`,680 err: ``,681 },682 {683 input: `<source src="http://www.foo.com/{{ "multiple/path/segments" }}?q={{ "bar&x=baz" }}">`,684 output: `<source src="http://www.foo.com/multiple/path/segments?q=bar%26x%3dbaz">`,685 err: ``,686 },687 {688 input: `<source src="?q={{ "myQuery" }}&hl={{ "en" }}">`,689 output: `<source src="?q=myQuery&hl=en">`,690 err: ``,691 },692 {693 input: `<source src="{{ "http://www.foo.com/main" }}?q={{ "param" }}">`,694 output: `<source src="http://www.foo.com/main?q=param">`,695 err: ``,696 },697 {698 input: `<source src="j{{ "avascript:alert(1)" }}">`,699 output: ``,700 err: `action cannot be interpolated into the "src" URL attribute value of this "source" element: URL prefix "j" is unsafe; it might be interpreted as part of a scheme`,701 },702 {703 input: `<source src="javascript:{{ "alert(1)" }}">`,704 output: ``,705 err: `action cannot be interpolated into the "src" URL attribute value of this "source" element: URL prefix "javascript:" contains an unsafe scheme`,706 },707 {708 input: `<source src="{{ "http://www.foo.com/?q=hello\\.world" }}">`,709 output: `<source src="http://www.foo.com/?q=hello%5c.world">`,710 err: ``,711 },712 {713 input: `<source src=" {{ "not interpreted as a URL prefix" }}">`,714 output: ``,715 err: `action cannot be interpolated into the "src" URL attribute value of this "source" element: URL prefix " " contains whitespace or control characters`,716 },717 {718 input: `<source src="/path/{{ ".." }}/{{ "foo" }}?n1=v1">`,719 output: `<source src="/path/../foo?n1=v1">`,720 err: ``,721 },722 {723 input: `<source src="/foo?a=b{{range $k, $v := .QueryParams}}&amp;{{$k}}={{$v}}{{end}}">`,724 output: `<source src="/foo?a=b&amp;k1=v1&amp;k2=v2&amp;k3=v3">`,725 err: ``,726 },727 // Attribute value contexts that expect Style.728 {729 input: `<p style="{{ "width: 1em;height: 1em;" }}">foo</p>`,730 output: ``,731 err: `expected a safehtml.Style value`,732 },733 {734 input: `<p style="{{ makeStyleForTest "width: 1em;height: 1em;" }}">foo</p>`,735 output: `<p style="width: 1em;height: 1em;">foo</p>`,736 err: ``,737 },738 {739 input: `<p style="color:green; &{{ "gt;<script>alert(1);</script>" }}">foo</p>`,740 output: ``,741 err: `action cannot be interpolated into the "style" attribute value of this "p" element: prefix "color:green; &" ends with an incomplete HTML character reference; did you mean "&amp;" instead of "&"?`,742 },743 // Element content contexts that expect StyleSheet.744 {745 input: `<style>{{ "P.special { color:red ; }" }}</style>`,746 output: ``,747 err: `expected a safehtml.StyleSheet value`,748 },749 {750 input: `<style>{{ makeStyleSheetForTest "P.special { color:red ; }" }}</style>`,751 output: `<style>P.special { color:red ; }</style>`,752 err: ``,753 },754 {755 input: `<style>// {{"cannot insert dynamic comment"}}</style>`,756 output: ``,757 err: `expected a safehtml.StyleSheet value`,758 },759 {760 input: `<style>/* </b{{"notParsedAsTagName"}} */</style>`,761 output: ``,762 err: `expected a safehtml.StyleSheet value`,763 },764 // Element content contexts that expect Script.765 {766 input: `<script>{{ "alert(1);" }}</script>`,767 output: ``,768 err: `expected a safehtml.Script value`,769 },770 {771 input: `<script>{{ makeScriptForTest "alert(1);" }}</script>`,772 output: `<script>alert(1);</script>`,773 err: ``,774 },775 {776 input: `<script>// {{"cannot insert dynamic comment"}}</script>`,777 output: ``,778 err: `expected a safehtml.Script value`,779 },780 // Attribute value contexts that expect enumerated string values.781 {782 input: `<a target="{{ "blah" }}">foo</a>`,783 output: ``,784 err: `expected one of the following strings: ["_blank" "_self"]`,785 },786 {787 input: `<a target="{{ "_blank" }}">foo</a>`,788 output: `<a target="_blank">foo</a>`,789 err: ``,790 },791 {792 input: `<a target="{{ "_self" }}">foo</a>`,793 output: `<a target="_self">foo</a>`,794 err: ``,795 },796 {797 input: `<a target="prefix{{ "_self" }}">foo</a>`,798 output: ``,799 err: `partial substitutions are disallowed in the "target" attribute value context of a "a" element`,800 },801 // Attribute value contexts that expect Identifiers.802 {803 input: `<p name="{{ "my-identifier" }}" id="{{ "my-identifier" }}">foo</p>`,804 output: ``,805 err: `expected a safehtml.Identifier value`,806 },807 {808 input: `<p name="{{ makeIdentifierForTest "my-identifier" }}" id="{{ makeIdentifierForTest "my-identifier" }}">foo</p>`,809 output: `<p name="my-identifier" id="my-identifier">foo</p>`,810 err: ``,811 },812 // Element content contexts that expect RCDATA.813 {814 input: `<textarea>{{ "</textarea><script>alert('pwned!');</script>" }}</textarea>`,815 output: `<textarea>&lt;/textarea&gt;&lt;script&gt;alert(&#39;pwned!&#39;);&lt;/script&gt;</textarea>`,816 err: ``,817 },818 {819 input: `<title>{{ "</title><script>alert('pwned!');</script>" }}</title>`,820 output: `<title>&lt;/title&gt;&lt;script&gt;alert(&#39;pwned!&#39;);&lt;/script&gt;</title>`,821 err: ``,822 },823 // data-* attributes values.824 {825 input: `<p data-foo="{{ "foo" }}" data-bar="{{ "b<a>r" }}">baz</p>`,826 output: `<p data-foo="foo" data-bar="b&lt;a&gt;r">baz</p>`,827 err: ``,828 },829 {830 input: `<p data-4badname="{{ "foo" }}">baz</p>`,831 output: ``,832 err: `actions must not occur in the "data-4badname" attribute value context of a "p" element`,833 },834 // Attribute sanitization contexts propagate correctly over conditionals.835 // Notice that the if and else branches are sanitized differently and correctly.836 {837 input: `<a {{if 1}}id="{{ "foo:bar" }}"{{else}}href="{{ "foo:bar" }}"{{end}}>foo</a>`,838 output: ``,839 err: `expected a safehtml.Identifier value`,840 },841 {842 input: `<a {{if 0}}id="{{ "foo:bar" }}"{{else}}href="{{ "foo:bar" }}"{{end}}>foo</a>`,843 output: `<a href="about:invalid#zGoSafez">foo</a>`,844 err: ``,845 },846 // Conditional valueless attribute name.847 {848 input: `<img class="{{"iconClass"}}"` +849 `{{if 1}} color="{{"<iconColor>"}}"{{end}}` +850 // Double quotes inside if/else.851 ` src=` +852 `{{if 1}}"/foo?{{"<iconPath>"}}"` +853 `{{else}}"images/cleardot.gif"{{end}}` +854 // Missing space before title, but it is not a855 // part of the src attribute.856 `{{if .T}}title="{{"<title>"}}"{{end}}` +857 // Quotes outside if/else.858 ` alt="` +859 `{{if .T}}{{"<alt>"}}` +860 `{{else}}{{if .F}}{{"<title>"}}{{end}}` +861 `{{end}}"` +862 `>`,863 output: `<img class="iconClass" color="&lt;iconColor&gt;" src="/foo?%3ciconPath%3e"title="&lt;title&gt;" alt="&lt;alt&gt;">`,864 err: ``,865 },866 } {867 tmpl := Must(New("").Funcs(testConversionFuncs).Parse(stringConstant(test.input)))868 var b bytes.Buffer869 err := tmpl.Execute(&b, data)870 if test.err != "" {871 if err == nil {872 t.Errorf("%s : expected error", test.input)873 continue874 }875 if got := err.Error(); !strings.Contains(got, test.err) {876 t.Errorf("%s : error\n\t%q\ndoes not contain expected string\n\t%q", test.input, got, test.err)877 }878 continue879 }880 if test.err == "" && err != nil {881 t.Errorf("%s : template execution failed:\n%s", test.input, err)882 continue883 }884 if want, got := test.output, b.String(); want != got {885 t.Errorf("%s : escaped output: got\n\t%s\nwant\n\t%s", test.input, got, want)886 continue887 }888 }889}890func TestConditionalURLPrefixError(t *testing.T) {891 data := struct {892 B []string893 C, D bool894 URLSuffix string895 }{896 B: []string{"foo", "bar"},897 C: false,898 D: true,899 URLSuffix: "suffix",900 }901 for _, test := range [...]struct {902 input, want string903 }{904 // Conditonal URL prefix in attribute value contexts that expect URLs.905 {906 `<q cite="{{if .C}}mailto:{{end}}{{ .URLSuffix }}">foo</q>`,907 `actions must not occur after an ambiguous URL prefix`,908 },909 {910 `<q cite="{{if .C}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">foo</q>`,911 `actions must not occur after an ambiguous URL prefix`,912 },913 {914 `<q cite="{{if .C}}mailto{{else}}javascript{{end}}:{{ .URLSuffix }}">foo</q>`,915 `actions must not occur after an ambiguous URL prefix`,916 },917 {918 `<q cite="{{if .C}}mailto:{{else if .D}}javascript:{{else}}tel:{{end}}{{ .URLSuffix }}">foo</q>`,919 `actions must not occur after an ambiguous URL prefix`,920 },921 {922 `<q cite="{{range .B}}mailto:{{end}}{{ .URLSuffix }}">foo</q>`,923 `actions must not occur after an ambiguous URL prefix`,924 },925 {926 `<q cite="{{range .B}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">foo</q>`,927 `actions must not occur after an ambiguous URL prefix`,928 },929 {930 `<q cite="{{with .C}}mailto:{{end}}{{ .URLSuffix }}">foo</q>`,931 `actions must not occur after an ambiguous URL prefix`,932 },933 {934 `<q cite="{{with .C}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">foo</q>`,935 `actions must not occur after an ambiguous URL prefix`,936 },937 // Conditonal URL prefix in attribute value contexts that expect TrustedResourceURLs.938 {939 `<link href="{{if .C}}mailto:{{end}}{{ .URLSuffix }}">`,940 `actions must not occur after an ambiguous URL prefix`,941 },942 {943 `<link href="{{if .C}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">`,944 `actions must not occur after an ambiguous URL prefix`,945 },946 {947 `<link href="{{if .C}}mailto{{else}}javascript{{end}}:{{ .URLSuffix }}">`,948 `actions must not occur after an ambiguous URL prefix`,949 },950 {951 `<link href="{{if .C}}mailto:{{else if .D}}javascript:{{else}}tel:{{end}}{{ .URLSuffix }}">`,952 `actions must not occur after an ambiguous URL prefix`,953 },954 {955 `<link href="{{range .B}}mailto:{{end}}{{ .URLSuffix }}">`,956 `actions must not occur after an ambiguous URL prefix`,957 },958 {959 `<link href="{{range .B}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">`,960 `actions must not occur after an ambiguous URL prefix`,961 },962 {963 `<link href="{{with .C}}mailto:{{end}}{{ .URLSuffix }}">`,964 `actions must not occur after an ambiguous URL prefix`,965 },966 {967 `<link href="{{with .C}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">`,968 `actions must not occur after an ambiguous URL prefix`,969 },970 // Conditonal URL prefix in attribute value contexts that expect URLs or TrustedResourceURLs.971 {972 `<source src="{{if .C}}mailto:{{end}}{{ .URLSuffix }}">`,973 `actions must not occur after an ambiguous URL prefix`,974 },975 {976 `<source src="{{if .C}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">`,977 `actions must not occur after an ambiguous URL prefix`,978 },979 {980 `<source src="{{if .C}}mailto{{else}}javascript{{end}}:{{ .URLSuffix }}">`,981 `actions must not occur after an ambiguous URL prefix`,982 },983 {984 `<source src="{{if .C}}mailto:{{else if .D}}javascript:{{else}}tel:{{end}}{{ .URLSuffix }}">`,985 `actions must not occur after an ambiguous URL prefix`,986 },987 {988 `<source src="{{range .B}}mailto:{{end}}{{ .URLSuffix }}">`,989 `actions must not occur after an ambiguous URL prefix`,990 },991 {992 `<source src="{{range .B}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">`,993 `actions must not occur after an ambiguous URL prefix`,994 },995 {996 `<source src="{{with .C}}mailto:{{end}}{{ .URLSuffix }}">`,997 `actions must not occur after an ambiguous URL prefix`,998 },999 {1000 `<source src="{{with .C}}mailto:{{else}}javascript:{{end}}{{ .URLSuffix }}">`,1001 `actions must not occur after an ambiguous URL prefix`,1002 },1003 } {1004 tmpl := Must(New(test.input).Parse(stringConstant(test.input)))1005 var b bytes.Buffer1006 err := tmpl.Execute(&b, data)1007 if err == nil {1008 t.Errorf("expected an error for template %s", test.input)1009 continue1010 }1011 if got := err.Error(); !strings.Contains(got, test.want) {1012 t.Errorf("got error:\n\t%s\nwant:\n\t%s", got, test.want)1013 }1014 }1015}1016func TestValidateDoesNotEndsWithCharRefPrefix(t *testing.T) {1017 const wantErr = `ends with an incomplete HTML character reference; did you mean "&amp;" instead of "&"?`1018 for _, test := range [...]struct {1019 in string1020 valid bool1021 }{1022 // Incomplete HTML character escape sequences.1023 {`&`, false},1024 {`javascript&`, false},1025 {`javascript&c`, false},1026 {`javascript&colon`, false},1027 {`javascript&blk1`, false},1028 {`javascript&#`, false},1029 {`javascript&#5`, false},1030 {`javascript&#x`, false},1031 {`javascript&#xa`, false},1032 {`javascript&#XA`, false},1033 {`javascript&#X3`, false},1034 // Invalid HTML character references.1035 {`javascript&x3A;`, true},1036 {`javascript&x3a;`, true},1037 {`javascript&X3A;`, true},1038 {`javascript&X3a;`, true},1039 // Complete HTML character references.1040 {`javascript&colon;`, true},1041 {`javascript&#58;`, true},1042 } {1043 err := validateDoesNotEndsWithCharRefPrefix(test.in)1044 switch {1045 case err != nil:1046 if test.valid {1047 t.Errorf("validateDoesNotEndsWithCharRefPrefix(%q) failed: %s", test.in, err)1048 } else if !strings.Contains(err.Error(), wantErr) {1049 t.Errorf("validateDoesNotEndsWithCharRefPrefix(%q) error\n\t%s\ndoes not contain expected string\n\t%s", test.in, err.Error(), wantErr)1050 }1051 case !test.valid:1052 t.Errorf("validateDoesNotEndsWithCharRefPrefix(%q) succeeded unexpectedly", test.in)1053 }1054 }1055}1056func TestDataAttributeNamePattern(t *testing.T) {1057 for _, test := range [...]struct {1058 in string1059 want bool1060 }{1061 {`data-a`, true},1062 {`data-foo`, true},1063 {`data-foo-bar`, true},1064 {`data-f0o-b4r`, true},1065 {`data-_foo`, true},1066 // Does not begin with "data-".1067 {`data`, false},1068 {`foo`, false},1069 // No characters after hyphen.1070 {`data-`, false},1071 // Suffix starts with a digit.1072 {`data-4oo`, false},1073 // Contains ACSII upper alphas.1074 // Note: this test case isn't strictly necessary, since sanitizerForContext is given1075 // lower-case attribute names.1076 {`data-Foo`, false},1077 // Contains colon characters.1078 {`data-foo:bar`, false},1079 // Contains unicode characters that are allowed in XML names1080 // (https://www.w3.org/TR/xml/#NT-Name), but conservatively rejected1081 // by our regexp pattern.1082 {"data-\u037Fbar", false},1083 {"data-fo\u0300", false},1084 } {1085 if got := dataAttributeNamePattern.MatchString(test.in); got != test.want {1086 t.Errorf("dataAttributeNamePattern.MatchString(%q) = %t", test.in, got)1087 }1088 }1089}1090const testSanitizationLogicWant = `cannot escape action {{.}}: unquoted attribute values disallowed`1091// TestSanitizationLogic ensures that the underlying html/template sanitization logic is1092// replaced by the safehtml/template sanitization logic no matter how the template is parsed1093// or executed.1094func TestSanitizationLogic(t *testing.T) {1095 // This template will be accepted by html/template but not by safehtml/template1096 // since the latter does not allow data to be substituted into unquoted attribute1097 // value contexts.1098 const templateText = `<a href={{.}}>unquoted href attribute value</a>`1099 // Create temp file containing the template text for constructors that parse templates1100 // from files.1101 tmpfile, err := ioutil.TempFile("", "path")1102 if err != nil {1103 t.Fatal(err)1104 }1105 defer os.Remove(tmpfile.Name())1106 if _, err := tmpfile.WriteString(templateText); err != nil {1107 t.Fatal(err)1108 }1109 filename := stringConstant(tmpfile.Name())1110 templateName := filepath.Base(tmpfile.Name())1111 for _, test := range [...]struct {1112 parseFuncName string1113 tmpl *Template1114 }{1115 {"Parse", Must(New(templateName).Parse(templateText))},1116 {"ParseFromTrustedTemplate", Must(New(templateName).ParseFromTrustedTemplate(MakeTrustedTemplate(templateText)))},1117 {"ParseFiles (method)", Must(New(templateName).ParseFiles(filename))},1118 {"ParseFiles (function)", Must(ParseFiles(filename))},1119 {"ParseFilesFromTrustedSources (method)", Must(New(templateName).ParseFilesFromTrustedSources(TrustedSourceFromConstant(filename)))},1120 {"ParseFilesFromTrustedSources (function)", Must(ParseFilesFromTrustedSources(TrustedSourceFromConstant(filename)))},1121 {"ParseGlob (method)", Must(New(templateName).ParseGlob(filename))},1122 {"ParseGlob (function)", Must(ParseGlob(filename))},1123 {"ParseGlobFromTrustedSource (method)", Must(New(templateName).ParseGlobFromTrustedSource(TrustedSourceFromConstant(filename)))},1124 {"ParseGlobFromTrustedSource (function)", Must(ParseGlobFromTrustedSource(TrustedSourceFromConstant(filename)))},1125 } {1126 var b bytes.Buffer1127 err := test.tmpl.Execute(&b, nil)1128 testSanitizationLogicCheckError(t, err, test.parseFuncName, "Execute")1129 _, err = test.tmpl.ExecuteToHTML(nil)1130 testSanitizationLogicCheckError(t, err, test.parseFuncName, "ExecuteToHTML")1131 err = test.tmpl.ExecuteTemplate(&b, templateName, nil)1132 testSanitizationLogicCheckError(t, err, test.parseFuncName, "ExecuteTemplate")1133 _, err = test.tmpl.ExecuteTemplateToHTML(templateName, nil)1134 testSanitizationLogicCheckError(t, err, test.parseFuncName, "ExecuteTemplateToHTML")1135 }1136}1137func testSanitizationLogicCheckError(t *testing.T, err error, parseFuncName, executeFuncName string) {1138 prefix := parseFuncName + ", " + executeFuncName1139 if err == nil {1140 t.Errorf("%s : expected execution error", prefix)1141 return1142 }1143 if got := err.Error(); !strings.Contains(got, testSanitizationLogicWant) {1144 t.Errorf("%s : the error message:\n\t%s\ndoes not contain:\n\t%s", prefix, got, testSanitizationLogicWant)1145 }1146}1147func TestCannotCallInternalSanitizers(t *testing.T) {1148 const templateName = "test"1149 // Programmatically generate templates that call each sanitizer function in the internal1150 // function map.1151 for sanitizerName := range funcs {1152 tmplText := `{{ "foo" | ` + sanitizerName + ` }}`1153 _, err := New(templateName).Parse(stringConstant(tmplText))1154 if err == nil {1155 t.Errorf("expected error parsing template which calls internal sanitizer %q", sanitizerName)1156 }1157 }1158}1159func TestExecuteErrors(t *testing.T) {1160 for _, test := range [...]struct {1161 desc string1162 tmpl stringConstant1163 data interface{}1164 want string1165 fullMatch bool1166 }{1167 {1168 desc: `invalid template`,1169 tmpl: `{{template "foo"}}`,1170 want: `no such template "foo"`,1171 },1172 {1173 desc: `missing '"' after recursive call`,1174 tmpl: `<select size="{{template "y"}}></select>` +1175 `{{define "y"}}{{if .Tail}}{{template "y" .Tail}}{{end}}3"{{end}}`,1176 want: `cannot compute output context for template y$htmltemplate_StateAttr_DelimDoubleQuote_attrSize_elementSelect`,1177 },1178 {1179 desc: `element and attribute name confused`,1180 tmpl: `<a=foo>`,1181 want: `: expected space, attr name, or end of tag, but got "=foo>"`,1182 },1183 {1184 desc: `urlquery is disallowed if it is not the last command in the pipeline`,1185 tmpl: `Hello, {{. | urlquery | print}}!`,1186 want: `predefined escaper "urlquery" disallowed in template`,1187 },1188 {1189 desc: `html is disallowed if it is not the last command in the pipeline`,1190 tmpl: `Hello, {{. | html | print}}!`,1191 want: `predefined escaper "html" disallowed in template`,1192 },1193 {1194 desc: `direct call to html is disallowed if it is not the last command in the pipeline`,1195 tmpl: `Hello, {{html . | print}}!`,1196 want: `predefined escaper "html" disallowed in template`,1197 },1198 {1199 desc: `html is disallowed in a pipeline that is in an unquoted attribute context, even if it is the last command in the pipeline`,1200 tmpl: `<div class={{. | html}}>Hello<div>`,1201 want: `predefined escaper "html" disallowed in template`,1202 },1203 {1204 desc: `html is allowed since it is the last command in the pipeline, but urlquery is not`,1205 tmpl: `Hello, {{. | urlquery | html}}!`,1206 want: `predefined escaper "urlquery" disallowed in template`,1207 },1208 {1209 desc: `unquoted attribute value disallowed`,1210 tmpl: `<a title={{ . }}>bar</a>`,1211 want: `unquoted attribute values disallowed`,1212 },1213 {1214 desc: `dynamic element name suffix 1`,1215 tmpl: `<a{{ "foo" }} title="foo">`,1216 want: `actions must not affect element or attribute names`,1217 },1218 {1219 desc: `dynamic element name suffix 2`,1220 tmpl: `<div{{template "y"}}>` +1221 // Illegal starting in stateTag but not in stateText.1222 `{{define "y"}} foo<b{{end}}`,1223 want: `"<" in attribute name: " foo<b"`,1224 },1225 {1226 desc: `dynamic whole attribute name 1`,1227 tmpl: `<area {{ "foo" }}>`,1228 want: `actions must not affect element or attribute names`,1229 },1230 {1231 desc: `dynamic whole attribute name 2`,1232 tmpl: `<area {{ "foo" }} title="foo">`,1233 want: `actions must not affect element or attribute names`,1234 },1235 {1236 desc: `dynamic whole attribute name 3`,1237 tmpl: `<area title="foo" {{ "foo" }}>`,1238 want: `actions must not affect element or attribute names`,1239 },1240 {1241 desc: `dynamic whole attribute name 4`,1242 tmpl: `<area {{ "foo" }}="foo">`,1243 want: `actions must not affect element or attribute names`,1244 },1245 {1246 desc: `dynamic attribute name suffix`,1247 tmpl: `<area t{{ "foo" }}="foo">`,1248 want: `actions must not affect element or attribute names`,1249 },1250 {1251 desc: `dynamic attribute name prefix`,1252 tmpl: `<area {{ "foo" }}t="foo">`,1253 want: `actions must not affect element or attribute names`,1254 },1255 {1256 desc: `missing quote in the else branch`,1257 tmpl: `{{if .Cond}}<a href="foo">{{else}}<a href="bar>{{end}}`,1258 want: `{{if}} branches end in different contexts`,1259 },1260 // When we have a conditional element or attribute name suffix, the1261 // sanitizer only sees the name prefix when performing template sanitization.1262 // The prefix is very unlikely to be a whitelisted element or attribute name1263 // on its own, and will therefore be rejected.1264 {1265 desc: `conditional element name suffix`,1266 tmpl: `<me{{if 1}}ta{{else}}nuitem{{end}}>{{ "foo" }}`,1267 want: `actions must not occur in the element content context of a "me" element`,1268 },1269 {1270 desc: `conditional attribute name suffix`,1271 tmpl: `<area d{{if 1}}raggabl{{else}}ropzon{{end}}e="{{ "foo" }}">`,1272 want: `actions must not occur in the "d" attribute value context of a "area" element`,1273 },1274 {1275 desc: `if = non-whitelisted element, else = HTML, safehtml/template conditonal branch error`,1276 tmpl: `{{if 0}}<object>{{end}}{{ "hello" }}`,1277 want: `conditional branch with element "object" results in sanitization error: ` +1278 `actions must not occur in the element content context of a "object" element`,1279 },1280 {1281 desc: `if = Script, else = HTML, html/template conditonal branch error`,1282 tmpl: `{{if 0}}<script>{{end}}{{ "hello" }}`,1283 want: `branches end in different contexts`,1284 },1285 {1286 desc: `if = Script, else = HTML, safehtml/template conditonal branch error`,1287 tmpl: `{{if 0}}<script{{else}}<span{{end}}>{{ "hello" }}`,1288 want: `conditional branches end in different element content sanitization contexts: ` +1289 `element "script" has sanitization context "Script", ` +1290 `element "span" has sanitization context "HTML"`,1291 },1292 {1293 desc: `if = Script, else = HTML, html/template conditonal branch error`,1294 tmpl: `{{if 0}}<script>{{else}}<span>{{end}}{{ "hello" }}`,1295 want: `branches end in different contexts`,1296 },1297 {1298 desc: `if = Script, else if = HTML, else = HTML, html/template conditonal branch error`,1299 tmpl: `{{if 0}}<script>{{else if 1}}<span>{{else}}<b>{{end}}{{ "hello" }}`,1300 want: `branches end in different contexts`,1301 },1302 {1303 desc: `range = non-whitelisted element, else = HTML, safehtml/template conditonal branch error`,1304 tmpl: `{{range .}}<object>{{end}}{{ "hello" }}`,1305 data: []string{"foo", "bar"},1306 want: `conditional branch with element "object" results in sanitization error: ` +1307 `actions must not occur in the element content context of a "object" element`,1308 },1309 {1310 desc: `range = Script, else = HTML, html/template conditonal branch error`,1311 tmpl: `{{range .}}<script>{{end}}{{ "hello" }}`,1312 data: []string{"foo", "bar"},1313 want: `branches end in different contexts`,1314 },1315 {1316 desc: `range = Script, else = HTML, html/template conditonal branch error`,1317 tmpl: `{{range .}}<script>{{else}}<area>{{end}}{{ "hello" }}`,1318 data: []string{"foo", "bar"},1319 want: `branches end in different contexts`,1320 },1321 {1322 desc: `with = non-whitelisted element, else = HTML, safehtml/template conditonal branch error`,1323 tmpl: `{{with 0}}<object>{{end}}{{ "hello" }}`,1324 want: `conditional branch with element "object" results in sanitization error: ` +1325 `actions must not occur in the element content context of a "object" element`,1326 },1327 {1328 desc: `with = Script, else = HTML, html/template conditonal branch error`,1329 tmpl: `{{with 0}}<script>{{end}}{{ "hello" }}`,1330 want: `branches end in different contexts`,1331 },1332 {1333 desc: `with = Script, else = HTML, safehtml/template conditonal branch error`,1334 tmpl: `{{with 0}}<script{{else}}<span{{end}}>{{ "hello" }}`,1335 want: `conditional branches end in different element content sanitization contexts: ` +1336 `element "script" has sanitization context "Script", ` +1337 `element "span" has sanitization context "HTML"`,1338 },1339 {1340 desc: `with = Script, else = HTML, html/template conditonal branch error`,1341 tmpl: `{{with 0}}<script>{{else}}<span>{{end}}{{ "hello" }}`,1342 want: `branches end in different contexts`,1343 },1344 {1345 desc: `if = non-whitelisted attribute, else = no sanitization, safehtml/template conditonal branch error`,1346 tmpl: `<p {{if 0}}customattr{{else}}class{{end}}="{{ "hello" }}">`,1347 want: `conditional branch with {element="p", attribute="customattr"} results in sanitization error: ` +1348 `actions must not occur in the "customattr" attribute value context of a "p" element`,1349 },1350 {1351 desc: `if = TrustedResourceURLOrURL, else = TrustedResourceURL, safehtml/template conditonal branch error`,1352 tmpl: `{{if 0}}<img{{else}}<track{{end}} src="{{ "hello" }}">`,1353 want: `conditional branches end in different attribute value sanitization contexts: ` +1354 `{element="img", attribute="src"} has sanitization context "TrustedResourceURLOrURL", ` +1355 `{element="track", attribute="src"} has sanitization context "TrustedResourceURL"`,1356 },1357 {1358 desc: `if = TrustedResourceURLOrURL, else if = TrustedResourceURLOrURL, else = TrustedResourceURL, html/template conditonal branch error`,1359 tmpl: `{{if 0}}<img{{else if 1}}<audio{{else}}<track{{end}} src="{{ "hello" }}">`,1360 want: `conditional branches end in different attribute value sanitization contexts: ` +1361 `{element="img", attribute="src"} has sanitization context "TrustedResourceURLOrURL", ` +1362 `{element="track", attribute="src"} has sanitization context "TrustedResourceURL"`,1363 },1364 {1365 desc: `if = TrustedResourceURLOrURL, else = Identifier, safehtml/template conditonal branch error`,1366 tmpl: `<a {{if 0}}href{{else}}id{{end}}="{{ "hello" }}">`,1367 want: `conditional branches end in different attribute value sanitization contexts: ` +1368 `{element="a", attribute="href"} has sanitization context "TrustedResourceURLOrURL", ` +1369 `{element="a", attribute="id"} has sanitization context "Identifier"`,1370 },1371 {1372 desc: `if = TrustedResourceURLOrURL, else if = Identifier, else = TargetEnum, safehtml/template conditonal branch error`,1373 tmpl: `<a {{if 0}}href{{else if .D}}id{{else}}target{{end}}="{{ "hello" }}">`,1374 want: `conditional branches end in different attribute value sanitization contexts: ` +1375 `{element="a", attribute="href"} has sanitization context "TrustedResourceURLOrURL", ` +1376 `{element="a", attribute="target"} has sanitization context "TargetEnum"`,1377 },1378 {1379 desc: `range = non-whitelisted attribute, else = no sanitization, safehtml/template conditonal branch error`,1380 tmpl: `<p {{range .}}customattr{{else}}class{{end}}="{{ "hello" }}">`,1381 data: []string{"foo", "bar"},1382 want: `conditional branch with {element="p", attribute="customattr"} results in sanitization error: ` +1383 `actions must not occur in the "customattr" attribute value context of a "p" element`,1384 },1385 {1386 desc: `range = TrustedResourceURLOrURL, else = Identifier, safehtml/template conditonal branch error`,1387 tmpl: `<a {{range .}}href{{else}}id{{end}}="{{ "hello" }}">`,1388 data: []string{"foo", "bar"},1389 want: `conditional branches end in different attribute value sanitization contexts: ` +1390 `{element="a", attribute="href"} has sanitization context "TrustedResourceURLOrURL", ` +1391 `{element="a", attribute="id"} has sanitization context "Identifier"`,1392 },1393 {1394 desc: `with = non-whitelisted attribute, else = no sanitization, safehtml/template conditonal branch error`,1395 tmpl: `<p {{with 0}}customattr{{else}}class{{end}}="{{ "hello" }}">`,1396 want: `conditional branch with {element="p", attribute="customattr"} results in sanitization error: ` +1397 `actions must not occur in the "customattr" attribute value context of a "p" element`,1398 },1399 {1400 desc: `with = TrustedResourceURLOrURL, else = HTML, html/template conditonal branch error`,1401 tmpl: `{{with 0}}<img{{end}} src="{{ "hello" }}">`,1402 want: `branches end in different contexts`,1403 },1404 {1405 desc: `with = TrustedResourceURLOrURL, else = TrustedResourceURL, safehtml/template conditonal branch error`,1406 tmpl: `{{with 0}}<img{{else}}<track{{end}} src="{{ "hello" }}">`,1407 want: `conditional branches end in different attribute value sanitization contexts: ` +1408 `{element="img", attribute="src"} has sanitization context "TrustedResourceURLOrURL", ` +1409 `{element="track", attribute="src"} has sanitization context "TrustedResourceURL"`,1410 },1411 {1412 desc: `with = TrustedResourceURLOrURL, else = Identifier, safehtml/template conditonal branch error`,1413 tmpl: `<a {{with 0}}href{{else}}id{{end}}="{{ "hello" }}">`,1414 want: `conditional branches end in different attribute value sanitization contexts: ` +1415 `{element="a", attribute="href"} has sanitization context "TrustedResourceURLOrURL", ` +1416 `{element="a", attribute="id"} has sanitization context "Identifier"`,1417 },1418 {1419 desc: `non-whitelisted attributes disallowed`,1420 tmpl: `<option customattr="{{ . }}">`,1421 want: `actions must not occur in the "customattr" attribute value context of a "option" element`,1422 },1423 {1424 desc: `non-whitelisted element name disallowed 1`,1425 tmpl: `<imaginaryelement>{{ . }}</imaginaryelement>`,1426 want: `actions must not occur in the element content context of a "imaginaryelement" element`,1427 },1428 {1429 desc: `non-whitelisted element name disallowed 2`,1430 tmpl: `<base title="{{ . }}">`,1431 want: `actions must not occur in the "title" attribute value context of a "base" element`,1432 },1433 {1434 desc: `non-whitelisted element name disallowed 3`,1435 tmpl: `<meta title="{{ . }}">`,1436 want: `actions must not occur in the "title" attribute value context of a "meta" element`,1437 },1438 {1439 desc: `non-whitelisted element name disallowed 4`,1440 tmpl: `<object src="{{ . }}"></object>`,1441 want: `actions must not occur in the "src" attribute value context of a "object" element`,1442 },1443 {1444 desc: `non-whitelisted element name disallowed 5`,1445 tmpl: `<object>{{ . }}</object>`,1446 want: `actions must not occur in the element content context of a "object" element`,1447 },1448 {1449 desc: `conditional URL prefix error in URL attribute value sanitization context 1`,1450 tmpl: `<q cite="{{if 0}}mailto:{{end}}{{ "suffix" }}">foo</q>`,1451 want: `actions must not occur after an ambiguous URL prefix`,1452 },1453 {1454 desc: `conditional URL prefix error in URL attribute value sanitization context 2`,1455 tmpl: `<q cite="{{if 0}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">foo</q>`,1456 want: `actions must not occur after an ambiguous URL prefix`,1457 },1458 {1459 desc: `conditional URL prefix error in URL attribute value sanitization context 3`,1460 tmpl: `<q cite="{{if 0}}mailto{{else}}javascript{{end}}:{{ "suffix" }}">foo</q>`,1461 want: `actions must not occur after an ambiguous URL prefix`,1462 },1463 {1464 desc: `conditional URL prefix error in URL attribute value sanitization context 4`,1465 tmpl: `<q cite="{{if 0}}mailto:{{else if 1}}javascript:{{else}}tel:{{end}}{{ "suffix" }}">foo</q>`,1466 want: `actions must not occur after an ambiguous URL prefix`,1467 },1468 {1469 desc: `conditional URL prefix error in URL attribute value sanitization context 5`,1470 tmpl: `<q cite="{{range .B}}mailto:{{end}}{{ "suffix" }}">foo</q>`,1471 data: []string{"foo", "bar"},1472 want: `actions must not occur after an ambiguous URL prefix`,1473 },1474 {1475 desc: `conditional URL prefix error in URL attribute value sanitization context 6`,1476 tmpl: `<q cite="{{range .B}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">foo</q>`,1477 data: []string{"foo", "bar"},1478 want: `actions must not occur after an ambiguous URL prefix`,1479 },1480 {1481 desc: `conditional URL prefix error in URL attribute value sanitization context 7`,1482 tmpl: `<q cite="{{with 0}}mailto:{{end}}{{ "suffix" }}">foo</q>`,1483 want: `actions must not occur after an ambiguous URL prefix`,1484 },1485 {1486 desc: `conditional URL prefix error in URL attribute value sanitization context 8`,1487 tmpl: `<q cite="{{with 0}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">foo</q>`,1488 want: `actions must not occur after an ambiguous URL prefix`,1489 },1490 {1491 desc: `conditional URL prefix error in TrustedResourceURL attribute value sanitization context 1`,1492 tmpl: `<link href="{{if 0}}mailto:{{end}}{{ "suffix" }}">`,1493 want: `actions must not occur after an ambiguous URL prefix`,1494 },1495 {1496 desc: `conditional URL prefix error in TrustedResourceURL attribute value sanitization context 2`,1497 tmpl: `<link href="{{if 0}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">`,1498 want: `actions must not occur after an ambiguous URL prefix`,1499 },1500 {1501 desc: `conditional URL prefix error in TrustedResourceURL attribute value sanitization context 3`,1502 tmpl: `<link href="{{if 0}}mailto{{else}}javascript{{end}}:{{ "suffix" }}">`,1503 want: `actions must not occur after an ambiguous URL prefix`,1504 },1505 {1506 desc: `conditional URL prefix error in TrustedResourceURL attribute value sanitization context 4`,1507 tmpl: `<link href="{{if 0}}mailto:{{else if 1}}javascript:{{else}}tel:{{end}}{{ "suffix" }}">`,1508 want: `actions must not occur after an ambiguous URL prefix`,1509 },1510 {1511 desc: `conditional URL prefix error in TrustedResourceURL attribute value sanitization context 5`,1512 tmpl: `<link href="{{range .B}}mailto:{{end}}{{ "suffix" }}">`,1513 data: []string{"foo", "bar"},1514 want: `actions must not occur after an ambiguous URL prefix`,1515 },1516 {1517 desc: `conditional URL prefix error in TrustedResourceURL attribute value sanitization context 6`,1518 tmpl: `<link href="{{range .B}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">`,1519 data: []string{"foo", "bar"},1520 want: `actions must not occur after an ambiguous URL prefix`,1521 },1522 {1523 desc: `conditional URL prefix error in TrustedResourceURL attribute value sanitization context 7`,1524 tmpl: `<link href="{{with 0}}mailto:{{end}}{{ "suffix" }}">`,1525 want: `actions must not occur after an ambiguous URL prefix`,1526 },1527 {1528 desc: `conditional URL prefix error in TrustedResourceURL attribute value sanitization context 8`,1529 tmpl: `<link href="{{with 0}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">`,1530 want: `actions must not occur after an ambiguous URL prefix`,1531 },1532 {1533 desc: `conditional URL prefix error in TrustedResourceURLOrURL attribute value sanitization context 1`,1534 tmpl: `<source src="{{if 0}}mailto:{{end}}{{ "suffix" }}">`,1535 want: `actions must not occur after an ambiguous URL prefix`,1536 },1537 {1538 desc: `conditional URL prefix error in TrustedResourceURLOrURL attribute value sanitization context 2`,1539 tmpl: `<source src="{{if 0}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">`,1540 want: `actions must not occur after an ambiguous URL prefix`,1541 },1542 {1543 desc: `conditional URL prefix error in TrustedResourceURLOrURL attribute value sanitization context 3`,1544 tmpl: `<source src="{{if 0}}mailto{{else}}javascript{{end}}:{{ "suffix" }}">`,1545 want: `actions must not occur after an ambiguous URL prefix`,1546 },1547 {1548 desc: `conditional URL prefix error in TrustedResourceURLOrURL attribute value sanitization context 4`,1549 tmpl: `<source src="{{if 0}}mailto:{{else if 1}}javascript:{{else}}tel:{{end}}{{ "suffix" }}">`,1550 want: `actions must not occur after an ambiguous URL prefix`,1551 },1552 {1553 desc: `conditional URL prefix error in TrustedResourceURLOrURL attribute value sanitization context 5`,1554 tmpl: `<source src="{{range .B}}mailto:{{end}}{{ "suffix" }}">`,1555 data: []string{"foo", "bar"},1556 want: `actions must not occur after an ambiguous URL prefix`,1557 },1558 {1559 desc: `conditional URL prefix error in TrustedResourceURLOrURL attribute value sanitization context 6`,1560 tmpl: `<source src="{{range .B}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">`,1561 data: []string{"foo", "bar"},1562 want: `actions must not occur after an ambiguous URL prefix`,1563 },1564 {1565 desc: `conditional URL prefix error in TrustedResourceURLOrURL attribute value sanitization context 7`,1566 tmpl: `<source src="{{with 0}}mailto:{{end}}{{ "suffix" }}">`,1567 want: `actions must not occur after an ambiguous URL prefix`,1568 },1569 {1570 desc: `conditional URL prefix error in TrustedResourceURLOrURL attribute value sanitization context 8`,1571 tmpl: `<source src="{{with 0}}mailto:{{else}}javascript:{{end}}{{ "suffix" }}">`,1572 want: `actions must not occur after an ambiguous URL prefix`,1573 },1574 {1575 desc: `error message reports accurate line number`,1576 tmpl: `<html>Line 11577Line 21578Line 31579Line 4<script>{{ "this will cause a run-time failure" }}</script>1580Line 51581Line 6</html>`,1582 want: `template: error message reports accurate line number:4:17: executing "error message reports accurate line number" at <_sanitizeScript>: error calling _sanitizeScript: expected a safehtml.Script value`,1583 fullMatch: true,1584 },1585 {1586 desc: `ends in non-text context 1`,1587 tmpl: `<a width=1 title={{"hello"}}`,1588 want: `ends in non-text context`,1589 },1590 {1591 desc: `ends in non-text context 2`,1592 tmpl: "<script>foo();",1593 want: `ends in non-text context`,1594 },1595 {1596 desc: `unquoted static attribute value 1`,1597 tmpl: `<input type=button value= 1+1=2>`,1598 want: `"=" in unquoted attr: "1+1=2"`,1599 },1600 {1601 desc: `unquoted static attribute value 2`,1602 tmpl: "<a class=`foo>",1603 want: "\"`\" in unquoted attr: \"`foo\"",1604 },1605 } {1606 tmpl := Must(New(test.desc).Parse(test.tmpl))1607 var b bytes.Buffer1608 err := tmpl.Execute(&b, test.data)1609 if err == nil {1610 t.Errorf("%s: expected an error", test.desc)1611 return1612 }1613 got := err.Error()1614 if test.fullMatch && got != test.want {1615 t.Errorf("%s: got error:\n\t%q\nwant:\n\t%q", test.desc, got, test.want)1616 return1617 }1618 if !test.fullMatch && !strings.Contains(got, test.want) {1619 t.Errorf("%s: error\n\t%q\ndoes not contain expected string\n\t%q", test.desc, got, test.want)1620 }1621 }1622}...

Full Screen

Full Screen

check-generic_test.go

Source:check-generic_test.go Github

copy

Full Screen

1package htmltest2import (3 "path"4 "testing"5 "github.com/wjdp/htmltest/issues"6)7var genericTests = []struct {8 fixture string9 errorCount int10}{11 {"areaValid.html", 0},12 {"areaBroken.html", 1},13 {"areaBlank.html", 2},14 {"areaMissing.html", 0},15 {"audioValid.html", 0},16 {"audioBroken.html", 5},17 {"audioBlank.html", 5},18 {"audioMissing.html", 0},19 {"citeValid.html", 0},20 {"citeBroken.html", 4},21 {"citeBlank.html", 4},22 {"citeMissing.html", 0},23 {"embedValid.html", 0},24 {"embedBroken.html", 1},25 {"embedBlank.html", 2},26 {"embedMissing.html", 0},27 {"iframeValid.html", 0},28 {"iframeBroken.html", 1},29 {"iframeBrokenButIgnored.html", 0},30 {"iframeBlank.html", 2},31 {"iframeMissing.html", 0},32 {"inputSrcValid.html", 0},33 {"inputSrcBroken.html", 1},34 {"inputSrcBlank.html", 2},35 {"inputSrcMissing.html", 0},36 {"objectValid.html", 0},37 {"objectBroken.html", 2},38 {"objectBlank.html", 2},39 {"objectMissing.html", 0},40 {"videoValid.html", 0},41 {"videoBroken.html", 9},42 {"videoBlank.html", 9},43 {"videoMissing.html", 0},44}45func TestCheckGenericTable(t *testing.T) {46 for _, gt := range genericTests {47 hT := tTestFileOpts(path.Join("fixtures/generic", gt.fixture),48 map[string]interface{}{"VCREnable": true})49 c := hT.issueStore.Count(issues.LevelError)50 if c != gt.errorCount {51 t.Error("error count", c, "!=", gt.errorCount, "in", gt.fixture)52 hT.issueStore.DumpIssues(true)53 }54 }55}...

Full Screen

Full Screen

Cite

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(html.EscapeString("This is <b>HTML</b>"))4}5import (6func main() {7 fmt.Println(html.UnescapeString("This is &lt;b&gt;HTML&lt;/b&gt;"))8}9import (10func main() {11 fmt.Println(html.EscapeString("This is <b>HTML</b>"))12}13import (14func main() {15 fmt.Println(html.UnescapeString("This is &lt;b&gt;HTML&lt;/b&gt;"))16}17import (18func main() {19 fmt.Println(html.EscapeString("This is <b>HTML</b>"))20}21import (22func main() {23 fmt.Println(html.UnescapeString("This is &lt;b&gt;HTML&lt;/b&gt;"))24}25import (26func main() {27 fmt.Println(html.EscapeString("This is <b>HTML</b>"))28}29import (

Full Screen

Full Screen

Cite

Using AI Code Generation

copy

Full Screen

1import (2func main() {3}4import (5func main() {6 fmt.Println(html.Comment("This is a comment"))7}8import (9func main() {10 fmt.Println(html.Commentf("This is a %s", "comment"))11}12import (13func main() {14 fmt.Println(html.Format("A < B"))15}16import (17func main() {18 fmt.Println(html.FormatBytes([]byte("A < B")))19}20import (21func main() {22 fmt.Println(html.FormatFloat(123.456))23}24import (25func main() {26 fmt.Println(html.FormatInt(123))27}28import (29func main() {30 fmt.Println(html.FormatUint(123))31}32import (33func main() {34 fmt.Println(html.FormatBool(true))35}

Full Screen

Full Screen

Cite

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(html.Cite("Hello, World!"))4}5import (6func main() {7 fmt.Println(html.Comment("Hello, World!"))8}9import (10func main() {11 fmt.Println(html.Commentf("Hello, %s!", "World"))12}13import (14func main() {15 fmt.Println(html.Format("Hello, <b>World</b>!"))16}17import (18func main() {19 fmt.Println(html.FormatBytes([]byte("Hello, <b>World</b>!")))20}21import (22func main() {23 fmt.Println(html.FormatHTML("Hello, <b>World</b>!"))24}25import (26func main() {27 fmt.Println(html.FormatHTMLBytes([]byte("Hello, <b>World</b>!")))28}29import (30func main() {31 html.FormatHTMLTo(&b, "Hello, <b>World</b>!")32 fmt.Println(b.String())33}

Full Screen

Full Screen

Cite

Using AI Code Generation

copy

Full Screen

1import (2func main() {3}4import (5func main() {6 fmt.Println(html.Code("Hello World"))7}8import (9func main() {10 fmt.Println(html.Data("Hello World"))11}12import (13func main() {14 fmt.Println(html.DataList("Hello World"))15}16import (17func main() {18 fmt.Println(html.Del("Hello World"))19}20import (21func main() {22 fmt.Println(html.Details("Hello World"))23}24import (25func main() {26 fmt.Println(html.Dialog("Hello World"))27}28import (29func main() {30 fmt.Println(html.Div("Hello World"))31}32import (33func main() {34 fmt.Println(html.Dfn("Hello World"))35}

Full Screen

Full Screen

Cite

Using AI Code Generation

copy

Full Screen

1import (2func main() {3}4import (5func main() {6 fmt.Println(html.Date())7}8import (9func main() {10 fmt.Println(html.EscapeString("hello <b>world</b>"))11}12hello &lt;b&gt;world&lt;/b&gt;13import (14func main() {15 fmt.Println(html.Format("hello <b>world</b>"))16}17import (18func main() {19 fmt.Println(html.FormatBytes([]byte("hello <b>world</b>")))20}21import (22func main() {23 fmt.Println(html.FormatFloat(123.45))24}25import (26func main() {27 fmt.Println(html.FormatInt(123))28}29import (30func main() {31 fmt.Println(html.FormatUint(123))32}33import (

Full Screen

Full Screen

Cite

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(html.Cite("Hello, world!"))4}5import (6func main() {7 fmt.Println(html.Cite("Hello, world!"))8}9import (10func main() {11 fmt.Println(html.Cite("Hello, world!"))12}13import (14func main() {15 fmt.Println(html.Cite("Hello, world!"))16}17import (18func main() {19 fmt.Println(html.Cite("Hello, world!"))20}21import (22func main() {23 fmt.Println(html.Cite("Hello, world!"))24}25import (26func main() {27 fmt.Println(html.Cite("Hello, world!"))28}29import (30func main() {31 fmt.Println(html.Cite("Hello, world!"))32}33import (34func main() {35 fmt.Println(html.Cite("Hello, world!"))36}

Full Screen

Full Screen

Cite

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(html.Cite("Hello World"))4}5import (6func main() {7 fmt.Println(html.Command("Hello World"))8}9import (10func main() {11 fmt.Println(html.Datalist("Hello World"))12}13import (14func main() {15 fmt.Println(html.Details("Hello World"))16}17import (18func main() {19 fmt.Println(html.Dialog("Hello World"))20}21import (22func main() {23 fmt.Println(html.Dfn("Hello World"))24}25import (26func main() {27 fmt.Println(html.Div("Hello World"))28}29import (30func main() {31 fmt.Println(html.Dl("Hello World"))32}

Full Screen

Full Screen

Cite

Using AI Code Generation

copy

Full Screen

1import (2func main() {3}4import (5func main() {6 fmt.Println(html.Date())7}8import (9func main() {10 fmt.Println(html.EscapeString("This is <b>HTML</b>"))11}12This is &lt;b&gt;HTML&lt;/b&gt;13import (14func main() {15 fmt.Println(html.FormatFloat(3.141592, 'f', 2, 64))16}17import (18func main() {19 fmt.Println(html.FormatInt(42, 16))20}21import (22func main() {23 fmt.Println(html.FormatUint(42, 16))24}25import (26func main() {27 fmt.Println(html.JSString("alert('Hello, world!');"))28}29alert('Hello, world!');30import (31func main() {32 fmt.Println(html.JS("alert('Hello, world!');"))33}34alert('Hello, world!');

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run K6 automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful