Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fffba7fe1 | ||
|
|
1c15a46489 | ||
|
|
318b29d661 | ||
|
|
c7a1baf1f0 | ||
|
|
19b11c49a9 | ||
|
|
6b8d891e4e | ||
|
|
cbffaffa6d | ||
|
|
8f2d48993a | ||
|
|
a8cea4cda0 | ||
|
|
342f4bf288 | ||
|
|
b4ea696b49 | ||
|
|
c619931610 | ||
|
|
bff1a8a3b1 | ||
|
|
cb6f9ce4c7 | ||
|
|
01dce10cbf | ||
|
|
86990145a6 | ||
|
|
8b5350b8e4 | ||
|
|
802ac98ffc | ||
|
|
554316495f | ||
|
|
69a8369b87 | ||
|
|
56612a5dc8 | ||
|
|
78bf569018 | ||
|
|
5fe252d191 | ||
|
|
dd58503eaf | ||
|
|
5c69520377 | ||
|
|
85a2bbe135 | ||
|
|
65904a75bc | ||
|
|
ad0c81b124 | ||
|
|
30f431fe2e | ||
|
|
e4806c2a18 | ||
|
|
cd73d696d0 | ||
|
|
18a71beb07 | ||
|
|
bde649ca89 | ||
|
|
ec0b7b7de4 | ||
|
|
a200931cae | ||
|
|
01479df5b6 | ||
|
|
610fc6598b | ||
|
|
8f72d82b63 | ||
|
|
4df8143754 | ||
|
|
70e139f3bc | ||
|
|
9b1d0910e1 | ||
|
|
54fc7ef5ad | ||
|
|
41848f960c | ||
|
|
c3882041a9 | ||
|
|
d98b9dac03 | ||
|
|
ca246227a8 | ||
|
|
02c38a83b9 | ||
|
|
6b68716f85 | ||
|
|
eacdcccb9e | ||
|
|
efcd0d5bd8 | ||
|
|
7510885c4d | ||
|
|
b4f17bdf98 | ||
|
|
879f5d9007 | ||
|
|
c50da29f00 | ||
|
|
465aef6f86 | ||
|
|
d9b3c09097 | ||
|
|
931e05acde | ||
|
|
78b1980875 | ||
|
|
8af4ac6444 | ||
|
|
0c34a28d85 | ||
|
|
6d62c5c99a | ||
|
|
6174b5e21e | ||
|
|
4081aa1277 |
5
AUTHORS
5
AUTHORS
@@ -10,6 +10,7 @@
|
||||
|
||||
Abhinav Gupta <abhinav.g90@gmail.com>
|
||||
Adrian O'Grady <elpollouk@gmail.com>
|
||||
Akshat Kumar <seed@mail.nanosouffle.net>
|
||||
Albert Strasheim <fullung@gmail.com>
|
||||
Aleksandar Dezelin <dezelin@gmail.com>
|
||||
Alex Brainman <alex.brainman@gmail.com>
|
||||
@@ -32,6 +33,7 @@ Arvindh Rajesh Tamilmani <art@a-30.net>
|
||||
Ben Olive <sionide21@gmail.com>
|
||||
Benny Siegert <bsiegert@gmail.com>
|
||||
Berengar Lehr <berengar.lehr@gmx.de>
|
||||
Bjorn Tillenius <bjorn@tillenius.me>
|
||||
Bjorn Tipling <bjorn.tipling@gmail.com>
|
||||
Blake Mizerany <blake.mizerany@gmail.com>
|
||||
Bobby Powers <bobbypowers@gmail.com>
|
||||
@@ -134,8 +136,10 @@ Mateusz Czapliński <czapkofan@gmail.com>
|
||||
Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
|
||||
Matthew Horsnell <matthew.horsnell@gmail.com>
|
||||
Micah Stetson <micah.stetson@gmail.com>
|
||||
Michael Chaten <mchaten@gmail.com>
|
||||
Michael Elkins <michael.elkins@gmail.com>
|
||||
Michael Hoisie <hoisie@gmail.com>
|
||||
Michael Lewis <mikelikespie@gmail.com>
|
||||
Michał Derkacz <ziutek@lnet.pl>
|
||||
Miek Gieben <miek@miek.nl>
|
||||
Mikael Tillenius <mikti42@gmail.com>
|
||||
@@ -183,6 +187,7 @@ Sergio Luis O. B. Correia <sergio@larces.uece.br>
|
||||
Shenghou Ma <minux.ma@gmail.com>
|
||||
Spring Mc <heresy.mc@gmail.com>
|
||||
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
||||
Stéphane Travostino <stephane.travostino@gmail.com>
|
||||
Stephen Weinberg <stephen@q5comm.com>
|
||||
Sven Almgren <sven@tras.se>
|
||||
Szabolcs Nagy <nsz@port70.net>
|
||||
|
||||
@@ -31,9 +31,11 @@
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Aaron Kemp <kemp.aaron@gmail.com>
|
||||
Abhinav Gupta <abhinav.g90@gmail.com>
|
||||
Adam Langley <agl@golang.org>
|
||||
Adrian O'Grady <elpollouk@gmail.com>
|
||||
Akshat Kumar <seed@mail.nanosouffle.net>
|
||||
Albert Strasheim <fullung@gmail.com>
|
||||
Aleksandar Dezelin <dezelin@gmail.com>
|
||||
Alex Brainman <alex.brainman@gmail.com>
|
||||
@@ -65,6 +67,7 @@ Ben Olive <sionide21@gmail.com>
|
||||
Benny Siegert <bsiegert@gmail.com>
|
||||
Berengar Lehr <Berengar.Lehr@gmx.de>
|
||||
Bill Neubauer <wcn@golang.org> <wcn@google.com>
|
||||
Bjorn Tillenius <bjorn@tillenius.me>
|
||||
Bjorn Tipling <bjorn.tipling@gmail.com>
|
||||
Blake Mizerany <blake.mizerany@gmail.com>
|
||||
Bobby Powers <bobbypowers@gmail.com>
|
||||
@@ -84,6 +87,7 @@ Christopher Nielsen <m4dh4tt3r@gmail.com>
|
||||
Christopher Redden <christopher.redden@gmail.com>
|
||||
Christopher Wedgwood <cw@f00f.org>
|
||||
Clement Skau <clementskau@gmail.com>
|
||||
Colby Ranger <cranger@google.com>
|
||||
Conrad Meyer <cemeyer@cs.washington.edu>
|
||||
Corey Thomasson <cthom.lists@gmail.com>
|
||||
Damian Gryski <dgryski@gmail.com>
|
||||
@@ -200,8 +204,10 @@ Matthew Horsnell <matthew.horsnell@gmail.com>
|
||||
Maxim Pimenov <mpimenov@google.com>
|
||||
Maxim Ushakov <ushakov@google.com>
|
||||
Micah Stetson <micah.stetson@gmail.com>
|
||||
Michael Chaten <mchaten@gmail.com>
|
||||
Michael Elkins <michael.elkins@gmail.com>
|
||||
Michael Hoisie <hoisie@gmail.com>
|
||||
Michael Lewis <mikelikespie@gmail.com>
|
||||
Michael Shields <mshields@google.com>
|
||||
Michael T. Jones <mtj@google.com> <michael.jones@gmail.com>
|
||||
Michał Derkacz <ziutek@lnet.pl>
|
||||
@@ -233,6 +239,7 @@ Peter Froehlich <peter.hans.froehlich@gmail.com>
|
||||
Peter McKenzie <petermck@google.com>
|
||||
Peter Mundy <go.peter.90@gmail.com>
|
||||
Péter Szabó <pts@google.com>
|
||||
Peter Weinberger <pjw@golang.org>
|
||||
Peter Williams <pwil3058@gmail.com>
|
||||
Phil Pennock <pdp@golang.org>
|
||||
Pieter Droogendijk <pieter@binky.org.uk>
|
||||
@@ -264,6 +271,7 @@ Sergio Luis O. B. Correia <sergio@larces.uece.br>
|
||||
Shenghou Ma <minux.ma@gmail.com>
|
||||
Spring Mc <heresy.mc@gmail.com>
|
||||
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
||||
Stéphane Travostino <stephane.travostino@gmail.com>
|
||||
Stephen Ma <stephenm@golang.org>
|
||||
Stephen Weinberg <stephen@q5comm.com>
|
||||
Sugu Sougoumarane <ssougou@gmail.com>
|
||||
|
||||
@@ -89,7 +89,7 @@ interface which has a <code>Set</code> method.
|
||||
|
||||
<p>
|
||||
To fill a rectangle with a solid color, use an <code>image.Uniform</code>
|
||||
source. The <code>ColorImage</code> type re-interprets a <code>Color</code> as a
|
||||
source. The <code>Uniform</code> type re-interprets a <code>Color</code> as a
|
||||
practically infinite-sized <code>Image</code> of that color. For those
|
||||
familiar with the design of Plan 9's draw library, there is no need
|
||||
for an explicit "repeat bit" in Go's slice-based image types; the
|
||||
@@ -189,7 +189,7 @@ To draw an image through a circular mask with center <code>p</code> and radius
|
||||
|
||||
<p>
|
||||
To draw a font glyph in blue starting from a point <code>p</code>, draw with
|
||||
an <code>image.ColorImage</code> source and an <code>image.Alpha mask</code>. For
|
||||
an <code>image.Uniform</code> source and an <code>image.Alpha mask</code>. For
|
||||
simplicity, we aren't performing any sub-pixel positioning or
|
||||
rendering, or correcting for a font's height above a baseline.
|
||||
</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<h1>Editing {{.Title |html}}</h1>
|
||||
<h1>Editing {{.Title}}</h1>
|
||||
|
||||
<form action="/save/{{.Title |html}}" method="POST">
|
||||
<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body |html}}</textarea></div>
|
||||
<form action="/save/{{.Title}}" method="POST">
|
||||
<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body}}</textarea></div>
|
||||
<div><input type="submit" value="Save"></div>
|
||||
</form>
|
||||
|
||||
@@ -359,10 +359,10 @@ First, we must add <code>html/template</code> to the list of imports:
|
||||
|
||||
<pre>
|
||||
import (
|
||||
<b>"html/template"</b>
|
||||
"http"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
<b>"html/template"</b>
|
||||
)
|
||||
</pre>
|
||||
|
||||
@@ -397,10 +397,11 @@ Template directives are enclosed in double curly braces.
|
||||
The <code>printf "%s" .Body</code> instruction is a function call
|
||||
that outputs <code>.Body</code> as a string instead of a stream of bytes,
|
||||
the same as a call to <code>fmt.Printf</code>.
|
||||
The <code>|html</code> part of each directive pipes the value through the
|
||||
<code>html</code> formatter before outputting it, which escapes HTML
|
||||
characters (such as replacing <code>></code> with <code>&gt;</code>),
|
||||
preventing user data from corrupting the form HTML.
|
||||
The <code>html/template</code> package helps guarantee that only safe and
|
||||
correct-looking HTML is generated by template actions. For instance, it
|
||||
automatically escapes any greater than sign (<code>></code>), replacing it
|
||||
with <code>&gt;</code>, to make sure user data does not corrupt the form
|
||||
HTML.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<h1>{{.Title |html}}</h1>
|
||||
<h1>{{.Title}}</h1>
|
||||
|
||||
<p>[<a href="/edit/{{.Title |html}}">edit</a>]</p>
|
||||
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
|
||||
|
||||
<div>{{printf "%s" .Body |html}}</div>
|
||||
<div>{{printf "%s" .Body}}</div>
|
||||
|
||||
@@ -236,7 +236,7 @@ are built and installed correctly.
|
||||
<p>
|
||||
As a convenience, the <code>go</code> command will assume the current directory
|
||||
if no import path is specified on the command line. This sequence of commands
|
||||
has the same affect as the one above:
|
||||
has the same effect as the one above:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -300,7 +300,8 @@ func main() {
|
||||
|
||||
<p>
|
||||
Next, run <code>go install</code>, which builds and installs the binary to
|
||||
<code>$GOPATH/bin</code>:
|
||||
<code>$GOPATH/bin</code> (or <code>$GOBIN</code>, if set; to simplify
|
||||
presentation, this document assumes <code>GOBIN</code> is unset):
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -384,7 +385,7 @@ package newmath
|
||||
import "testing"
|
||||
|
||||
func TestSqrt(t *testing.T) {
|
||||
const in, out = 9, 3
|
||||
const in, out = 4, 2
|
||||
if x := Sqrt(in); x != out {
|
||||
t.Errorf("Sqrt(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
@@ -397,7 +398,7 @@ Now run the test with <code>go test</code>:
|
||||
|
||||
<pre>
|
||||
$ go test example/newmath
|
||||
ok example/newmath
|
||||
ok example/newmath 0.165s
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -475,8 +476,8 @@ import "code.google.com/p/go.example/newmath"
|
||||
<p>
|
||||
This convention is the easiest way to make your Go packages available for
|
||||
others to use.
|
||||
The <a href="http://godashboard.appspot.com/package">Go Package Dashboard</a>
|
||||
displays a list of packages recently installed with the <code>go</code> command.
|
||||
The <a href="http://godashboard.appspot.com">Go Project Dashboard</a>
|
||||
is a list of external Go projects including programs and libraries.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -215,7 +215,7 @@ p[len(p)-1] = suffix
|
||||
|
||||
<step title="Choosing a suffix at random" src="doc/codewalk/markov.go:/next := choices/,/Shift/">
|
||||
To choose a suffix we use the
|
||||
<code><a href="/pkg/rand/#Intn">rand.Intn</a></code> function.
|
||||
<code><a href="/pkg/math/rand/#Intn">rand.Intn</a></code> function.
|
||||
It returns a random integer up to (but not including) the provided
|
||||
value. Passing in <code>len(choices)</code> gives us a random index
|
||||
into the full length of the list.
|
||||
@@ -287,11 +287,11 @@ a plan a man a plan a canal panama</pre>
|
||||
Here's a transcript of generating some text using the Go distribution's
|
||||
README file as source material:
|
||||
<pre>
|
||||
$ ./markov -words=10 < $GOROOT/go/README
|
||||
$ ./markov -words=10 < $GOROOT/README
|
||||
This is the source code repository for the Go source
|
||||
$ ./markov -prefix=1 -words=10 < $GOROOT/go/README
|
||||
$ ./markov -prefix=1 -words=10 < $GOROOT/README
|
||||
This is the go directory (the one containing this README).
|
||||
$ ./markov -prefix=1 -words=10 < $GOROOT/go/README
|
||||
$ ./markov -prefix=1 -words=10 < $GOROOT/README
|
||||
This is the variable if you have just untarred a</pre>
|
||||
</step>
|
||||
|
||||
|
||||
@@ -35,6 +35,20 @@ The go1 release corresponds to
|
||||
<code><a href="weekly.html#2012-03-27">weekly.2012-03-27</a></code>.
|
||||
</p>
|
||||
|
||||
<h3 id="go1.minor">Minor revisions</h3>
|
||||
|
||||
<p>
|
||||
go1.0.1 (released 2012/04/25) was issued to
|
||||
<a href="https://code.google.com/p/go/source/detail?r=a890477d3dfb">fix</a> an
|
||||
<a href="https://code.google.com/p/go/issues/detail?id=3545">escape analysis
|
||||
bug</a> that can lead to memory corruption.
|
||||
It also includes several minor code and documentation fixes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
See the <a href="http://code.google.com/p/go/source/list?name=release-branch.go1">go1 release branch history</a> for the complete list of changes.
|
||||
</p>
|
||||
|
||||
<h2 id="r60">r60 (released 2011/09/07)</h2>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -2291,7 +2291,7 @@ This would be useful if we wanted to refine the methods of <code>Logger</code>.
|
||||
</p>
|
||||
<pre>
|
||||
func (job *Job) Logf(format string, args ...interface{}) {
|
||||
job.Logger.Logf("%q: %s", job.Command, fmt.Sprintf(format, args))
|
||||
job.Logger.Logf("%q: %s", job.Command, fmt.Sprintf(format, args...))
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
@@ -2479,7 +2479,7 @@ func handle(queue chan *Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func Serve(clientRequests chan *clientRequests, quit chan bool) {
|
||||
func Serve(clientRequests chan *Request, quit chan bool) {
|
||||
// Start handlers
|
||||
for i := 0; i < MaxOutstanding; i++ {
|
||||
go handle(clientRequests)
|
||||
|
||||
@@ -1253,7 +1253,7 @@ Since the package's functionality is new, no updating is necessary.
|
||||
<p>
|
||||
In Go 1 the <a href="/pkg/net/http/"><code>http</code></a> package is refactored,
|
||||
putting some of the utilities into a
|
||||
<a href="/pkg/net/httputil/"><code>httputil</code></a> subdirectory.
|
||||
<a href="/pkg/net/http/httputil/"><code>httputil</code></a> subdirectory.
|
||||
These pieces are only rarely needed by HTTP clients.
|
||||
The affected items are:
|
||||
</p>
|
||||
@@ -1261,7 +1261,6 @@ The affected items are:
|
||||
<ul>
|
||||
<li>ClientConn</li>
|
||||
<li>DumpRequest</li>
|
||||
<li>DumpRequest</li>
|
||||
<li>DumpRequestOut</li>
|
||||
<li>DumpResponse</li>
|
||||
<li>NewChunkedReader</li>
|
||||
@@ -1789,7 +1788,7 @@ for full details.
|
||||
<td colspan="2"><hr></td>
|
||||
</tr>
|
||||
<tr><td>Atoui(x)</td> <td>ParseUint(x, 10, 0)§</td></tr>
|
||||
<tr><td>Atoi64(x)</td> <td>ParseInt(x, 10, 64)</td></tr>
|
||||
<tr><td>Atoui64(x)</td> <td>ParseUint(x, 10, 64)</td></tr>
|
||||
<tr>
|
||||
<td colspan="2"><hr></td>
|
||||
</tr>
|
||||
|
||||
@@ -1598,7 +1598,7 @@ Given a set of identifiers, an identifier is called <i>unique</i> if it is
|
||||
<i>different</i> from every other in the set.
|
||||
Two identifiers are different if they are spelled differently, or if they
|
||||
appear in different <a href="#Packages">packages</a> and are not
|
||||
<a href="Exported_identifiers">exported</a>. Otherwise, they are the same.
|
||||
<a href="#Exported_identifiers">exported</a>. Otherwise, they are the same.
|
||||
</p>
|
||||
|
||||
<h3 id="Constant_declarations">Constant declarations</h3>
|
||||
@@ -2396,7 +2396,7 @@ type T2 struct {
|
||||
|
||||
func (recv *T2) M2()
|
||||
|
||||
var p *T2 // with p != nil and p.T1 != nil
|
||||
var p *T2 // with p != nil and p.T0 != nil
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -2659,7 +2659,7 @@ back to the calling function when the function returns.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Calling a <code>nil</code> function value
|
||||
Calling a <code>nil</code> function value
|
||||
causes a <a href="#Run_time_panics">run-time panic</a>.
|
||||
</p>
|
||||
|
||||
@@ -3030,29 +3030,29 @@ These terms and the result of the comparisons are defined as follows:
|
||||
<li>
|
||||
Integer values are comparable and ordered, in the usual way.
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
Floating point values are comparable and ordered,
|
||||
as defined by the IEEE-754 standard.
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
Complex values are comparable.
|
||||
Two complex values <code>u</code> and <code>v</code> are
|
||||
equal if both <code>real(u) == real(v)</code> and
|
||||
<code>imag(u) == imag(v)</code>.
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
String values are comparable and ordered, lexically byte-wise.
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
Pointer values are comparable.
|
||||
Two pointer values are equal if they point to the same variable or if both have value <code>nil</code>.
|
||||
Pointers to distinct <a href="#Size_and_alignment_guarantees">zero-size</a> variables may or may not be equal.
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
Channel values are comparable.
|
||||
Two channel values are equal if they were created by the same call to <code>make</code>
|
||||
@@ -3065,7 +3065,7 @@ These terms and the result of the comparisons are defined as follows:
|
||||
Two interface values are equal if they have <a href="#Type_identity">identical</a> dynamic types
|
||||
and equal dynamic values or if both have value <code>nil</code>.
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
A value <code>x</code> of non-interface type <code>X</code> and
|
||||
a value <code>t</code> of interface type <code>T</code> are comparable when values
|
||||
@@ -3080,7 +3080,7 @@ These terms and the result of the comparisons are defined as follows:
|
||||
Two struct values are equal if their corresponding
|
||||
non-<a href="#Blank_identifier">blank</a> fields are equal.
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
Array values are comparable if values of the array element type are comparable.
|
||||
Two array values are equal if their corresponding elements are equal.
|
||||
@@ -5401,7 +5401,7 @@ type ArbitraryType int // shorthand for an arbitrary Go type; it is not a real
|
||||
type Pointer *ArbitraryType
|
||||
|
||||
func Alignof(variable ArbitraryType) uintptr
|
||||
func Offsetof(selector ArbitraryType) uinptr
|
||||
func Offsetof(selector ArbitraryType) uintptr
|
||||
func Sizeof(variable ArbitraryType) uintptr
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -106,26 +106,13 @@ On Windows, install <code>gcc</code> with
|
||||
|
||||
<p>
|
||||
To perform the next step you must have Mercurial installed. (Check that you
|
||||
have an <code>hg</code> command.) This suffices to install Mercurial on most
|
||||
Unix systems:
|
||||
have an <code>hg</code> command.)
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
sudo easy_install mercurial==2.0
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
On Ubuntu/Debian, the Mercurial in your distribution's
|
||||
package repository is most likely old and broken.
|
||||
You might try this first:
|
||||
</p>
|
||||
|
||||
<pre>apt-get install python-setuptools python-dev build-essential</pre>
|
||||
|
||||
<p>
|
||||
If that fails, or if you use Windows, install manually from the
|
||||
<a href="http://mercurial.selenic.com/wiki/Download">Mercurial Download</a>
|
||||
page.
|
||||
If you do not have a working Mercurial installation,
|
||||
follow the instructions on the
|
||||
<a href="http://mercurial.selenic.com/downloads/">Mercurial downloads</a> page.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
// codeEl - code editor element
|
||||
// outputEl - program output element
|
||||
// runEl - run button element
|
||||
// fmtEl - fmt button element (optional)
|
||||
// shareEl - share button element (optional)
|
||||
// shareURLEl - share URL text input element (optional)
|
||||
// shareRedirect - base URL to redirect to on share (optional)
|
||||
// preCompile - callback to mutate request data before compiling
|
||||
// postCompile - callback to read response data after compiling
|
||||
// simple - use plain textarea instead of CodeMirror.
|
||||
// toysEl - select element with a list of toys.
|
||||
// preCompile - callback to mutate request data before compiling (optional)
|
||||
// postCompile - callback to read response data after compiling (optional)
|
||||
// simple - use plain textarea instead of CodeMirror. (optional)
|
||||
// toysEl - select element with a list of toys. (optional)
|
||||
function playground(opts) {
|
||||
var simple = opts['simple'];
|
||||
var code = $(opts['codeEl']);
|
||||
@@ -97,7 +98,7 @@ function playground(opts) {
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
var errorRe = /[a-z]+\.go:([0-9]+): /g;
|
||||
var errorRe = /[a-z]+\.go:([0-9]+):/g;
|
||||
var result;
|
||||
while ((result = errorRe.exec(text)) != null) {
|
||||
var line = result[1]*1-1;
|
||||
@@ -120,13 +121,23 @@ function playground(opts) {
|
||||
function origin(href) {
|
||||
return (""+href).split("/").slice(0, 3).join("/");
|
||||
}
|
||||
function loading() {
|
||||
output.removeClass("error").html(
|
||||
'<div class="loading">Waiting for remote server...</div>'
|
||||
);
|
||||
}
|
||||
function setOutput(text, error) {
|
||||
output.empty();
|
||||
if (error) {
|
||||
output.addClass("error");
|
||||
}
|
||||
$("<pre/>").text(text).appendTo(output);
|
||||
}
|
||||
|
||||
var seq = 0;
|
||||
function run() {
|
||||
clearErrors();
|
||||
output.removeClass("error").html(
|
||||
'<div class="loading">Waiting for remote server...</div>'
|
||||
);
|
||||
loading();
|
||||
seq++;
|
||||
var cur = seq;
|
||||
var data = {"body": body()};
|
||||
@@ -141,8 +152,6 @@ function playground(opts) {
|
||||
if (seq != cur) {
|
||||
return;
|
||||
}
|
||||
pre = $("<pre/>");
|
||||
output.empty().append(pre);
|
||||
if (opts['postCompile']) {
|
||||
opts['postCompile'](data);
|
||||
}
|
||||
@@ -150,8 +159,7 @@ function playground(opts) {
|
||||
return;
|
||||
}
|
||||
if (data.compile_errors != "") {
|
||||
pre.text(data.compile_errors);
|
||||
output.addClass("error");
|
||||
setOutput(data.compile_errors, true);
|
||||
highlightErrors(data.compile_errors);
|
||||
return;
|
||||
}
|
||||
@@ -164,11 +172,10 @@ function playground(opts) {
|
||||
output.empty().append(img);
|
||||
return;
|
||||
}
|
||||
pre.text(out);
|
||||
setOutput(out, false);
|
||||
},
|
||||
error: function(xhr) {
|
||||
var text = "Error communicating with remote server.";
|
||||
console.log(xhr.status);
|
||||
if (xhr.status == 501) {
|
||||
text = xhr.responseText;
|
||||
}
|
||||
@@ -178,6 +185,41 @@ function playground(opts) {
|
||||
}
|
||||
$(opts['runEl']).click(run);
|
||||
|
||||
$(opts['fmtEl']).click(function() {
|
||||
loading();
|
||||
$.ajax("/fmt", {
|
||||
data: {"body": body()},
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if (data.Error) {
|
||||
setOutput(data.Error, true);
|
||||
highlightErrors(data.Error);
|
||||
return;
|
||||
}
|
||||
setBody(data.Body);
|
||||
setOutput("", false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(opts['toysEl']).bind('change', function() {
|
||||
var toy = $(this).val();
|
||||
loading();
|
||||
$.ajax("/doc/play/"+toy, {
|
||||
processData: false,
|
||||
type: "GET",
|
||||
complete: function(xhr) {
|
||||
if (xhr.status != 200) {
|
||||
setOutput("Server error; try again.", true);
|
||||
return;
|
||||
}
|
||||
setBody(xhr.responseText);
|
||||
setOutput("", false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (opts['shareEl'] != null && (opts['shareURLEl'] != null || opts['shareRedirect'] != null)) {
|
||||
var shareURL;
|
||||
if (opts['shareURLEl']) {
|
||||
@@ -213,22 +255,5 @@ function playground(opts) {
|
||||
});
|
||||
}
|
||||
|
||||
if (opts['toysEl'] != null) {
|
||||
$(opts['toysEl']).bind('change', function() {
|
||||
var toy = $(this).val();
|
||||
$.ajax("/doc/play/"+toy, {
|
||||
processData: false,
|
||||
type: "GET",
|
||||
complete: function(xhr) {
|
||||
if (xhr.status != 200) {
|
||||
alert("Server error; try again.")
|
||||
return;
|
||||
}
|
||||
setBody(xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
@@ -84,8 +84,8 @@ func ConvAndCircle() {
|
||||
|
||||
// CONV OMIT
|
||||
b := src.Bounds()
|
||||
m := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
|
||||
draw.Draw(m, m.Bounds(), src, b.Min, draw.Src)
|
||||
m := image.NewRGBA(b)
|
||||
draw.Draw(m, b, src, b.Min, draw.Src)
|
||||
// STOP OMIT
|
||||
|
||||
p := image.Point{100, 100}
|
||||
|
||||
@@ -108,7 +108,9 @@ table.dir td {
|
||||
word-wrap: break-word;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div#page.wide table.dir td.name {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.alert {
|
||||
color: #AA0000;
|
||||
}
|
||||
@@ -388,4 +390,3 @@ img.gopher {
|
||||
margin-bottom: -120px;
|
||||
}
|
||||
h2 { clear: right; }
|
||||
|
||||
|
||||
@@ -192,14 +192,14 @@
|
||||
{{if $.DirFlat}}
|
||||
{{if .HasPkg}}
|
||||
<tr>
|
||||
<td><a href="{{html .Path}}">{{html .Path}}</a></td>
|
||||
<td class="name"><a href="{{html .Path}}">{{html .Path}}</a></td>
|
||||
<td> </td>
|
||||
<td style="width: auto">{{html .Synopsis}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<tr>
|
||||
<td>{{repeat ` ` .Depth}}<a href="{{html .Path}}">{{html .Name}}</a></td>
|
||||
<td class="name">{{repeat ` ` .Depth}}<a href="{{html .Path}}">{{html .Name}}</a></td>
|
||||
<td> </td>
|
||||
<td style="width: auto">{{html .Synopsis}}</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Copyright 2012 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
include ../../Make.dist
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
|
||||
Cov is a rudimentary code coverage tool.
|
||||
|
||||
Usage:
|
||||
go tool cov [-lsv] [-g substring] [-m minlines] [6.out args]
|
||||
|
||||
Given a command to run, it runs the command while tracking which
|
||||
sections of code have been executed. When the command finishes,
|
||||
cov prints the line numbers of sections of code in the binary that
|
||||
were not executed. With no arguments it assumes the command "6.out".
|
||||
|
||||
|
||||
The options are:
|
||||
|
||||
-l
|
||||
print full path names instead of paths relative to the current directory
|
||||
-s
|
||||
show the source code that didn't execute, in addition to the line numbers.
|
||||
-v
|
||||
print debugging information during the run.
|
||||
-g substring
|
||||
restrict the coverage analysis to functions or files whose names contain substring
|
||||
-m minlines
|
||||
only report uncovered sections of code larger than minlines lines
|
||||
|
||||
The program is the same for all architectures: 386, amd64, and arm.
|
||||
|
||||
*/
|
||||
package documentation
|
||||
@@ -1,480 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
* code coverage
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include "tree.h"
|
||||
|
||||
#include <ureg_amd64.h>
|
||||
#include <mach.h>
|
||||
typedef struct Ureg Ureg;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: cov [-lsv] [-g substring] [-m minlines] [6.out args...]\n");
|
||||
fprint(2, "-g specifies pattern of interesting functions or files\n");
|
||||
exits("usage");
|
||||
}
|
||||
|
||||
typedef struct Range Range;
|
||||
struct Range
|
||||
{
|
||||
uvlong pc;
|
||||
uvlong epc;
|
||||
};
|
||||
|
||||
int chatty;
|
||||
int fd;
|
||||
int longnames;
|
||||
int pid;
|
||||
int doshowsrc;
|
||||
Map *mem;
|
||||
Map *text;
|
||||
Fhdr fhdr;
|
||||
char *substring;
|
||||
char cwd[1000];
|
||||
int ncwd;
|
||||
int minlines = -1000;
|
||||
|
||||
Tree breakpoints; // code ranges not run
|
||||
|
||||
/*
|
||||
* comparison for Range structures
|
||||
* they are "equal" if they overlap, so
|
||||
* that a search for [pc, pc+1) finds the
|
||||
* Range containing pc.
|
||||
*/
|
||||
int
|
||||
rangecmp(void *va, void *vb)
|
||||
{
|
||||
Range *a = va, *b = vb;
|
||||
if(a->epc <= b->pc)
|
||||
return 1;
|
||||
if(b->epc <= a->pc)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* remember that we ran the section of code [pc, epc).
|
||||
*/
|
||||
void
|
||||
ran(uvlong pc, uvlong epc)
|
||||
{
|
||||
Range key;
|
||||
Range *r;
|
||||
uvlong oldepc;
|
||||
|
||||
if(chatty)
|
||||
print("run %#llux-%#llux\n", pc, epc);
|
||||
|
||||
key.pc = pc;
|
||||
key.epc = pc+1;
|
||||
r = treeget(&breakpoints, &key);
|
||||
if(r == nil)
|
||||
sysfatal("unchecked breakpoint at %#llux+%d", pc, (int)(epc-pc));
|
||||
|
||||
// Might be that the tail of the sequence
|
||||
// was run already, so r->epc is before the end.
|
||||
// Adjust len.
|
||||
if(epc > r->epc)
|
||||
epc = r->epc;
|
||||
|
||||
if(r->pc == pc) {
|
||||
r->pc = epc;
|
||||
} else {
|
||||
// Chop r to before pc;
|
||||
// add new entry for after if needed.
|
||||
// Changing r->epc does not affect r's position in the tree.
|
||||
oldepc = r->epc;
|
||||
r->epc = pc;
|
||||
if(epc < oldepc) {
|
||||
Range *n;
|
||||
n = malloc(sizeof *n);
|
||||
n->pc = epc;
|
||||
n->epc = oldepc;
|
||||
treeput(&breakpoints, n, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
showsrc(char *file, int line1, int line2)
|
||||
{
|
||||
Biobuf *b;
|
||||
char *p;
|
||||
int n, stop;
|
||||
|
||||
if((b = Bopen(file, OREAD)) == nil) {
|
||||
print("\topen %s: %r\n", file);
|
||||
return;
|
||||
}
|
||||
|
||||
for(n=1; n<line1 && (p = Brdstr(b, '\n', 1)) != nil; n++)
|
||||
free(p);
|
||||
|
||||
// print up to five lines (this one and 4 more).
|
||||
// if there are more than five lines, print 4 and "..."
|
||||
stop = n+4;
|
||||
if(stop > line2)
|
||||
stop = line2;
|
||||
if(stop < line2)
|
||||
stop--;
|
||||
for(; n<=stop && (p = Brdstr(b, '\n', 1)) != nil; n++) {
|
||||
print(" %d %s\n", n, p);
|
||||
free(p);
|
||||
}
|
||||
if(n < line2)
|
||||
print(" ...\n");
|
||||
Bterm(b);
|
||||
}
|
||||
|
||||
/*
|
||||
* if s is in the current directory or below,
|
||||
* return the relative path.
|
||||
*/
|
||||
char*
|
||||
shortname(char *s)
|
||||
{
|
||||
if(!longnames && strlen(s) > ncwd && memcmp(s, cwd, ncwd) == 0 && s[ncwd] == '/')
|
||||
return s+ncwd+1;
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* we've decided that [pc, epc) did not run.
|
||||
* do something about it.
|
||||
*/
|
||||
void
|
||||
missing(uvlong pc, uvlong epc)
|
||||
{
|
||||
char file[1000];
|
||||
int line1, line2;
|
||||
char buf[100];
|
||||
Symbol s;
|
||||
char *p;
|
||||
uvlong uv;
|
||||
|
||||
if(!findsym(pc, CTEXT, &s) || !fileline(file, sizeof file, pc)) {
|
||||
notfound:
|
||||
print("%#llux-%#llux\n", pc, epc);
|
||||
return;
|
||||
}
|
||||
p = strrchr(file, ':');
|
||||
*p++ = 0;
|
||||
line1 = atoi(p);
|
||||
for(uv=pc; uv<epc; ) {
|
||||
if(!fileline(file, sizeof file, epc-2))
|
||||
goto notfound;
|
||||
uv += machdata->instsize(text, uv);
|
||||
}
|
||||
p = strrchr(file, ':');
|
||||
*p++ = 0;
|
||||
line2 = atoi(p);
|
||||
|
||||
if(line2+1-line2 < minlines)
|
||||
return;
|
||||
|
||||
if(pc == s.value) {
|
||||
// never entered function
|
||||
print("%s:%d %s never called (%#llux-%#llux)\n", shortname(file), line1, s.name, pc, epc);
|
||||
return;
|
||||
}
|
||||
if(pc <= s.value+13) {
|
||||
// probably stub for stack growth.
|
||||
// check whether last instruction is call to morestack.
|
||||
// the -5 below is the length of
|
||||
// CALL sys.morestack.
|
||||
buf[0] = 0;
|
||||
machdata->das(text, epc-5, 0, buf, sizeof buf);
|
||||
if(strstr(buf, "morestack"))
|
||||
return;
|
||||
}
|
||||
|
||||
if(epc - pc == 5) {
|
||||
// check for CALL sys.panicindex
|
||||
buf[0] = 0;
|
||||
machdata->das(text, pc, 0, buf, sizeof buf);
|
||||
if(strstr(buf, "panicindex"))
|
||||
return;
|
||||
}
|
||||
|
||||
if(epc - pc == 2 || epc -pc == 3) {
|
||||
// check for XORL inside shift.
|
||||
// (on x86 have to implement large left or unsigned right shift with explicit zeroing).
|
||||
// f+90 0x00002c9f CMPL CX,$20
|
||||
// f+93 0x00002ca2 JCS f+97(SB)
|
||||
// f+95 0x00002ca4 XORL AX,AX <<<
|
||||
// f+97 0x00002ca6 SHLL CL,AX
|
||||
// f+99 0x00002ca8 MOVL $1,CX
|
||||
//
|
||||
// f+c8 0x00002cd7 CMPL CX,$40
|
||||
// f+cb 0x00002cda JCS f+d0(SB)
|
||||
// f+cd 0x00002cdc XORQ AX,AX <<<
|
||||
// f+d0 0x00002cdf SHLQ CL,AX
|
||||
// f+d3 0x00002ce2 MOVQ $1,CX
|
||||
buf[0] = 0;
|
||||
machdata->das(text, pc, 0, buf, sizeof buf);
|
||||
if(strncmp(buf, "XOR", 3) == 0) {
|
||||
machdata->das(text, epc, 0, buf, sizeof buf);
|
||||
if(strncmp(buf, "SHL", 3) == 0 || strncmp(buf, "SHR", 3) == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(epc - pc == 3) {
|
||||
// check for SAR inside shift.
|
||||
// (on x86 have to implement large signed right shift as >>31).
|
||||
// f+36 0x00016216 CMPL CX,$20
|
||||
// f+39 0x00016219 JCS f+3e(SB)
|
||||
// f+3b 0x0001621b SARL $1f,AX <<<
|
||||
// f+3e 0x0001621e SARL CL,AX
|
||||
// f+40 0x00016220 XORL CX,CX
|
||||
// f+42 0x00016222 CMPL CX,AX
|
||||
buf[0] = 0;
|
||||
machdata->das(text, pc, 0, buf, sizeof buf);
|
||||
if(strncmp(buf, "SAR", 3) == 0) {
|
||||
machdata->das(text, epc, 0, buf, sizeof buf);
|
||||
if(strncmp(buf, "SAR", 3) == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// show first instruction to make clear where we were.
|
||||
machdata->das(text, pc, 0, buf, sizeof buf);
|
||||
|
||||
if(line1 != line2)
|
||||
print("%s:%d,%d %#llux-%#llux %s\n",
|
||||
shortname(file), line1, line2, pc, epc, buf);
|
||||
else
|
||||
print("%s:%d %#llux-%#llux %s\n",
|
||||
shortname(file), line1, pc, epc, buf);
|
||||
if(doshowsrc)
|
||||
showsrc(file, line1, line2);
|
||||
}
|
||||
|
||||
/*
|
||||
* walk the tree, calling missing for each non-empty
|
||||
* section of missing code.
|
||||
*/
|
||||
void
|
||||
walktree(TreeNode *t)
|
||||
{
|
||||
Range *n;
|
||||
|
||||
if(t == nil)
|
||||
return;
|
||||
walktree(t->left);
|
||||
n = t->key;
|
||||
if(n->pc < n->epc)
|
||||
missing(n->pc, n->epc);
|
||||
walktree(t->right);
|
||||
}
|
||||
|
||||
/*
|
||||
* set a breakpoint all over [pc, epc)
|
||||
* and remember that we did.
|
||||
*/
|
||||
void
|
||||
breakpoint(uvlong pc, uvlong epc)
|
||||
{
|
||||
Range *r;
|
||||
|
||||
r = malloc(sizeof *r);
|
||||
r->pc = pc;
|
||||
r->epc = epc;
|
||||
treeput(&breakpoints, r, r);
|
||||
|
||||
for(; pc < epc; pc+=machdata->bpsize)
|
||||
put1(mem, pc, machdata->bpinst, machdata->bpsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* install breakpoints over all text symbols
|
||||
* that match the pattern.
|
||||
*/
|
||||
void
|
||||
cover(void)
|
||||
{
|
||||
Symbol s;
|
||||
char *lastfn;
|
||||
uvlong lastpc;
|
||||
int i;
|
||||
char buf[200];
|
||||
|
||||
lastfn = nil;
|
||||
lastpc = 0;
|
||||
for(i=0; textsym(&s, i); i++) {
|
||||
switch(s.type) {
|
||||
case 'T':
|
||||
case 't':
|
||||
if(lastpc != 0) {
|
||||
breakpoint(lastpc, s.value);
|
||||
lastpc = 0;
|
||||
}
|
||||
// Ignore second entry for a given name;
|
||||
// that's the debugging blob.
|
||||
if(lastfn && strcmp(s.name, lastfn) == 0)
|
||||
break;
|
||||
lastfn = s.name;
|
||||
buf[0] = 0;
|
||||
fileline(buf, sizeof buf, s.value);
|
||||
if(substring == nil || strstr(buf, substring) || strstr(s.name, substring))
|
||||
lastpc = s.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uvlong
|
||||
rgetzero(Map *map, char *reg)
|
||||
{
|
||||
USED(map);
|
||||
USED(reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove the breakpoints at pc and successive instructions,
|
||||
* up to and including the first jump or other control flow transfer.
|
||||
*/
|
||||
void
|
||||
uncover(uvlong pc)
|
||||
{
|
||||
uchar buf[1000];
|
||||
int n, n1, n2;
|
||||
uvlong foll[2];
|
||||
|
||||
// Double-check that we stopped at a breakpoint.
|
||||
if(get1(mem, pc, buf, machdata->bpsize) < 0)
|
||||
sysfatal("read mem inst at %#llux: %r", pc);
|
||||
if(memcmp(buf, machdata->bpinst, machdata->bpsize) != 0)
|
||||
sysfatal("stopped at %#llux; not at breakpoint %d", pc, machdata->bpsize);
|
||||
|
||||
// Figure out how many bytes of straight-line code
|
||||
// there are in the text starting at pc.
|
||||
n = 0;
|
||||
while(n < sizeof buf) {
|
||||
n1 = machdata->instsize(text, pc+n);
|
||||
if(n+n1 > sizeof buf)
|
||||
break;
|
||||
n2 = machdata->foll(text, pc+n, rgetzero, foll);
|
||||
n += n1;
|
||||
if(n2 != 1 || foll[0] != pc+n)
|
||||
break;
|
||||
}
|
||||
|
||||
// Record that this section of code ran.
|
||||
ran(pc, pc+n);
|
||||
|
||||
// Put original instructions back.
|
||||
if(get1(text, pc, buf, n) < 0)
|
||||
sysfatal("get1: %r");
|
||||
if(put1(mem, pc, buf, n) < 0)
|
||||
sysfatal("put1: %r");
|
||||
}
|
||||
|
||||
int
|
||||
startprocess(char **argv)
|
||||
{
|
||||
int pid;
|
||||
|
||||
if((pid = fork()) < 0)
|
||||
sysfatal("fork: %r");
|
||||
if(pid == 0) {
|
||||
pid = getpid();
|
||||
if(ctlproc(pid, "hang") < 0)
|
||||
sysfatal("ctlproc hang: %r");
|
||||
exec(argv[0], argv);
|
||||
sysfatal("exec %s: %r", argv[0]);
|
||||
}
|
||||
if(ctlproc(pid, "attached") < 0 || ctlproc(pid, "waitstop") < 0)
|
||||
sysfatal("attach %d %s: %r", pid, argv[0]);
|
||||
return pid;
|
||||
}
|
||||
|
||||
int
|
||||
go(void)
|
||||
{
|
||||
uvlong pc;
|
||||
char buf[100];
|
||||
int n;
|
||||
|
||||
for(n = 0;; n++) {
|
||||
ctlproc(pid, "startstop");
|
||||
if(get8(mem, offsetof(Ureg, ip), &pc) < 0) {
|
||||
rerrstr(buf, sizeof buf);
|
||||
if(strstr(buf, "exited") || strstr(buf, "No such process"))
|
||||
return n;
|
||||
sysfatal("cannot read pc: %r");
|
||||
}
|
||||
pc--;
|
||||
if(put8(mem, offsetof(Ureg, ip), pc) < 0)
|
||||
sysfatal("cannot write pc: %r");
|
||||
uncover(pc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int n;
|
||||
|
||||
ARGBEGIN{
|
||||
case 'g':
|
||||
substring = EARGF(usage());
|
||||
break;
|
||||
case 'l':
|
||||
longnames++;
|
||||
break;
|
||||
case 'n':
|
||||
minlines = atoi(EARGF(usage()));
|
||||
break;
|
||||
case 's':
|
||||
doshowsrc = 1;
|
||||
break;
|
||||
case 'v':
|
||||
chatty++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND
|
||||
|
||||
getwd(cwd, sizeof cwd);
|
||||
ncwd = strlen(cwd);
|
||||
|
||||
if(argc == 0) {
|
||||
*--argv = "6.out";
|
||||
}
|
||||
fd = open(argv[0], OREAD);
|
||||
if(fd < 0)
|
||||
sysfatal("open %s: %r", argv[0]);
|
||||
if(crackhdr(fd, &fhdr) <= 0)
|
||||
sysfatal("crackhdr: %r");
|
||||
machbytype(fhdr.type);
|
||||
if(syminit(fd, &fhdr) <= 0)
|
||||
sysfatal("syminit: %r");
|
||||
text = loadmap(nil, fd, &fhdr);
|
||||
if(text == nil)
|
||||
sysfatal("loadmap: %r");
|
||||
pid = startprocess(argv);
|
||||
mem = attachproc(pid, &fhdr);
|
||||
if(mem == nil)
|
||||
sysfatal("attachproc: %r");
|
||||
breakpoints.cmp = rangecmp;
|
||||
cover();
|
||||
n = go();
|
||||
walktree(breakpoints.root);
|
||||
if(chatty)
|
||||
print("%d breakpoints\n", n);
|
||||
detachproc(mem);
|
||||
exits(0);
|
||||
}
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
// Renamed from Map to Tree to avoid conflict with libmach.
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2007 Russ Cox, Tom Bergan, Austin Clements,
|
||||
Massachusetts Institute of Technology
|
||||
Portions Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Mutable map structure, but still based on
|
||||
// Okasaki, Red Black Trees in a Functional Setting, JFP 1999,
|
||||
// which is a lot easier than the traditional red-black
|
||||
// and plenty fast enough for me. (Also I could copy
|
||||
// and edit fmap.c.)
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "tree.h"
|
||||
|
||||
enum
|
||||
{
|
||||
Red = 0,
|
||||
Black = 1
|
||||
};
|
||||
|
||||
|
||||
// Red-black trees are binary trees with this property:
|
||||
// 1. No red node has a red parent.
|
||||
// 2. Every path from the root to a leaf contains the
|
||||
// same number of black nodes.
|
||||
|
||||
static TreeNode*
|
||||
rwTreeNode(TreeNode *p, int color, TreeNode *left, void *key, void *value, TreeNode *right)
|
||||
{
|
||||
if(p == nil)
|
||||
p = malloc(sizeof *p);
|
||||
p->color = color;
|
||||
p->left = left;
|
||||
p->key = key;
|
||||
p->value = value;
|
||||
p->right = right;
|
||||
return p;
|
||||
}
|
||||
|
||||
static TreeNode*
|
||||
balance(TreeNode *m0)
|
||||
{
|
||||
void *xk, *xv, *yk, *yv, *zk, *zv;
|
||||
TreeNode *a, *b, *c, *d;
|
||||
TreeNode *m1, *m2;
|
||||
int color;
|
||||
TreeNode *left, *right;
|
||||
void *key, *value;
|
||||
|
||||
color = m0->color;
|
||||
left = m0->left;
|
||||
key = m0->key;
|
||||
value = m0->value;
|
||||
right = m0->right;
|
||||
|
||||
// Okasaki notation: (T is mkTreeNode, B is Black, R is Red, x, y, z are key-value.
|
||||
//
|
||||
// balance B (T R (T R a x b) y c) z d
|
||||
// balance B (T R a x (T R b y c)) z d
|
||||
// balance B a x (T R (T R b y c) z d)
|
||||
// balance B a x (T R b y (T R c z d))
|
||||
//
|
||||
// = T R (T B a x b) y (T B c z d)
|
||||
|
||||
if(color == Black){
|
||||
if(left && left->color == Red){
|
||||
if(left->left && left->left->color == Red){
|
||||
a = left->left->left;
|
||||
xk = left->left->key;
|
||||
xv = left->left->value;
|
||||
b = left->left->right;
|
||||
yk = left->key;
|
||||
yv = left->value;
|
||||
c = left->right;
|
||||
zk = key;
|
||||
zv = value;
|
||||
d = right;
|
||||
m1 = left;
|
||||
m2 = left->left;
|
||||
goto hard;
|
||||
}else if(left->right && left->right->color == Red){
|
||||
a = left->left;
|
||||
xk = left->key;
|
||||
xv = left->value;
|
||||
b = left->right->left;
|
||||
yk = left->right->key;
|
||||
yv = left->right->value;
|
||||
c = left->right->right;
|
||||
zk = key;
|
||||
zv = value;
|
||||
d = right;
|
||||
m1 = left;
|
||||
m2 = left->right;
|
||||
goto hard;
|
||||
}
|
||||
}else if(right && right->color == Red){
|
||||
if(right->left && right->left->color == Red){
|
||||
a = left;
|
||||
xk = key;
|
||||
xv = value;
|
||||
b = right->left->left;
|
||||
yk = right->left->key;
|
||||
yv = right->left->value;
|
||||
c = right->left->right;
|
||||
zk = right->key;
|
||||
zv = right->value;
|
||||
d = right->right;
|
||||
m1 = right;
|
||||
m2 = right->left;
|
||||
goto hard;
|
||||
}else if(right->right && right->right->color == Red){
|
||||
a = left;
|
||||
xk = key;
|
||||
xv = value;
|
||||
b = right->left;
|
||||
yk = right->key;
|
||||
yv = right->value;
|
||||
c = right->right->left;
|
||||
zk = right->right->key;
|
||||
zv = right->right->value;
|
||||
d = right->right->right;
|
||||
m1 = right;
|
||||
m2 = right->right;
|
||||
goto hard;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rwTreeNode(m0, color, left, key, value, right);
|
||||
|
||||
hard:
|
||||
return rwTreeNode(m0, Red, rwTreeNode(m1, Black, a, xk, xv, b),
|
||||
yk, yv, rwTreeNode(m2, Black, c, zk, zv, d));
|
||||
}
|
||||
|
||||
static TreeNode*
|
||||
ins0(TreeNode *p, void *k, void *v, TreeNode *rw)
|
||||
{
|
||||
if(p == nil)
|
||||
return rwTreeNode(rw, Red, nil, k, v, nil);
|
||||
if(p->key == k){
|
||||
if(rw)
|
||||
return rwTreeNode(rw, p->color, p->left, k, v, p->right);
|
||||
p->value = v;
|
||||
return p;
|
||||
}
|
||||
if(p->key < k)
|
||||
p->left = ins0(p->left, k, v, rw);
|
||||
else
|
||||
p->right = ins0(p->right, k, v, rw);
|
||||
return balance(p);
|
||||
}
|
||||
|
||||
static TreeNode*
|
||||
ins1(Tree *m, TreeNode *p, void *k, void *v, TreeNode *rw)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(p == nil)
|
||||
return rwTreeNode(rw, Red, nil, k, v, nil);
|
||||
i = m->cmp(p->key, k);
|
||||
if(i == 0){
|
||||
if(rw)
|
||||
return rwTreeNode(rw, p->color, p->left, k, v, p->right);
|
||||
p->value = v;
|
||||
return p;
|
||||
}
|
||||
if(i < 0)
|
||||
p->left = ins1(m, p->left, k, v, rw);
|
||||
else
|
||||
p->right = ins1(m, p->right, k, v, rw);
|
||||
return balance(p);
|
||||
}
|
||||
|
||||
void
|
||||
treeputelem(Tree *m, void *key, void *val, TreeNode *rw)
|
||||
{
|
||||
if(m->cmp)
|
||||
m->root = ins1(m, m->root, key, val, rw);
|
||||
else
|
||||
m->root = ins0(m->root, key, val, rw);
|
||||
}
|
||||
|
||||
void
|
||||
treeput(Tree *m, void *key, void *val)
|
||||
{
|
||||
treeputelem(m, key, val, nil);
|
||||
}
|
||||
|
||||
void*
|
||||
treeget(Tree *m, void *key)
|
||||
{
|
||||
int i;
|
||||
TreeNode *p;
|
||||
|
||||
p = m->root;
|
||||
if(m->cmp){
|
||||
for(;;){
|
||||
if(p == nil)
|
||||
return nil;
|
||||
i = m->cmp(p->key, key);
|
||||
if(i < 0)
|
||||
p = p->left;
|
||||
else if(i > 0)
|
||||
p = p->right;
|
||||
else
|
||||
return p->value;
|
||||
}
|
||||
}else{
|
||||
for(;;){
|
||||
if(p == nil)
|
||||
return nil;
|
||||
if(p->key == key)
|
||||
return p->value;
|
||||
if(p->key < key)
|
||||
p = p->left;
|
||||
else
|
||||
p = p->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// Renamed from Map to Tree to avoid conflict with libmach.
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2007 Russ Cox, Tom Bergan, Austin Clements,
|
||||
Massachusetts Institute of Technology
|
||||
Portions Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef struct Tree Tree;
|
||||
typedef struct TreeNode TreeNode;
|
||||
struct Tree
|
||||
{
|
||||
int (*cmp)(void*, void*);
|
||||
TreeNode *root;
|
||||
};
|
||||
|
||||
struct TreeNode
|
||||
{
|
||||
int color;
|
||||
TreeNode *left;
|
||||
void *key;
|
||||
void *value;
|
||||
TreeNode *right;
|
||||
};
|
||||
|
||||
void *treeget(Tree*, void*);
|
||||
void treeput(Tree*, void*, void*);
|
||||
void treeputelem(Tree*, void*, void*, TreeNode*);
|
||||
13
src/cmd/dist/build.c
vendored
13
src/cmd/dist/build.c
vendored
@@ -19,7 +19,7 @@ char *goos;
|
||||
char *goroot = GOROOT_FINAL;
|
||||
char *goroot_final = GOROOT_FINAL;
|
||||
char *workdir;
|
||||
char *tooldir;
|
||||
char *tooldir;
|
||||
char *gochar;
|
||||
char *goversion;
|
||||
char *slash; // / for unix, \ for windows
|
||||
@@ -1462,7 +1462,7 @@ void
|
||||
cmdbanner(int argc, char **argv)
|
||||
{
|
||||
char *pathsep;
|
||||
Buf b, b1, search;
|
||||
Buf b, b1, search, path;
|
||||
|
||||
ARGBEGIN{
|
||||
case 'v':
|
||||
@@ -1478,6 +1478,7 @@ cmdbanner(int argc, char **argv)
|
||||
binit(&b);
|
||||
binit(&b1);
|
||||
binit(&search);
|
||||
binit(&path);
|
||||
|
||||
xprintf("\n");
|
||||
xprintf("---\n");
|
||||
@@ -1495,9 +1496,10 @@ cmdbanner(int argc, char **argv)
|
||||
xprintf("*** You need to add %s to your PATH.\n", gobin);
|
||||
|
||||
if(streq(gohostos, "darwin")) {
|
||||
xprintf("\n"
|
||||
"On OS X the debuggers must be installed setgid procmod.\n"
|
||||
"Read and run ./sudo.bash to install the debuggers.\n");
|
||||
if(isfile(bpathf(&path, "%s/cov", tooldir)))
|
||||
xprintf("\n"
|
||||
"On OS X the debuggers must be installed setgid procmod.\n"
|
||||
"Read and run ./sudo.bash to install the debuggers.\n");
|
||||
}
|
||||
|
||||
if(!streq(goroot_final, goroot)) {
|
||||
@@ -1509,6 +1511,7 @@ cmdbanner(int argc, char **argv)
|
||||
bfree(&b);
|
||||
bfree(&b1);
|
||||
bfree(&search);
|
||||
bfree(&path);
|
||||
}
|
||||
|
||||
// Version prints the Go version.
|
||||
|
||||
@@ -131,7 +131,12 @@ escfunc(Node *func)
|
||||
}
|
||||
|
||||
// walk will take the address of cvar->closure later and assign it to cvar.
|
||||
// handle that here by linking a fake oaddr node directly to the closure.
|
||||
// linking a fake oaddr node directly to the closure handles the case
|
||||
// of the closure itself leaking. Following the flow of the value to th
|
||||
// paramref is done in escflow, because if we did that here, it would look
|
||||
// like the original is assigned out of its loop depth, whereas it's just
|
||||
// assigned to something in an inner function. A paramref itself is never
|
||||
// moved to the heap, only its original.
|
||||
for(ll=curfn->cvars; ll; ll=ll->next) {
|
||||
if(ll->n->op == OXXX) // see dcl.c:398
|
||||
continue;
|
||||
@@ -221,16 +226,19 @@ esc(Node *n)
|
||||
if(n->op == OFOR || n->op == ORANGE)
|
||||
loopdepth++;
|
||||
|
||||
esc(n->left);
|
||||
esc(n->right);
|
||||
esc(n->ntest);
|
||||
esc(n->nincr);
|
||||
esclist(n->ninit);
|
||||
esclist(n->nbody);
|
||||
esclist(n->nelse);
|
||||
esclist(n->list);
|
||||
esclist(n->rlist);
|
||||
|
||||
if(n->op == OCLOSURE) {
|
||||
escfunc(n);
|
||||
} else {
|
||||
esc(n->left);
|
||||
esc(n->right);
|
||||
esc(n->ntest);
|
||||
esc(n->nincr);
|
||||
esclist(n->ninit);
|
||||
esclist(n->nbody);
|
||||
esclist(n->nelse);
|
||||
esclist(n->list);
|
||||
esclist(n->rlist);
|
||||
}
|
||||
if(n->op == OFOR || n->op == ORANGE)
|
||||
loopdepth--;
|
||||
|
||||
@@ -379,8 +387,8 @@ esc(Node *n)
|
||||
}
|
||||
break;
|
||||
|
||||
case OADDR:
|
||||
case OCLOSURE:
|
||||
case OADDR:
|
||||
case OMAKECHAN:
|
||||
case OMAKEMAP:
|
||||
case OMAKESLICE:
|
||||
@@ -407,8 +415,8 @@ escassign(Node *dst, Node *src)
|
||||
return;
|
||||
|
||||
if(debug['m'] > 1)
|
||||
print("%L:[%d] %S escassign: %hN = %hN\n", lineno, loopdepth,
|
||||
(curfn && curfn->nname) ? curfn->nname->sym : S, dst, src);
|
||||
print("%L:[%d] %S escassign: %hN(%hJ) = %hN(%hJ)\n", lineno, loopdepth,
|
||||
(curfn && curfn->nname) ? curfn->nname->sym : S, dst, dst, src, src);
|
||||
|
||||
setlineno(dst);
|
||||
|
||||
@@ -467,7 +475,11 @@ escassign(Node *dst, Node *src)
|
||||
case OARRAYLIT:
|
||||
case OMAPLIT:
|
||||
case OSTRUCTLIT:
|
||||
// loopdepth was set in the defining statement or function header
|
||||
case OMAKECHAN:
|
||||
case OMAKEMAP:
|
||||
case OMAKESLICE:
|
||||
case ONEW:
|
||||
case OCLOSURE:
|
||||
escflows(dst, src);
|
||||
break;
|
||||
|
||||
@@ -500,18 +512,6 @@ escassign(Node *dst, Node *src)
|
||||
escassign(dst, src->left);
|
||||
break;
|
||||
|
||||
case OMAKECHAN:
|
||||
case OMAKEMAP:
|
||||
case OMAKESLICE:
|
||||
case ONEW:
|
||||
escflows(dst, src);
|
||||
break;
|
||||
|
||||
case OCLOSURE:
|
||||
escflows(dst, src);
|
||||
escfunc(src);
|
||||
break;
|
||||
|
||||
case OADD:
|
||||
case OSUB:
|
||||
case OOR:
|
||||
@@ -543,7 +543,7 @@ escassign(Node *dst, Node *src)
|
||||
// This is a bit messier than fortunate, pulled out of escassign's big
|
||||
// switch for clarity. We either have the paramnodes, which may be
|
||||
// connected to other things throug flows or we have the parameter type
|
||||
// nodes, which may be marked 'n(ofloworescape)'. Navigating the ast is slightly
|
||||
// nodes, which may be marked "noescape". Navigating the ast is slightly
|
||||
// different for methods vs plain functions and for imported vs
|
||||
// this-package
|
||||
static void
|
||||
@@ -711,8 +711,8 @@ escwalk(int level, Node *dst, Node *src)
|
||||
src->walkgen = walkgen;
|
||||
|
||||
if(debug['m']>1)
|
||||
print("escwalk: level:%d depth:%d %.*s %hN scope:%S[%d]\n",
|
||||
level, pdepth, pdepth, "\t\t\t\t\t\t\t\t\t\t", src,
|
||||
print("escwalk: level:%d depth:%d %.*s %hN(%hJ) scope:%S[%d]\n",
|
||||
level, pdepth, pdepth, "\t\t\t\t\t\t\t\t\t\t", src, src,
|
||||
(src->curfn && src->curfn->nname) ? src->curfn->nname->sym : S, src->escloopdepth);
|
||||
|
||||
pdepth++;
|
||||
@@ -726,6 +726,16 @@ escwalk(int level, Node *dst, Node *src)
|
||||
if(debug['m'])
|
||||
warnl(src->lineno, "leaking param: %hN", src);
|
||||
}
|
||||
// handle the missing flow ref <- orig
|
||||
// a paramref is automagically dereferenced, and taking its
|
||||
// address produces the address of the original, so all we have to do here
|
||||
// is keep track of the value flow, so level is unchanged.
|
||||
// alternatively, we could have substituted PPARAMREFs with their ->closure in esc/escassign/flow,
|
||||
if(src->class == PPARAMREF) {
|
||||
if(leaks && debug['m'])
|
||||
warnl(src->lineno, "leaking closure reference %hN", src);
|
||||
escwalk(level, dst, src->closure);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTRLIT:
|
||||
|
||||
@@ -227,15 +227,11 @@ The -u flag instructs get to use the network to update the named packages
|
||||
and their dependencies. By default, get uses the network to check out
|
||||
missing packages but does not use it to look for updates to existing packages.
|
||||
|
||||
When checking out or updating a package, get looks for a branch or
|
||||
tag that matches the locally installed version of Go. If the local
|
||||
version "is release.rNN", it searches for "go.rNN". (For an
|
||||
installation using Go version "weekly.YYYY-MM-DD", it searches for a
|
||||
package version labeled "go.YYYY-MM-DD".) If the desired version
|
||||
cannot be found but others exist with labels in the correct format,
|
||||
get retrieves the most recent version before the desired label.
|
||||
Finally, if all else fails it retrieves the most recent version of
|
||||
the package.
|
||||
When checking out or updating a package, get looks for a branch or tag
|
||||
that matches the locally installed version of Go. The most important
|
||||
rule is that if the local installation is running version "go1", get
|
||||
searches for a branch or tag named "go1". If no such version exists it
|
||||
retrieves the most recent version of the package.
|
||||
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
|
||||
@@ -37,15 +37,11 @@ The -u flag instructs get to use the network to update the named packages
|
||||
and their dependencies. By default, get uses the network to check out
|
||||
missing packages but does not use it to look for updates to existing packages.
|
||||
|
||||
When checking out or updating a package, get looks for a branch or
|
||||
tag that matches the locally installed version of Go. If the local
|
||||
version "is release.rNN", it searches for "go.rNN". (For an
|
||||
installation using Go version "weekly.YYYY-MM-DD", it searches for a
|
||||
package version labeled "go.YYYY-MM-DD".) If the desired version
|
||||
cannot be found but others exist with labels in the correct format,
|
||||
get retrieves the most recent version before the desired label.
|
||||
Finally, if all else fails it retrieves the most recent version of
|
||||
the package.
|
||||
When checking out or updating a package, get looks for a branch or tag
|
||||
that matches the locally installed version of Go. The most important
|
||||
rule is that if the local installation is running version "go1", get
|
||||
searches for a branch or tag named "go1". If no such version exists it
|
||||
retrieves the most recent version of the package.
|
||||
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
@@ -339,56 +335,32 @@ var goTag = regexp.MustCompile(
|
||||
// Version "goX" (or "goX.Y" or "goX.Y.Z") matches tags of the same form.
|
||||
// Version "release.rN" matches tags of the form "go.rN" (N being a floating-point number).
|
||||
// Version "weekly.YYYY-MM-DD" matches tags like "go.weekly.YYYY-MM-DD".
|
||||
//
|
||||
// NOTE(rsc): Eventually we will need to decide on some logic here.
|
||||
// For now, there is only "go1". This matches the docs in go help get.
|
||||
func selectTag(goVersion string, tags []string) (match string) {
|
||||
const rPrefix = "release.r"
|
||||
if strings.HasPrefix(goVersion, rPrefix) {
|
||||
p := "go.r"
|
||||
v, err := strconv.ParseFloat(goVersion[len(rPrefix):], 64)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
var matchf float64
|
||||
for _, t := range tags {
|
||||
if !strings.HasPrefix(t, p) {
|
||||
continue
|
||||
}
|
||||
tf, err := strconv.ParseFloat(t[len(p):], 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if matchf < tf && tf <= v {
|
||||
match, matchf = t, tf
|
||||
}
|
||||
for _, t := range tags {
|
||||
if t == "go1" {
|
||||
return "go1"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
|
||||
const wPrefix = "weekly."
|
||||
if strings.HasPrefix(goVersion, wPrefix) {
|
||||
p := "go.weekly."
|
||||
v := goVersion[len(wPrefix):]
|
||||
for _, t := range tags {
|
||||
if !strings.HasPrefix(t, p) {
|
||||
continue
|
||||
}
|
||||
if match < t && t[len(p):] <= v {
|
||||
match = t
|
||||
/*
|
||||
if goTag.MatchString(goVersion) {
|
||||
v := goVersion
|
||||
for _, t := range tags {
|
||||
if !goTag.MatchString(t) {
|
||||
continue
|
||||
}
|
||||
if cmpGoVersion(match, t) < 0 && cmpGoVersion(t, v) <= 0 {
|
||||
match = t
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if goTag.MatchString(goVersion) {
|
||||
v := goVersion
|
||||
for _, t := range tags {
|
||||
if !goTag.MatchString(t) {
|
||||
continue
|
||||
}
|
||||
if cmpGoVersion(match, t) < 0 && cmpGoVersion(t, v) <= 0 {
|
||||
match = t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return match
|
||||
return match
|
||||
*/
|
||||
}
|
||||
|
||||
// cmpGoVersion returns -1, 0, +1 reporting whether
|
||||
|
||||
@@ -50,41 +50,44 @@ var selectTagTests = []struct {
|
||||
version string
|
||||
selected string
|
||||
}{
|
||||
{"release.r57", ""},
|
||||
{"release.r58.2", "go.r58.1"},
|
||||
{"release.r59", "go.r59"},
|
||||
{"release.r59.1", "go.r59.1"},
|
||||
{"release.r60", "go.r59.1"},
|
||||
{"release.r60.1", "go.r59.1"},
|
||||
{"release.r61", "go.r61"},
|
||||
{"release.r66", "go.r61.1"},
|
||||
{"weekly.2010-01-01", ""},
|
||||
{"weekly.2010-01-02", "go.weekly.2010-01-02"},
|
||||
{"weekly.2010-01-02.1", "go.weekly.2010-01-02"},
|
||||
{"weekly.2010-01-03", "go.weekly.2010-01-02"},
|
||||
{"weekly.2011-10-12", "go.weekly.2011-10-12"},
|
||||
{"weekly.2011-10-12.1", "go.weekly.2011-10-12.1"},
|
||||
{"weekly.2011-10-13", "go.weekly.2011-10-12.1"},
|
||||
{"weekly.2011-10-14", "go.weekly.2011-10-14"},
|
||||
{"weekly.2011-10-14.1", "go.weekly.2011-10-14"},
|
||||
{"weekly.2011-11-01", "go.weekly.2011-11-01"},
|
||||
{"weekly.2014-01-01", "go.weekly.2011-11-01"},
|
||||
{"weekly.3000-01-01", "go.weekly.2011-11-01"},
|
||||
{"go1", "go1"},
|
||||
{"go1.1", "go1.0.1"},
|
||||
{"go1.998", "go1.9.2"},
|
||||
{"go1.1000", "go1.999"},
|
||||
{"go6", "go5"},
|
||||
/*
|
||||
{"release.r57", ""},
|
||||
{"release.r58.2", "go.r58.1"},
|
||||
{"release.r59", "go.r59"},
|
||||
{"release.r59.1", "go.r59.1"},
|
||||
{"release.r60", "go.r59.1"},
|
||||
{"release.r60.1", "go.r59.1"},
|
||||
{"release.r61", "go.r61"},
|
||||
{"release.r66", "go.r61.1"},
|
||||
{"weekly.2010-01-01", ""},
|
||||
{"weekly.2010-01-02", "go.weekly.2010-01-02"},
|
||||
{"weekly.2010-01-02.1", "go.weekly.2010-01-02"},
|
||||
{"weekly.2010-01-03", "go.weekly.2010-01-02"},
|
||||
{"weekly.2011-10-12", "go.weekly.2011-10-12"},
|
||||
{"weekly.2011-10-12.1", "go.weekly.2011-10-12.1"},
|
||||
{"weekly.2011-10-13", "go.weekly.2011-10-12.1"},
|
||||
{"weekly.2011-10-14", "go.weekly.2011-10-14"},
|
||||
{"weekly.2011-10-14.1", "go.weekly.2011-10-14"},
|
||||
{"weekly.2011-11-01", "go.weekly.2011-11-01"},
|
||||
{"weekly.2014-01-01", "go.weekly.2011-11-01"},
|
||||
{"weekly.3000-01-01", "go.weekly.2011-11-01"},
|
||||
{"go1", "go1"},
|
||||
{"go1.1", "go1.0.1"},
|
||||
{"go1.998", "go1.9.2"},
|
||||
{"go1.1000", "go1.999"},
|
||||
{"go6", "go5"},
|
||||
|
||||
// faulty versions:
|
||||
{"release.f00", ""},
|
||||
{"weekly.1999-01-01", ""},
|
||||
{"junk", ""},
|
||||
{"", ""},
|
||||
{"go2x", ""},
|
||||
{"go200000000000", ""},
|
||||
{"go2.", ""},
|
||||
{"go2.0", ""},
|
||||
// faulty versions:
|
||||
{"release.f00", ""},
|
||||
{"weekly.1999-01-01", ""},
|
||||
{"junk", ""},
|
||||
{"", ""},
|
||||
{"go2x", ""},
|
||||
{"go200000000000", ""},
|
||||
{"go2.", ""},
|
||||
{"go2.0", ""},
|
||||
*/
|
||||
{"anything", "go1"},
|
||||
}
|
||||
|
||||
func TestSelectTag(t *testing.T) {
|
||||
|
||||
@@ -422,11 +422,15 @@ func repoRootForImportPathStatic(importPath, scheme string) (*repoRoot, error) {
|
||||
func repoRootForImportDynamic(importPath string) (*repoRoot, error) {
|
||||
slash := strings.Index(importPath, "/")
|
||||
if slash < 0 {
|
||||
return nil, fmt.Errorf("missing / in import %q", importPath)
|
||||
return nil, errors.New("import path doesn't contain a slash")
|
||||
}
|
||||
host := importPath[:slash]
|
||||
if !strings.Contains(host, ".") {
|
||||
return nil, errors.New("import path doesn't contain a hostname")
|
||||
}
|
||||
urlStr, body, err := httpsOrHTTP(importPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("http/https fetch for import %q: %v", importPath, err)
|
||||
return nil, fmt.Errorf("http/https fetch: %v", err)
|
||||
}
|
||||
defer body.Close()
|
||||
metaImport, err := matchGoImport(parseMetaGoImports(body), importPath)
|
||||
|
||||
@@ -8,8 +8,8 @@ godoc on appengine
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
* Go appengine SDK 1.5.5 - 2011-10-11
|
||||
http://code.google.com/appengine/downloads.html#Google_App_Engine_SDK_for_Go
|
||||
* Go appengine SDK
|
||||
https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Go
|
||||
|
||||
* Go sources at tip under $GOROOT
|
||||
|
||||
@@ -23,10 +23,6 @@ Directory structure
|
||||
* $APPDIR contains the following entries (this may change depending on
|
||||
app-engine release and version of godoc):
|
||||
|
||||
alt/
|
||||
encoding/binary/
|
||||
go/*
|
||||
index/suffixarray/
|
||||
app.yaml
|
||||
godoc.zip
|
||||
godoc/
|
||||
@@ -36,31 +32,16 @@ Directory structure
|
||||
For instance:
|
||||
|
||||
application: godoc-app
|
||||
version: 1-5-5
|
||||
version: 1
|
||||
runtime: go
|
||||
api_version: 3
|
||||
api_version: go1
|
||||
|
||||
handlers:
|
||||
- url: /.*
|
||||
script: _go_app
|
||||
|
||||
* The godoc/ directory contains a copy of the files under $GOROOT/src/cmd/godoc
|
||||
with modifications:
|
||||
|
||||
- doc.go is excluded (it belongs to pseudo-package <20>documentation<6F>)
|
||||
- main.go is excluded (appinit.go is taking its place)
|
||||
|
||||
Additional manual modifications are required to refer to the alt/ packages
|
||||
where the app-engine library is not up-to-date with the godoc version.
|
||||
|
||||
* The alt/ directory contains up-to-date copies of Go packages that a tip-based
|
||||
godoc is dependent on but which do not yet exist in the current app-engine SDK.
|
||||
At the time of this writing (10/14/2011) this is the entire go directory tree
|
||||
(for the missing FileSet serialization code in go/token) as well as the
|
||||
index/suffixarray package (for the missing suffix array serialization code).
|
||||
The latest (alt/)index/suffixarray package internally requires the latest
|
||||
version of encoding/binary, which is why it also needs to be present under
|
||||
alt/.
|
||||
with doc.go excluded (it belongs to pseudo-package "documentation")
|
||||
|
||||
|
||||
Configuring and running godoc
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// godoc crypto/block Cipher NewCMAC
|
||||
// - prints doc for Cipher and NewCMAC in package crypto/block
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
@@ -44,8 +44,8 @@ getArgs() {
|
||||
if [ ! -d $GOROOT ]; then
|
||||
error "$GOROOT is not a directory"
|
||||
fi
|
||||
if [ ! -x $GOROOT/src/cmd/godoc/godoc ]; then
|
||||
error "$GOROOT/src/cmd/godoc/godoc does not exist or is not executable"
|
||||
if [ ! -x $GOROOT/bin/godoc ]; then
|
||||
error "$GOROOT/bin/godoc does not exist or is not executable"
|
||||
fi
|
||||
if [ ! -d $APPDIR ]; then
|
||||
error "$APPDIR is not a directory"
|
||||
@@ -72,15 +72,15 @@ cleanup() {
|
||||
|
||||
makeZipfile() {
|
||||
echo "*** make $APPDIR/$ZIPFILE"
|
||||
zip -q -r $APPDIR/$ZIPFILE $GOROOT -i \*.go -i \*.html -i \*.css -i \*.js -i \*.txt -i \*.c -i \*.h -i \*.s -i \*.png -i \*.jpg -i \*.sh -i \*.ico
|
||||
zip -q -r $APPDIR/$ZIPFILE $GOROOT -i \*.go -i \*.html -i \*.xml -i \*.css -i \*.js -i \*.txt -i \*.c -i \*.h -i \*.s -i \*.png -i \*.jpg -i \*.sh -i \*.ico
|
||||
}
|
||||
|
||||
makeIndexfile() {
|
||||
echo "*** make $APPDIR/$INDEXFILE"
|
||||
OUT=/tmp/godoc.out
|
||||
$GOROOT/src/cmd/godoc/godoc -write_index -index_files=$APPDIR/$INDEXFILE -zip=$APPDIR/$ZIPFILE 2> $OUT
|
||||
$GOROOT/bin/godoc -write_index -index_files=$APPDIR/$INDEXFILE -zip=$APPDIR/$ZIPFILE 2> $OUT
|
||||
if [ $? != 0 ]; then
|
||||
error "$GOROOT/src/cmd/godoc/godoc failed - see $OUT for details"
|
||||
error "$GOROOT/bin/godoc failed - see $OUT for details"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Copyright 2012 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
include ../../Make.dist
|
||||
@@ -1,47 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
|
||||
Prof is a rudimentary real-time profiler.
|
||||
|
||||
Given a command to run or the process id (pid) of a command already
|
||||
running, it samples the program's state at regular intervals and reports
|
||||
on its behavior. With no options, it prints a histogram of the locations
|
||||
in the code that were sampled during execution.
|
||||
|
||||
Since it is a real-time profiler, unlike a traditional profiler it samples
|
||||
the program's state even when it is not running, such as when it is
|
||||
asleep or waiting for I/O. Each thread contributes equally to the
|
||||
statistics.
|
||||
|
||||
Usage:
|
||||
go tool prof -p pid [-t total_secs] [-d delta_msec] [6.out args ...]
|
||||
|
||||
The output modes (default -h) are:
|
||||
|
||||
-P file.prof:
|
||||
Write the profile information to file.prof, in the format used by pprof.
|
||||
At the moment, this only works on Linux amd64 binaries and requires that the
|
||||
binary be written using 6l -e to produce ELF debug info.
|
||||
See http://code.google.com/p/google-perftools for details.
|
||||
-h: histograms
|
||||
How many times a sample occurred at each location.
|
||||
-f: dynamic functions
|
||||
At each sample period, print the name of the executing function.
|
||||
-l: dynamic file and line numbers
|
||||
At each sample period, print the file and line number of the executing instruction.
|
||||
-r: dynamic registers
|
||||
At each sample period, print the register contents.
|
||||
-s: dynamic function stack traces
|
||||
At each sample period, print the symbolic stack trace.
|
||||
|
||||
Flag -t sets the maximum real time to sample, in seconds, and -d
|
||||
sets the sampling interval in milliseconds. The default is to sample
|
||||
every 100ms until the program completes.
|
||||
|
||||
It is installed as go tool prof and is architecture-independent.
|
||||
|
||||
*/
|
||||
package documentation
|
||||
@@ -1,899 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <time.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define Ureg Ureg_amd64
|
||||
#include <ureg_amd64.h>
|
||||
#undef Ureg
|
||||
#define Ureg Ureg_x86
|
||||
#include <ureg_x86.h>
|
||||
#undef Ureg
|
||||
#include <mach.h>
|
||||
|
||||
char* file = "6.out";
|
||||
static Fhdr fhdr;
|
||||
int have_syms;
|
||||
int fd;
|
||||
struct Ureg_amd64 ureg_amd64;
|
||||
struct Ureg_x86 ureg_x86;
|
||||
int total_sec = 0;
|
||||
int delta_msec = 100;
|
||||
int nsample;
|
||||
int nsamplethread;
|
||||
|
||||
// pprof data, stored as sequences of N followed by N PC values.
|
||||
// See http://code.google.com/p/google-perftools .
|
||||
uvlong *ppdata; // traces
|
||||
Biobuf* pproffd; // file descriptor to write trace info
|
||||
long ppstart; // start position of current trace
|
||||
long nppdata; // length of data
|
||||
long ppalloc; // size of allocated data
|
||||
char ppmapdata[10*1024]; // the map information for the output file
|
||||
|
||||
// output formats
|
||||
int pprof; // print pprof output to named file
|
||||
int functions; // print functions
|
||||
int histograms; // print histograms
|
||||
int linenums; // print file and line numbers rather than function names
|
||||
int registers; // print registers
|
||||
int stacks; // print stack traces
|
||||
|
||||
int pid; // main process pid
|
||||
|
||||
int nthread; // number of threads
|
||||
int thread[32]; // thread pids
|
||||
Map *map[32]; // thread maps
|
||||
|
||||
void
|
||||
Usage(void)
|
||||
{
|
||||
fprint(2, "Usage: prof -p pid [-t total_secs] [-d delta_msec]\n");
|
||||
fprint(2, " prof [-t total_secs] [-d delta_msec] 6.out args ...\n");
|
||||
fprint(2, "\tformats (default -h):\n");
|
||||
fprint(2, "\t\t-P file.prof: write [c]pprof output to file.prof\n");
|
||||
fprint(2, "\t\t-h: histograms\n");
|
||||
fprint(2, "\t\t-f: dynamic functions\n");
|
||||
fprint(2, "\t\t-l: dynamic file and line numbers\n");
|
||||
fprint(2, "\t\t-r: dynamic registers\n");
|
||||
fprint(2, "\t\t-s: dynamic function stack traces\n");
|
||||
fprint(2, "\t\t-hs: include stack info in histograms\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
typedef struct PC PC;
|
||||
struct PC {
|
||||
uvlong pc;
|
||||
uvlong callerpc;
|
||||
unsigned int count;
|
||||
PC* next;
|
||||
};
|
||||
|
||||
enum {
|
||||
Ncounters = 256
|
||||
};
|
||||
|
||||
PC *counters[Ncounters];
|
||||
|
||||
// Set up by setarch() to make most of the code architecture-independent.
|
||||
typedef struct Arch Arch;
|
||||
struct Arch {
|
||||
char* name;
|
||||
void (*regprint)(void);
|
||||
int (*getregs)(Map*);
|
||||
int (*getPC)(Map*);
|
||||
int (*getSP)(Map*);
|
||||
uvlong (*uregPC)(void);
|
||||
uvlong (*uregSP)(void);
|
||||
void (*ppword)(uvlong w);
|
||||
};
|
||||
|
||||
void
|
||||
amd64_regprint(void)
|
||||
{
|
||||
fprint(2, "ax\t0x%llux\n", ureg_amd64.ax);
|
||||
fprint(2, "bx\t0x%llux\n", ureg_amd64.bx);
|
||||
fprint(2, "cx\t0x%llux\n", ureg_amd64.cx);
|
||||
fprint(2, "dx\t0x%llux\n", ureg_amd64.dx);
|
||||
fprint(2, "si\t0x%llux\n", ureg_amd64.si);
|
||||
fprint(2, "di\t0x%llux\n", ureg_amd64.di);
|
||||
fprint(2, "bp\t0x%llux\n", ureg_amd64.bp);
|
||||
fprint(2, "r8\t0x%llux\n", ureg_amd64.r8);
|
||||
fprint(2, "r9\t0x%llux\n", ureg_amd64.r9);
|
||||
fprint(2, "r10\t0x%llux\n", ureg_amd64.r10);
|
||||
fprint(2, "r11\t0x%llux\n", ureg_amd64.r11);
|
||||
fprint(2, "r12\t0x%llux\n", ureg_amd64.r12);
|
||||
fprint(2, "r13\t0x%llux\n", ureg_amd64.r13);
|
||||
fprint(2, "r14\t0x%llux\n", ureg_amd64.r14);
|
||||
fprint(2, "r15\t0x%llux\n", ureg_amd64.r15);
|
||||
fprint(2, "ds\t0x%llux\n", ureg_amd64.ds);
|
||||
fprint(2, "es\t0x%llux\n", ureg_amd64.es);
|
||||
fprint(2, "fs\t0x%llux\n", ureg_amd64.fs);
|
||||
fprint(2, "gs\t0x%llux\n", ureg_amd64.gs);
|
||||
fprint(2, "type\t0x%llux\n", ureg_amd64.type);
|
||||
fprint(2, "error\t0x%llux\n", ureg_amd64.error);
|
||||
fprint(2, "pc\t0x%llux\n", ureg_amd64.ip);
|
||||
fprint(2, "cs\t0x%llux\n", ureg_amd64.cs);
|
||||
fprint(2, "flags\t0x%llux\n", ureg_amd64.flags);
|
||||
fprint(2, "sp\t0x%llux\n", ureg_amd64.sp);
|
||||
fprint(2, "ss\t0x%llux\n", ureg_amd64.ss);
|
||||
}
|
||||
|
||||
int
|
||||
amd64_getregs(Map *map)
|
||||
{
|
||||
int i;
|
||||
union {
|
||||
uvlong regs[1];
|
||||
struct Ureg_amd64 ureg;
|
||||
} u;
|
||||
|
||||
for(i = 0; i < sizeof ureg_amd64; i+=8) {
|
||||
if(get8(map, (uvlong)i, &u.regs[i/8]) < 0)
|
||||
return -1;
|
||||
}
|
||||
ureg_amd64 = u.ureg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
amd64_getPC(Map *map)
|
||||
{
|
||||
uvlong x;
|
||||
int r;
|
||||
|
||||
r = get8(map, offsetof(struct Ureg_amd64, ip), &x);
|
||||
ureg_amd64.ip = x;
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
amd64_getSP(Map *map)
|
||||
{
|
||||
uvlong x;
|
||||
int r;
|
||||
|
||||
r = get8(map, offsetof(struct Ureg_amd64, sp), &x);
|
||||
ureg_amd64.sp = x;
|
||||
return r;
|
||||
}
|
||||
|
||||
uvlong
|
||||
amd64_uregPC(void)
|
||||
{
|
||||
return ureg_amd64.ip;
|
||||
}
|
||||
|
||||
uvlong
|
||||
amd64_uregSP(void) {
|
||||
return ureg_amd64.sp;
|
||||
}
|
||||
|
||||
void
|
||||
amd64_ppword(uvlong w)
|
||||
{
|
||||
uchar buf[8];
|
||||
|
||||
buf[0] = w;
|
||||
buf[1] = w >> 8;
|
||||
buf[2] = w >> 16;
|
||||
buf[3] = w >> 24;
|
||||
buf[4] = w >> 32;
|
||||
buf[5] = w >> 40;
|
||||
buf[6] = w >> 48;
|
||||
buf[7] = w >> 56;
|
||||
Bwrite(pproffd, buf, 8);
|
||||
}
|
||||
|
||||
void
|
||||
x86_regprint(void)
|
||||
{
|
||||
fprint(2, "ax\t0x%ux\n", ureg_x86.ax);
|
||||
fprint(2, "bx\t0x%ux\n", ureg_x86.bx);
|
||||
fprint(2, "cx\t0x%ux\n", ureg_x86.cx);
|
||||
fprint(2, "dx\t0x%ux\n", ureg_x86.dx);
|
||||
fprint(2, "si\t0x%ux\n", ureg_x86.si);
|
||||
fprint(2, "di\t0x%ux\n", ureg_x86.di);
|
||||
fprint(2, "bp\t0x%ux\n", ureg_x86.bp);
|
||||
fprint(2, "ds\t0x%ux\n", ureg_x86.ds);
|
||||
fprint(2, "es\t0x%ux\n", ureg_x86.es);
|
||||
fprint(2, "fs\t0x%ux\n", ureg_x86.fs);
|
||||
fprint(2, "gs\t0x%ux\n", ureg_x86.gs);
|
||||
fprint(2, "cs\t0x%ux\n", ureg_x86.cs);
|
||||
fprint(2, "flags\t0x%ux\n", ureg_x86.flags);
|
||||
fprint(2, "pc\t0x%ux\n", ureg_x86.pc);
|
||||
fprint(2, "sp\t0x%ux\n", ureg_x86.sp);
|
||||
fprint(2, "ss\t0x%ux\n", ureg_x86.ss);
|
||||
}
|
||||
|
||||
int
|
||||
x86_getregs(Map *map)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof ureg_x86; i+=4) {
|
||||
if(get4(map, (uvlong)i, &((uint32*)&ureg_x86)[i/4]) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
x86_getPC(Map* map)
|
||||
{
|
||||
return get4(map, offsetof(struct Ureg_x86, pc), &ureg_x86.pc);
|
||||
}
|
||||
|
||||
int
|
||||
x86_getSP(Map* map)
|
||||
{
|
||||
return get4(map, offsetof(struct Ureg_x86, sp), &ureg_x86.sp);
|
||||
}
|
||||
|
||||
uvlong
|
||||
x86_uregPC(void)
|
||||
{
|
||||
return (uvlong)ureg_x86.pc;
|
||||
}
|
||||
|
||||
uvlong
|
||||
x86_uregSP(void)
|
||||
{
|
||||
return (uvlong)ureg_x86.sp;
|
||||
}
|
||||
|
||||
void
|
||||
x86_ppword(uvlong w)
|
||||
{
|
||||
uchar buf[4];
|
||||
|
||||
buf[0] = w;
|
||||
buf[1] = w >> 8;
|
||||
buf[2] = w >> 16;
|
||||
buf[3] = w >> 24;
|
||||
Bwrite(pproffd, buf, 4);
|
||||
}
|
||||
|
||||
Arch archtab[] = {
|
||||
{
|
||||
"amd64",
|
||||
amd64_regprint,
|
||||
amd64_getregs,
|
||||
amd64_getPC,
|
||||
amd64_getSP,
|
||||
amd64_uregPC,
|
||||
amd64_uregSP,
|
||||
amd64_ppword,
|
||||
},
|
||||
{
|
||||
"386",
|
||||
x86_regprint,
|
||||
x86_getregs,
|
||||
x86_getPC,
|
||||
x86_getSP,
|
||||
x86_uregPC,
|
||||
x86_uregSP,
|
||||
x86_ppword,
|
||||
},
|
||||
{
|
||||
nil
|
||||
}
|
||||
};
|
||||
|
||||
Arch *arch;
|
||||
|
||||
int
|
||||
setarch(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(mach != nil) {
|
||||
for(i = 0; archtab[i].name != nil; i++) {
|
||||
if (strcmp(mach->name, archtab[i].name) == 0) {
|
||||
arch = &archtab[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
getthreads(void)
|
||||
{
|
||||
int i, j, curn, found;
|
||||
Map *curmap[nelem(map)];
|
||||
int curthread[nelem(map)];
|
||||
static int complained = 0;
|
||||
|
||||
curn = procthreadpids(pid, curthread, nelem(curthread));
|
||||
if(curn <= 0)
|
||||
return curn;
|
||||
|
||||
if(curn > nelem(map)) {
|
||||
if(complained == 0) {
|
||||
fprint(2, "prof: too many threads; limiting to %d\n", nthread, nelem(map));
|
||||
complained = 1;
|
||||
}
|
||||
curn = nelem(map);
|
||||
}
|
||||
if(curn == nthread && memcmp(thread, curthread, curn*sizeof(*thread)) == 0)
|
||||
return curn; // no changes
|
||||
|
||||
// Number of threads has changed (might be the init case).
|
||||
// A bit expensive but rare enough not to bother being clever.
|
||||
for(i = 0; i < curn; i++) {
|
||||
found = 0;
|
||||
for(j = 0; j < nthread; j++) {
|
||||
if(curthread[i] == thread[j]) {
|
||||
found = 1;
|
||||
curmap[i] = map[j];
|
||||
map[j] = nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
continue;
|
||||
|
||||
// map new thread
|
||||
curmap[i] = attachproc(curthread[i], &fhdr);
|
||||
if(curmap[i] == nil) {
|
||||
fprint(2, "prof: can't attach to %d: %r\n", curthread[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for(j = 0; j < nthread; j++)
|
||||
if(map[j] != nil)
|
||||
detachproc(map[j]);
|
||||
|
||||
nthread = curn;
|
||||
memmove(thread, curthread, nthread*sizeof thread[0]);
|
||||
memmove(map, curmap, sizeof map);
|
||||
return nthread;
|
||||
}
|
||||
|
||||
int
|
||||
sample(Map *map)
|
||||
{
|
||||
static int n;
|
||||
|
||||
n++;
|
||||
if(registers) {
|
||||
if(arch->getregs(map) < 0)
|
||||
goto bad;
|
||||
} else {
|
||||
// we need only two registers
|
||||
if(arch->getPC(map) < 0)
|
||||
goto bad;
|
||||
if(arch->getSP(map) < 0)
|
||||
goto bad;
|
||||
}
|
||||
return 1;
|
||||
bad:
|
||||
if(n == 1)
|
||||
fprint(2, "prof: can't read registers: %r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
addtohistogram(uvlong pc, uvlong callerpc, uvlong sp)
|
||||
{
|
||||
int h;
|
||||
PC *x;
|
||||
|
||||
USED(sp);
|
||||
|
||||
h = (pc + callerpc*101) % Ncounters;
|
||||
for(x = counters[h]; x != NULL; x = x->next) {
|
||||
if(x->pc == pc && x->callerpc == callerpc) {
|
||||
x->count++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
x = malloc(sizeof(PC));
|
||||
x->pc = pc;
|
||||
x->callerpc = callerpc;
|
||||
x->count = 1;
|
||||
x->next = counters[h];
|
||||
counters[h] = x;
|
||||
}
|
||||
|
||||
void
|
||||
addppword(uvlong pc)
|
||||
{
|
||||
if(pc == 0) {
|
||||
return;
|
||||
}
|
||||
if(nppdata == ppalloc) {
|
||||
ppalloc = (1000+nppdata)*2;
|
||||
ppdata = realloc(ppdata, ppalloc * sizeof ppdata[0]);
|
||||
if(ppdata == nil) {
|
||||
fprint(2, "prof: realloc failed: %r\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
ppdata[nppdata++] = pc;
|
||||
}
|
||||
|
||||
void
|
||||
startpptrace()
|
||||
{
|
||||
ppstart = nppdata;
|
||||
addppword(~0);
|
||||
}
|
||||
|
||||
void
|
||||
endpptrace()
|
||||
{
|
||||
ppdata[ppstart] = nppdata-ppstart-1;
|
||||
}
|
||||
|
||||
uvlong nextpc;
|
||||
|
||||
void
|
||||
xptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
|
||||
{
|
||||
USED(map);
|
||||
|
||||
char buf[1024];
|
||||
if(sym == nil){
|
||||
fprint(2, "syms\n");
|
||||
return;
|
||||
}
|
||||
if(histograms)
|
||||
addtohistogram(nextpc, pc, sp);
|
||||
if(!histograms || stacks > 1 || pprof) {
|
||||
if(nextpc == 0)
|
||||
nextpc = sym->value;
|
||||
if(stacks){
|
||||
fprint(2, "%s(", sym->name);
|
||||
fprint(2, ")");
|
||||
if(nextpc != sym->value)
|
||||
fprint(2, "+%#llux ", nextpc - sym->value);
|
||||
if(have_syms && linenums && fileline(buf, sizeof buf, pc)) {
|
||||
fprint(2, " %s", buf);
|
||||
}
|
||||
fprint(2, "\n");
|
||||
}
|
||||
if (pprof) {
|
||||
addppword(nextpc);
|
||||
}
|
||||
}
|
||||
nextpc = pc;
|
||||
}
|
||||
|
||||
void
|
||||
stacktracepcsp(Map *map, uvlong pc, uvlong sp)
|
||||
{
|
||||
nextpc = pc;
|
||||
if(pprof){
|
||||
startpptrace();
|
||||
}
|
||||
if(machdata->ctrace==nil)
|
||||
fprint(2, "no machdata->ctrace\n");
|
||||
else if(machdata->ctrace(map, pc, sp, 0, xptrace) <= 0)
|
||||
fprint(2, "no stack frame: pc=%#p sp=%#p\n", pc, sp);
|
||||
else {
|
||||
addtohistogram(nextpc, 0, sp);
|
||||
if(stacks)
|
||||
fprint(2, "\n");
|
||||
}
|
||||
if(pprof){
|
||||
endpptrace();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
printpc(Map *map, uvlong pc, uvlong sp)
|
||||
{
|
||||
char buf[1024];
|
||||
if(registers)
|
||||
arch->regprint();
|
||||
if(have_syms > 0 && linenums && fileline(buf, sizeof buf, pc))
|
||||
fprint(2, "%s\n", buf);
|
||||
if(have_syms > 0 && functions) {
|
||||
symoff(buf, sizeof(buf), pc, CANY);
|
||||
fprint(2, "%s\n", buf);
|
||||
}
|
||||
if(stacks || pprof){
|
||||
stacktracepcsp(map, pc, sp);
|
||||
}
|
||||
else if(histograms){
|
||||
addtohistogram(pc, 0, sp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ppmaps(void)
|
||||
{
|
||||
int fd, n;
|
||||
char tmp[100];
|
||||
Seg *seg;
|
||||
|
||||
// If it's Linux, the info is in /proc/$pid/maps
|
||||
snprint(tmp, sizeof tmp, "/proc/%d/maps", pid);
|
||||
fd = open(tmp, 0);
|
||||
if(fd >= 0) {
|
||||
n = read(fd, ppmapdata, sizeof ppmapdata - 1);
|
||||
close(fd);
|
||||
if(n < 0) {
|
||||
fprint(2, "prof: can't read %s: %r\n", tmp);
|
||||
exit(2);
|
||||
}
|
||||
ppmapdata[n] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// It's probably a mac. Synthesize an entry for the text file.
|
||||
// The register segment may come first but it has a zero offset, so grab the first non-zero offset segment.
|
||||
for(n = 0; n < 3; n++){
|
||||
seg = &map[0]->seg[n];
|
||||
if(seg->b == 0) {
|
||||
continue;
|
||||
}
|
||||
snprint(ppmapdata, sizeof ppmapdata,
|
||||
"%.16x-%.16x r-xp %d 00:00 34968549 %s\n",
|
||||
seg->b, seg->e, seg->f, "/home/r/6.out"
|
||||
);
|
||||
return;
|
||||
}
|
||||
fprint(2, "prof: no text segment in maps for %s\n", file);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
void
|
||||
samples(void)
|
||||
{
|
||||
int i, pid, msec;
|
||||
struct timespec req;
|
||||
int getmaps;
|
||||
|
||||
req.tv_sec = delta_msec/1000;
|
||||
req.tv_nsec = 1000000*(delta_msec % 1000);
|
||||
getmaps = 0;
|
||||
if(pprof)
|
||||
getmaps= 1;
|
||||
for(msec = 0; total_sec <= 0 || msec < 1000*total_sec; msec += delta_msec) {
|
||||
nsample++;
|
||||
nsamplethread += nthread;
|
||||
for(i = 0; i < nthread; i++) {
|
||||
pid = thread[i];
|
||||
if(ctlproc(pid, "stop") < 0)
|
||||
return;
|
||||
if(!sample(map[i])) {
|
||||
ctlproc(pid, "start");
|
||||
return;
|
||||
}
|
||||
printpc(map[i], arch->uregPC(), arch->uregSP());
|
||||
ctlproc(pid, "start");
|
||||
}
|
||||
nanosleep(&req, NULL);
|
||||
getthreads();
|
||||
if(nthread == 0)
|
||||
break;
|
||||
if(getmaps) {
|
||||
getmaps = 0;
|
||||
ppmaps();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct Func Func;
|
||||
struct Func
|
||||
{
|
||||
Func *next;
|
||||
Symbol s;
|
||||
uint onstack;
|
||||
uint leaf;
|
||||
};
|
||||
|
||||
Func *func[257];
|
||||
int nfunc;
|
||||
|
||||
Func*
|
||||
findfunc(uvlong pc)
|
||||
{
|
||||
Func *f;
|
||||
uint h;
|
||||
Symbol s;
|
||||
|
||||
if(pc == 0)
|
||||
return nil;
|
||||
|
||||
if(!findsym(pc, CTEXT, &s))
|
||||
return nil;
|
||||
|
||||
h = s.value % nelem(func);
|
||||
for(f = func[h]; f != NULL; f = f->next)
|
||||
if(f->s.value == s.value)
|
||||
return f;
|
||||
|
||||
f = malloc(sizeof *f);
|
||||
memset(f, 0, sizeof *f);
|
||||
f->s = s;
|
||||
f->next = func[h];
|
||||
func[h] = f;
|
||||
nfunc++;
|
||||
return f;
|
||||
}
|
||||
|
||||
int
|
||||
compareleaf(const void *va, const void *vb)
|
||||
{
|
||||
Func *a, *b;
|
||||
|
||||
a = *(Func**)va;
|
||||
b = *(Func**)vb;
|
||||
if(a->leaf != b->leaf)
|
||||
return b->leaf - a->leaf;
|
||||
if(a->onstack != b->onstack)
|
||||
return b->onstack - a->onstack;
|
||||
return strcmp(a->s.name, b->s.name);
|
||||
}
|
||||
|
||||
void
|
||||
dumphistogram()
|
||||
{
|
||||
int i, h, n;
|
||||
PC *x;
|
||||
Func *f, **ff;
|
||||
|
||||
if(!histograms)
|
||||
return;
|
||||
|
||||
// assign counts to functions.
|
||||
for(h = 0; h < Ncounters; h++) {
|
||||
for(x = counters[h]; x != NULL; x = x->next) {
|
||||
f = findfunc(x->pc);
|
||||
if(f) {
|
||||
f->onstack += x->count;
|
||||
f->leaf += x->count;
|
||||
}
|
||||
f = findfunc(x->callerpc);
|
||||
if(f)
|
||||
f->leaf -= x->count;
|
||||
}
|
||||
}
|
||||
|
||||
// build array
|
||||
ff = malloc(nfunc*sizeof ff[0]);
|
||||
n = 0;
|
||||
for(h = 0; h < nelem(func); h++)
|
||||
for(f = func[h]; f != NULL; f = f->next)
|
||||
ff[n++] = f;
|
||||
|
||||
// sort by leaf counts
|
||||
qsort(ff, nfunc, sizeof ff[0], compareleaf);
|
||||
|
||||
// print.
|
||||
fprint(2, "%d samples (avg %.1g threads)\n", nsample, (double)nsamplethread/nsample);
|
||||
for(i = 0; i < nfunc; i++) {
|
||||
f = ff[i];
|
||||
fprint(2, "%6.2f%%\t", 100.0*(double)f->leaf/nsample);
|
||||
if(stacks)
|
||||
fprint(2, "%6.2f%%\t", 100.0*(double)f->onstack/nsample);
|
||||
fprint(2, "%s\n", f->s.name);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct Trace Trace;
|
||||
struct Trace {
|
||||
int count;
|
||||
int npc;
|
||||
uvlong *pc;
|
||||
Trace *next;
|
||||
};
|
||||
|
||||
void
|
||||
dumppprof()
|
||||
{
|
||||
uvlong i, n, *p, *e;
|
||||
int ntrace;
|
||||
Trace *trace, *tp, *up, *prev;
|
||||
|
||||
if(!pprof)
|
||||
return;
|
||||
e = ppdata + nppdata;
|
||||
// Create list of traces. First, count the traces
|
||||
ntrace = 0;
|
||||
for(p = ppdata; p < e;) {
|
||||
n = *p++;
|
||||
p += n;
|
||||
if(n == 0)
|
||||
continue;
|
||||
ntrace++;
|
||||
}
|
||||
if(ntrace <= 0)
|
||||
return;
|
||||
// Allocate and link the traces together.
|
||||
trace = malloc(ntrace * sizeof(Trace));
|
||||
tp = trace;
|
||||
for(p = ppdata; p < e;) {
|
||||
n = *p++;
|
||||
if(n == 0)
|
||||
continue;
|
||||
tp->count = 1;
|
||||
tp->npc = n;
|
||||
tp->pc = p;
|
||||
tp->next = tp+1;
|
||||
tp++;
|
||||
p += n;
|
||||
}
|
||||
trace[ntrace-1].next = nil;
|
||||
// Eliminate duplicates. Lousy algorithm, although not as bad as it looks because
|
||||
// the list collapses fast.
|
||||
for(tp = trace; tp != nil; tp = tp->next) {
|
||||
prev = tp;
|
||||
for(up = tp->next; up != nil; up = up->next) {
|
||||
if(up->npc == tp->npc && memcmp(up->pc, tp->pc, up->npc*sizeof up->pc[0]) == 0) {
|
||||
tp->count++;
|
||||
prev->next = up->next;
|
||||
} else {
|
||||
prev = up;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Write file.
|
||||
// See http://code.google.com/p/google-perftools/source/browse/trunk/doc/cpuprofile-fileformat.html
|
||||
// 1) Header
|
||||
arch->ppword(0); // must be zero
|
||||
arch->ppword(3); // 3 words follow in header
|
||||
arch->ppword(0); // must be zero
|
||||
arch->ppword(delta_msec * 1000); // sampling period in microseconds
|
||||
arch->ppword(0); // must be zero (padding)
|
||||
// 2) One record for each trace.
|
||||
for(tp = trace; tp != nil; tp = tp->next) {
|
||||
arch->ppword(tp->count);
|
||||
arch->ppword(tp->npc);
|
||||
for(i = 0; i < tp->npc; i++) {
|
||||
arch->ppword(tp->pc[i]);
|
||||
}
|
||||
}
|
||||
// 3) Binary trailer
|
||||
arch->ppword(0); // must be zero
|
||||
arch->ppword(1); // must be one
|
||||
arch->ppword(0); // must be zero
|
||||
// 4) Mapped objects.
|
||||
Bwrite(pproffd, ppmapdata, strlen(ppmapdata));
|
||||
// 5) That's it.
|
||||
Bterm(pproffd);
|
||||
}
|
||||
|
||||
int
|
||||
startprocess(char **argv)
|
||||
{
|
||||
int pid;
|
||||
|
||||
if((pid = fork()) == 0) {
|
||||
pid = getpid();
|
||||
if(ctlproc(pid, "hang") < 0){
|
||||
fprint(2, "prof: child process could not hang\n");
|
||||
exits(0);
|
||||
}
|
||||
execv(argv[0], argv);
|
||||
fprint(2, "prof: could not exec %s: %r\n", argv[0]);
|
||||
exits(0);
|
||||
}
|
||||
|
||||
if(pid == -1) {
|
||||
fprint(2, "prof: could not fork\n");
|
||||
exit(1);
|
||||
}
|
||||
if(ctlproc(pid, "attached") < 0 || ctlproc(pid, "waitstop") < 0) {
|
||||
fprint(2, "prof: could not attach to child process: %r\n");
|
||||
exit(1);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
void
|
||||
detach(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < nthread; i++)
|
||||
detachproc(map[i]);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
char *ppfile;
|
||||
|
||||
ARGBEGIN{
|
||||
case 'P':
|
||||
pprof =1;
|
||||
ppfile = EARGF(Usage());
|
||||
pproffd = Bopen(ppfile, OWRITE);
|
||||
if(pproffd == nil) {
|
||||
fprint(2, "prof: cannot open %s: %r\n", ppfile);
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
delta_msec = atoi(EARGF(Usage()));
|
||||
break;
|
||||
case 't':
|
||||
total_sec = atoi(EARGF(Usage()));
|
||||
break;
|
||||
case 'p':
|
||||
pid = atoi(EARGF(Usage()));
|
||||
break;
|
||||
case 'f':
|
||||
functions = 1;
|
||||
break;
|
||||
case 'h':
|
||||
histograms = 1;
|
||||
break;
|
||||
case 'l':
|
||||
linenums = 1;
|
||||
break;
|
||||
case 'r':
|
||||
registers = 1;
|
||||
break;
|
||||
case 's':
|
||||
stacks++;
|
||||
break;
|
||||
default:
|
||||
Usage();
|
||||
}ARGEND
|
||||
if(pid <= 0 && argc == 0)
|
||||
Usage();
|
||||
if(functions+linenums+registers+stacks+pprof == 0)
|
||||
histograms = 1;
|
||||
if(!machbyname("amd64")) {
|
||||
fprint(2, "prof: no amd64 support\n", pid);
|
||||
exit(1);
|
||||
}
|
||||
if(argc > 0)
|
||||
file = argv[0];
|
||||
else if(pid) {
|
||||
file = proctextfile(pid);
|
||||
if (file == NULL) {
|
||||
fprint(2, "prof: can't find file for pid %d: %r\n", pid);
|
||||
fprint(2, "prof: on Darwin, need to provide file name explicitly\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fd = open(file, 0);
|
||||
if(fd < 0) {
|
||||
fprint(2, "prof: can't open %s: %r\n", file);
|
||||
exit(1);
|
||||
}
|
||||
if(crackhdr(fd, &fhdr)) {
|
||||
have_syms = syminit(fd, &fhdr);
|
||||
if(!have_syms) {
|
||||
fprint(2, "prof: no symbols for %s: %r\n", file);
|
||||
}
|
||||
} else {
|
||||
fprint(2, "prof: crack header for %s: %r\n", file);
|
||||
exit(1);
|
||||
}
|
||||
if(pid <= 0)
|
||||
pid = startprocess(argv);
|
||||
attachproc(pid, &fhdr); // initializes thread list
|
||||
if(setarch() < 0) {
|
||||
detach();
|
||||
fprint(2, "prof: can't identify binary architecture for pid %d\n", pid);
|
||||
exit(1);
|
||||
}
|
||||
if(getthreads() <= 0) {
|
||||
detach();
|
||||
fprint(2, "prof: can't find threads for pid %d\n", pid);
|
||||
exit(1);
|
||||
}
|
||||
for(i = 0; i < nthread; i++)
|
||||
ctlproc(thread[i], "start");
|
||||
samples();
|
||||
detach();
|
||||
dumphistogram();
|
||||
dumppprof();
|
||||
exit(0);
|
||||
}
|
||||
@@ -23,8 +23,8 @@ type keyAgreement interface {
|
||||
// In the case that the key agreement protocol doesn't use a
|
||||
// ServerKeyExchange message, generateServerKeyExchange can return nil,
|
||||
// nil.
|
||||
generateServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
|
||||
processClientKeyExchange(*Config, *clientKeyExchangeMsg, uint16) ([]byte, error)
|
||||
generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
|
||||
processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
|
||||
|
||||
// On the client side, the next two methods are called in order.
|
||||
|
||||
|
||||
@@ -112,37 +112,38 @@ FindCipherSuite:
|
||||
hello.nextProtoNeg = true
|
||||
hello.nextProtos = config.NextProtos
|
||||
}
|
||||
if clientHello.ocspStapling && len(config.Certificates[0].OCSPStaple) > 0 {
|
||||
|
||||
if len(config.Certificates) == 0 {
|
||||
return c.sendAlert(alertInternalError)
|
||||
}
|
||||
cert := &config.Certificates[0]
|
||||
if len(clientHello.serverName) > 0 {
|
||||
c.serverName = clientHello.serverName
|
||||
cert = config.getCertificateForName(clientHello.serverName)
|
||||
}
|
||||
|
||||
if clientHello.ocspStapling && len(cert.OCSPStaple) > 0 {
|
||||
hello.ocspStapling = true
|
||||
}
|
||||
|
||||
finishedHash.Write(hello.marshal())
|
||||
c.writeRecord(recordTypeHandshake, hello.marshal())
|
||||
|
||||
if len(config.Certificates) == 0 {
|
||||
return c.sendAlert(alertInternalError)
|
||||
}
|
||||
|
||||
certMsg := new(certificateMsg)
|
||||
if len(clientHello.serverName) > 0 {
|
||||
c.serverName = clientHello.serverName
|
||||
certMsg.certificates = config.getCertificateForName(clientHello.serverName).Certificate
|
||||
} else {
|
||||
certMsg.certificates = config.Certificates[0].Certificate
|
||||
}
|
||||
certMsg.certificates = cert.Certificate
|
||||
finishedHash.Write(certMsg.marshal())
|
||||
c.writeRecord(recordTypeHandshake, certMsg.marshal())
|
||||
|
||||
if hello.ocspStapling {
|
||||
certStatus := new(certificateStatusMsg)
|
||||
certStatus.statusType = statusTypeOCSP
|
||||
certStatus.response = config.Certificates[0].OCSPStaple
|
||||
certStatus.response = cert.OCSPStaple
|
||||
finishedHash.Write(certStatus.marshal())
|
||||
c.writeRecord(recordTypeHandshake, certStatus.marshal())
|
||||
}
|
||||
|
||||
keyAgreement := suite.ka()
|
||||
skx, err := keyAgreement.generateServerKeyExchange(config, clientHello, hello)
|
||||
skx, err := keyAgreement.generateServerKeyExchange(config, cert, clientHello, hello)
|
||||
if err != nil {
|
||||
c.sendAlert(alertHandshakeFailure)
|
||||
return err
|
||||
@@ -288,7 +289,7 @@ FindCipherSuite:
|
||||
finishedHash.Write(certVerify.marshal())
|
||||
}
|
||||
|
||||
preMasterSecret, err := keyAgreement.processClientKeyExchange(config, ckx, c.vers)
|
||||
preMasterSecret, err := keyAgreement.processClientKeyExchange(config, cert, ckx, c.vers)
|
||||
if err != nil {
|
||||
c.sendAlert(alertHandshakeFailure)
|
||||
return err
|
||||
|
||||
@@ -37,9 +37,12 @@ func init() {
|
||||
testConfig = new(Config)
|
||||
testConfig.Time = func() time.Time { return time.Unix(0, 0) }
|
||||
testConfig.Rand = zeroSource{}
|
||||
testConfig.Certificates = make([]Certificate, 1)
|
||||
testConfig.Certificates = make([]Certificate, 2)
|
||||
testConfig.Certificates[0].Certificate = [][]byte{testCertificate}
|
||||
testConfig.Certificates[0].PrivateKey = testPrivateKey
|
||||
testConfig.Certificates[1].Certificate = [][]byte{testSNICertificate}
|
||||
testConfig.Certificates[1].PrivateKey = testPrivateKey
|
||||
testConfig.BuildNameToCertificate()
|
||||
testConfig.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
|
||||
testConfig.InsecureSkipVerify = true
|
||||
}
|
||||
@@ -176,6 +179,13 @@ func TestHandshakeServerSSLv3(t *testing.T) {
|
||||
testServerScript(t, "SSLv3", sslv3ServerScript, testConfig, nil)
|
||||
}
|
||||
|
||||
// TestHandshakeServerSNI involves a client sending an SNI extension of
|
||||
// "snitest.com", which happens to match the CN of testSNICertificate. The test
|
||||
// verifies that the server correctly selects that certificate.
|
||||
func TestHandshakeServerSNI(t *testing.T) {
|
||||
testServerScript(t, "SNI", selectCertificateBySNIScript, testConfig, nil)
|
||||
}
|
||||
|
||||
type clientauthTest struct {
|
||||
name string
|
||||
clientauth ClientAuthType
|
||||
@@ -258,6 +268,8 @@ func fromHex(s string) []byte {
|
||||
|
||||
var testCertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101050003818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a381a73081a4301d0603551d0e04160414b1ade2855acfcb28db69ce2369ded3268e18883930750603551d23046e306c8014b1ade2855acfcb28db69ce2369ded3268e188839a149a4473045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746482090085b0bba48a7fb8ca300c0603551d13040530030101ff300d06092a864886f70d010105050003818100086c4524c76bb159ab0c52ccf2b014d7879d7a6475b55a9566e4c52b8eae12661feb4f38b36e60d392fdf74108b52513b1187a24fb301dbaed98b917ece7d73159db95d31d78ea50565cd5825a2d5a5f33c4b6d8c97590968c0f5298b5cd981f89205ff2a01ca31b9694dda9fd57e970e8266d71999b266e3850296c90a7bdd9")
|
||||
|
||||
var testSNICertificate = fromHex("308201f23082015da003020102020100300b06092a864886f70d01010530283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d301e170d3132303431313137343033355a170d3133303431313137343533355a30283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d30819d300b06092a864886f70d01010103818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a3323030300e0603551d0f0101ff0404030200a0300d0603551d0e0406040401020304300f0603551d2304083006800401020304300b06092a864886f70d0101050381810089c6455f1c1f5ef8eb1ab174ee2439059f5c4259bb1a8d86cdb1d056f56a717da40e95ab90f59e8deaf627c157995094db0802266eb34fc6842dea8a4b68d9c1389103ab84fb9e1f85d9b5d23ff2312c8670fbb540148245a4ebafe264d90c8a4cf4f85b0fac12ac2fc4a3154bad52462868af96c62c6525d652b6e31845bdcc")
|
||||
|
||||
var testPrivateKey = &rsa.PrivateKey{
|
||||
PublicKey: rsa.PublicKey{
|
||||
N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"),
|
||||
@@ -947,6 +959,142 @@ var sslv3ServerScript = [][]byte{
|
||||
},
|
||||
}
|
||||
|
||||
var selectCertificateBySNIScript = [][]byte{
|
||||
{
|
||||
0x16, 0x03, 0x01, 0x00, 0x6e, 0x01, 0x00, 0x00,
|
||||
0x6a, 0x03, 0x01, 0x4f, 0x85, 0xc4, 0xc2, 0xb9,
|
||||
0x39, 0x80, 0x91, 0x66, 0x65, 0x56, 0x8e, 0xdd,
|
||||
0x48, 0xe9, 0xca, 0x34, 0x02, 0x3c, 0xaf, 0x0d,
|
||||
0x73, 0xb5, 0x2a, 0x05, 0x6e, 0xbd, 0x5e, 0x8f,
|
||||
0x38, 0xf9, 0xe5, 0x00, 0x00, 0x28, 0x00, 0x39,
|
||||
0x00, 0x38, 0x00, 0x35, 0x00, 0x16, 0x00, 0x13,
|
||||
0x00, 0x0a, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2f,
|
||||
0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12,
|
||||
0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08,
|
||||
0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01,
|
||||
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0x0e, 0x00, 0x00, 0x0b, 0x73, 0x6e, 0x69, 0x74,
|
||||
0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x00,
|
||||
0x23, 0x00, 0x00,
|
||||
},
|
||||
{
|
||||
0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
|
||||
0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16,
|
||||
0x03, 0x01, 0x02, 0x00, 0x0b, 0x00, 0x01, 0xfc,
|
||||
0x00, 0x01, 0xf9, 0x00, 0x01, 0xf6, 0x30, 0x82,
|
||||
0x01, 0xf2, 0x30, 0x82, 0x01, 0x5d, 0xa0, 0x03,
|
||||
0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30, 0x0b,
|
||||
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
||||
0x01, 0x01, 0x05, 0x30, 0x28, 0x31, 0x10, 0x30,
|
||||
0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07,
|
||||
0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f, 0x31,
|
||||
0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03,
|
||||
0x13, 0x0b, 0x73, 0x6e, 0x69, 0x74, 0x65, 0x73,
|
||||
0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17,
|
||||
0x0d, 0x31, 0x32, 0x30, 0x34, 0x31, 0x31, 0x31,
|
||||
0x37, 0x34, 0x30, 0x33, 0x35, 0x5a, 0x17, 0x0d,
|
||||
0x31, 0x33, 0x30, 0x34, 0x31, 0x31, 0x31, 0x37,
|
||||
0x34, 0x35, 0x33, 0x35, 0x5a, 0x30, 0x28, 0x31,
|
||||
0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43,
|
||||
0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x13, 0x0b, 0x73, 0x6e, 0x69, 0x74,
|
||||
0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30,
|
||||
0x81, 0x9d, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86,
|
||||
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x03,
|
||||
0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81,
|
||||
0x81, 0x00, 0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5,
|
||||
0xe5, 0xbf, 0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe,
|
||||
0xe6, 0x2b, 0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d,
|
||||
0x8a, 0x7a, 0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7,
|
||||
0xa5, 0x65, 0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c,
|
||||
0xb5, 0xb4, 0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b,
|
||||
0x7e, 0x62, 0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe,
|
||||
0x12, 0x5c, 0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf,
|
||||
0xfa, 0x58, 0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04,
|
||||
0xd3, 0xd0, 0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4,
|
||||
0x54, 0x9f, 0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00,
|
||||
0xfe, 0x18, 0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d,
|
||||
0x7d, 0xf1, 0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb,
|
||||
0x51, 0xc9, 0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32,
|
||||
0x66, 0x01, 0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71,
|
||||
0x9a, 0x1d, 0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda,
|
||||
0x2d, 0x79, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
|
||||
0x32, 0x30, 0x30, 0x30, 0x0e, 0x06, 0x03, 0x55,
|
||||
0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03,
|
||||
0x02, 0x00, 0xa0, 0x30, 0x0d, 0x06, 0x03, 0x55,
|
||||
0x1d, 0x0e, 0x04, 0x06, 0x04, 0x04, 0x01, 0x02,
|
||||
0x03, 0x04, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d,
|
||||
0x23, 0x04, 0x08, 0x30, 0x06, 0x80, 0x04, 0x01,
|
||||
0x02, 0x03, 0x04, 0x30, 0x0b, 0x06, 0x09, 0x2a,
|
||||
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
|
||||
0x03, 0x81, 0x81, 0x00, 0x89, 0xc6, 0x45, 0x5f,
|
||||
0x1c, 0x1f, 0x5e, 0xf8, 0xeb, 0x1a, 0xb1, 0x74,
|
||||
0xee, 0x24, 0x39, 0x05, 0x9f, 0x5c, 0x42, 0x59,
|
||||
0xbb, 0x1a, 0x8d, 0x86, 0xcd, 0xb1, 0xd0, 0x56,
|
||||
0xf5, 0x6a, 0x71, 0x7d, 0xa4, 0x0e, 0x95, 0xab,
|
||||
0x90, 0xf5, 0x9e, 0x8d, 0xea, 0xf6, 0x27, 0xc1,
|
||||
0x57, 0x99, 0x50, 0x94, 0xdb, 0x08, 0x02, 0x26,
|
||||
0x6e, 0xb3, 0x4f, 0xc6, 0x84, 0x2d, 0xea, 0x8a,
|
||||
0x4b, 0x68, 0xd9, 0xc1, 0x38, 0x91, 0x03, 0xab,
|
||||
0x84, 0xfb, 0x9e, 0x1f, 0x85, 0xd9, 0xb5, 0xd2,
|
||||
0x3f, 0xf2, 0x31, 0x2c, 0x86, 0x70, 0xfb, 0xb5,
|
||||
0x40, 0x14, 0x82, 0x45, 0xa4, 0xeb, 0xaf, 0xe2,
|
||||
0x64, 0xd9, 0x0c, 0x8a, 0x4c, 0xf4, 0xf8, 0x5b,
|
||||
0x0f, 0xac, 0x12, 0xac, 0x2f, 0xc4, 0xa3, 0x15,
|
||||
0x4b, 0xad, 0x52, 0x46, 0x28, 0x68, 0xaf, 0x96,
|
||||
0xc6, 0x2c, 0x65, 0x25, 0xd6, 0x52, 0xb6, 0xe3,
|
||||
0x18, 0x45, 0xbd, 0xcc, 0x16, 0x03, 0x01, 0x00,
|
||||
0x04, 0x0e, 0x00, 0x00, 0x00,
|
||||
},
|
||||
{
|
||||
0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
|
||||
0x82, 0x00, 0x80, 0x70, 0x1d, 0x34, 0x75, 0xa2,
|
||||
0xe7, 0xe3, 0x2f, 0x3d, 0xc1, 0x1d, 0xca, 0x0b,
|
||||
0xe3, 0x64, 0xb9, 0x1a, 0x00, 0x69, 0xc4, 0x14,
|
||||
0x05, 0x07, 0x7e, 0xc3, 0x51, 0x43, 0x52, 0x66,
|
||||
0xe3, 0xbd, 0xff, 0x1b, 0x1a, 0x6a, 0x84, 0xf2,
|
||||
0x07, 0x24, 0xd7, 0x12, 0xa8, 0x58, 0xcf, 0x8a,
|
||||
0x50, 0x30, 0xe8, 0xc8, 0xb2, 0xf9, 0x58, 0x1c,
|
||||
0x56, 0x53, 0x76, 0x21, 0xe0, 0x03, 0x7f, 0x77,
|
||||
0xa7, 0xf1, 0xad, 0x67, 0xd4, 0xe2, 0x8f, 0xa0,
|
||||
0x58, 0x6c, 0xe0, 0x28, 0x59, 0xf3, 0xd1, 0x53,
|
||||
0x2b, 0x21, 0xbd, 0xa3, 0x84, 0x31, 0x73, 0xbf,
|
||||
0x84, 0x0f, 0x83, 0xf4, 0xc4, 0xd0, 0xe5, 0x3c,
|
||||
0x2d, 0x3e, 0xf2, 0x8a, 0x1e, 0xe7, 0xe9, 0x1f,
|
||||
0x12, 0x13, 0xad, 0x29, 0xd6, 0x0c, 0xc7, 0xc6,
|
||||
0x05, 0x53, 0x7d, 0x5e, 0xc6, 0x92, 0x72, 0xba,
|
||||
0xd2, 0x93, 0x8f, 0x53, 0x84, 0x87, 0x44, 0x05,
|
||||
0x9f, 0x5d, 0x66, 0x14, 0x03, 0x01, 0x00, 0x01,
|
||||
0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xfc, 0x71,
|
||||
0xaa, 0xa8, 0x37, 0xa8, 0xbd, 0x63, 0xb7, 0xbc,
|
||||
0x95, 0xef, 0x0c, 0xcf, 0x39, 0x31, 0x93, 0xe6,
|
||||
0x86, 0xbd, 0x3f, 0x56, 0x9d, 0xf0, 0xb2, 0xb5,
|
||||
0xd1, 0xa7, 0xc6, 0x45, 0x89, 0x18, 0xfb, 0xa0,
|
||||
0x7f, 0xc1,
|
||||
},
|
||||
{
|
||||
0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
|
||||
0x01, 0x00, 0x24, 0xb8, 0x6d, 0x9a, 0x90, 0x3c,
|
||||
0x45, 0xe0, 0xff, 0x63, 0xba, 0xab, 0x3d, 0x7a,
|
||||
0xa6, 0x49, 0x5a, 0x13, 0xdc, 0x0e, 0xa3, 0xba,
|
||||
0x7f, 0x04, 0x19, 0x45, 0xfd, 0xfb, 0xbd, 0x00,
|
||||
0xa3, 0xa7, 0x78, 0x81, 0x38, 0x9f, 0x10, 0x17,
|
||||
0x03, 0x01, 0x00, 0x21, 0x43, 0xc3, 0x91, 0xb7,
|
||||
0xbf, 0x50, 0x0b, 0x04, 0xb4, 0x5d, 0xc6, 0x20,
|
||||
0x64, 0xb8, 0x01, 0x09, 0x25, 0x2c, 0x03, 0x30,
|
||||
0xc0, 0x77, 0xc9, 0x5e, 0xe6, 0xe0, 0x99, 0xdc,
|
||||
0xcd, 0x75, 0x9d, 0x51, 0x82, 0x15, 0x03, 0x01,
|
||||
0x00, 0x16, 0x2d, 0x7a, 0x89, 0x7b, 0x36, 0x85,
|
||||
0x2a, 0x93, 0xcb, 0x83, 0xa7, 0x2f, 0x9e, 0x91,
|
||||
0xfc, 0xad, 0x57, 0xca, 0xf5, 0xbc, 0x13, 0x2f,
|
||||
},
|
||||
}
|
||||
|
||||
var clientauthTests = []clientauthTest{
|
||||
// Server doesn't asks for cert
|
||||
// go test -run "TestRunServer" -serve -clientauth 0
|
||||
@@ -1285,7 +1433,7 @@ var clientauthTests = []clientauthTest{
|
||||
// go test -run "TestRunServer" -serve -clientauth 1
|
||||
// gnutls-cli --insecure --debug 100 -p 10443 localhost
|
||||
{"RequestClientCert, client gives it", RequestClientCert,
|
||||
[]*x509.Certificate{clicert},
|
||||
[]*x509.Certificate{clientCertificate},
|
||||
[][]byte{{
|
||||
0x16, 0x03, 0x02, 0x00, 0x7a, 0x01, 0x00, 0x00,
|
||||
0x76, 0x03, 0x02, 0x4e, 0xe7, 0x44, 0xda, 0x58,
|
||||
@@ -1528,14 +1676,16 @@ var clientauthTests = []clientauthTest{
|
||||
0x00, 0x16, 0x53, 0xf5, 0xff, 0xe0, 0xa1, 0x6c,
|
||||
0x33, 0xf4, 0x4e, 0x89, 0x68, 0xe1, 0xf7, 0x61,
|
||||
0x13, 0xb3, 0x12, 0xa1, 0x8e, 0x5a, 0x7a, 0x02,
|
||||
}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// cert.pem and key.pem were generated with generate_cert.go
|
||||
// Thus, they have no ExtKeyUsage fields and trigger an error
|
||||
// when verification is turned on.
|
||||
|
||||
var clicert = loadPEMCert(`
|
||||
var clientCertificate = loadPEMCert(`
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD
|
||||
bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4
|
||||
|
||||
@@ -20,11 +20,11 @@ import (
|
||||
// encrypts the pre-master secret to the server's public key.
|
||||
type rsaKeyAgreement struct{}
|
||||
|
||||
func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
||||
func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
|
||||
func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
|
||||
preMasterSecret := make([]byte, 48)
|
||||
_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
|
||||
if err != nil {
|
||||
@@ -44,7 +44,7 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, ckx *clientKe
|
||||
ciphertext = ckx.ciphertext[2:]
|
||||
}
|
||||
|
||||
err = rsa.DecryptPKCS1v15SessionKey(config.rand(), config.Certificates[0].PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
|
||||
err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,7 +109,7 @@ type ecdheRSAKeyAgreement struct {
|
||||
x, y *big.Int
|
||||
}
|
||||
|
||||
func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
||||
func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
||||
var curveid uint16
|
||||
|
||||
Curve:
|
||||
@@ -151,7 +151,7 @@ Curve:
|
||||
copy(serverECDHParams[4:], ecdhePublic)
|
||||
|
||||
md5sha1 := md5SHA1Hash(clientHello.random, hello.random, serverECDHParams)
|
||||
sig, err := rsa.SignPKCS1v15(config.rand(), config.Certificates[0].PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, md5sha1)
|
||||
sig, err := rsa.SignPKCS1v15(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, md5sha1)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
|
||||
}
|
||||
@@ -167,7 +167,7 @@ Curve:
|
||||
return skx, nil
|
||||
}
|
||||
|
||||
func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
|
||||
func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
|
||||
if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
|
||||
return nil, errors.New("bad ClientKeyExchange")
|
||||
}
|
||||
|
||||
@@ -327,6 +327,9 @@ func (db *DB) prepare(query string) (stmt *Stmt, err error) {
|
||||
// Exec executes a query without returning any rows.
|
||||
func (db *DB) Exec(query string, args ...interface{}) (Result, error) {
|
||||
sargs, err := subsetTypeArgs(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res Result
|
||||
for i := 0; i < 10; i++ {
|
||||
res, err = db.exec(query, sargs)
|
||||
|
||||
@@ -57,6 +57,7 @@ func Encode(dst, src []byte) int {
|
||||
if v == 0 && len(src) >= 4 {
|
||||
dst[0] = 'z'
|
||||
dst = dst[1:]
|
||||
src = src[4:]
|
||||
n++
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -28,6 +28,11 @@ var pairs = []testpair{
|
||||
"l(DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G\n" +
|
||||
">uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c\n",
|
||||
},
|
||||
// Special case when shortening !!!!! to z.
|
||||
{
|
||||
"\000\000\000\000",
|
||||
"z",
|
||||
},
|
||||
}
|
||||
|
||||
var bigtest = pairs[len(pairs)-1]
|
||||
|
||||
@@ -377,11 +377,6 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
|
||||
} else {
|
||||
// Bottom 7 bits give the number of length bytes to follow.
|
||||
numBytes := int(b & 0x7f)
|
||||
// We risk overflowing a signed 32-bit number if we accept more than 3 bytes.
|
||||
if numBytes > 3 {
|
||||
err = StructuralError{"length too large"}
|
||||
return
|
||||
}
|
||||
if numBytes == 0 {
|
||||
err = SyntaxError{"indefinite length found (not DER)"}
|
||||
return
|
||||
@@ -394,8 +389,19 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
|
||||
}
|
||||
b = bytes[offset]
|
||||
offset++
|
||||
if ret.length >= 1<<23 {
|
||||
// We can't shift ret.length up without
|
||||
// overflowing.
|
||||
err = StructuralError{"length too large"}
|
||||
return
|
||||
}
|
||||
ret.length <<= 8
|
||||
ret.length |= int(b)
|
||||
if ret.length == 0 {
|
||||
// DER requires that lengths be minimal.
|
||||
err = StructuralError{"superfluous leading zeros in length"}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -283,6 +283,12 @@ var tagAndLengthData = []tagAndLengthTest{
|
||||
{[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}},
|
||||
{[]byte{0x1f, 0x85}, false, tagAndLength{}},
|
||||
{[]byte{0x30, 0x80}, false, tagAndLength{}},
|
||||
// Superfluous zeros in the length should be an error.
|
||||
{[]byte{0xa0, 0x82, 0x00, 0x01}, false, tagAndLength{}},
|
||||
// Lengths up to the maximum size of an int should work.
|
||||
{[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}},
|
||||
// Lengths that would overflow an int should be rejected.
|
||||
{[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}},
|
||||
}
|
||||
|
||||
func TestParseTagAndLength(t *testing.T) {
|
||||
|
||||
@@ -230,7 +230,12 @@ func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
|
||||
if in == '=' && j >= 2 && len(src) < 4 {
|
||||
// We've reached the end and there's
|
||||
// padding
|
||||
if len(src) == 0 && j == 2 {
|
||||
// not enough padding
|
||||
return n, false, CorruptInputError(len(osrc))
|
||||
}
|
||||
if len(src) > 0 && src[0] != '=' {
|
||||
// incorrect padding
|
||||
return n, false, CorruptInputError(len(osrc) - len(src) - 1)
|
||||
}
|
||||
dlen = j
|
||||
|
||||
@@ -151,6 +151,9 @@ func TestDecodeCorrupt(t *testing.T) {
|
||||
{"AAA=AAAA", 3},
|
||||
{"AAAAA", 4},
|
||||
{"AAAAAA", 4},
|
||||
{"A=", 1},
|
||||
{"AA=", 3},
|
||||
{"AAAAAA=", 7},
|
||||
}
|
||||
|
||||
for _, e := range examples {
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
@@ -415,9 +416,11 @@ func isValidTag(s string) bool {
|
||||
return false
|
||||
}
|
||||
for _, c := range s {
|
||||
switch c {
|
||||
case '$', '-', '_', '/', '%':
|
||||
// Acceptable
|
||||
switch {
|
||||
case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~", c):
|
||||
// Backslash and quote chars are reserved, but
|
||||
// otherwise any punctuation chars are allowed
|
||||
// in a tag name.
|
||||
default:
|
||||
if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
|
||||
return false
|
||||
|
||||
@@ -40,6 +40,10 @@ type percentSlashTag struct {
|
||||
V string `json:"text/html%"` // http://golang.org/issue/2718
|
||||
}
|
||||
|
||||
type punctuationTag struct {
|
||||
V string `json:"!#$%&()*+-./:<=>?@[]^_{|}~"` // http://golang.org/issue/3546
|
||||
}
|
||||
|
||||
type emptyTag struct {
|
||||
W string
|
||||
}
|
||||
@@ -73,6 +77,7 @@ var structTagObjectKeyTests = []struct {
|
||||
{badFormatTag{"Orfevre"}, "Orfevre", "Y"},
|
||||
{badCodeTag{"Reliable Man"}, "Reliable Man", "Z"},
|
||||
{percentSlashTag{"brut"}, "brut", "text/html%"},
|
||||
{punctuationTag{"Union Rags"}, "Union Rags", "!#$%&()*+-./:<=>?@[]^_{|}~"},
|
||||
}
|
||||
|
||||
func TestStructTagObjectKey(t *testing.T) {
|
||||
|
||||
@@ -28,9 +28,10 @@ type Block struct {
|
||||
}
|
||||
|
||||
// getLine results the first \r\n or \n delineated line from the given byte
|
||||
// array. The line does not include the \r\n or \n. The remainder of the byte
|
||||
// array (also not including the new line bytes) is also returned and this will
|
||||
// always be smaller than the original argument.
|
||||
// array. The line does not include trailing whitespace or the trailing new
|
||||
// line bytes. The remainder of the byte array (also not including the new line
|
||||
// bytes) is also returned and this will always be smaller than the original
|
||||
// argument.
|
||||
func getLine(data []byte) (line, rest []byte) {
|
||||
i := bytes.Index(data, []byte{'\n'})
|
||||
var j int
|
||||
@@ -43,7 +44,7 @@ func getLine(data []byte) (line, rest []byte) {
|
||||
i--
|
||||
}
|
||||
}
|
||||
return data[0:i], data[j:]
|
||||
return bytes.TrimRight(data[0:i], " \t"), data[j:]
|
||||
}
|
||||
|
||||
// removeWhitespace returns a copy of its input with all spaces, tab and
|
||||
|
||||
@@ -127,13 +127,13 @@ Certificate chain
|
||||
-----BEGIN CERTIFICATE-----
|
||||
testing
|
||||
-----BEGIN CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID6TCCA1ICAQEwDQYJKoZIhvcNAQEFBQAwgYsxCzAJBgNVBAYTAlVTMRMwEQYD
|
||||
VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQK
|
||||
EwtHb29nbGUgSW5jLjEMMAoGA1UECxMDRW5nMQwwCgYDVQQDEwNhZ2wxHTAbBgkq
|
||||
hkiG9w0BCQEWDmFnbEBnb29nbGUuY29tMB4XDTA5MDkwOTIyMDU0M1oXDTEwMDkw
|
||||
OTIyMDU0M1owajELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAf
|
||||
BgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEjMCEGA1UEAxMaZXVyb3Bh
|
||||
EwtHb29nbGUgSW5jLjEMMAoGA1UECxMDRW5nMQwwCgYDVQQDEwNhZ2wxHTAbBgkq
|
||||
hkiG9w0BCQEWDmFnbEBnb29nbGUuY29tMB4XDTA5MDkwOTIyMDU0M1oXDTEwMDkw
|
||||
OTIyMDU0M1owajELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAf
|
||||
BgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEjMCEGA1UEAxMaZXVyb3Bh
|
||||
LnNmby5jb3JwLmdvb2dsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
||||
AoICAQC6pgYt7/EibBDumASF+S0qvqdL/f+nouJw2T1Qc8GmXF/iiUcrsgzh/Fd8
|
||||
pDhz/T96Qg9IyR4ztuc2MXrmPra+zAuSf5bevFReSqvpIt8Duv0HbDbcqs/XKPfB
|
||||
@@ -149,15 +149,15 @@ Pomjn71GNTtDeWAXibjCgdL6iHACCF6Htbl0zGlG0OAK+bdn0QIDAQABMA0GCSqG
|
||||
SIb3DQEBBQUAA4GBAOKnQDtqBV24vVqvesL5dnmyFpFPXBn3WdFfwD6DzEb21UVG
|
||||
5krmJiu+ViipORJPGMkgoL6BjU21XI95VQbun5P8vvg8Z+FnFsvRFY3e1CCzAVQY
|
||||
ZsUkLw2I7zI/dNlWdB8Xp7v+3w9sX5N3J/WuJ1KOO5m26kRlHQo7EzT3974g
|
||||
-----END CERTIFICATE-----
|
||||
-----END CERTIFICATE-----
|
||||
1 s:/C=ZA/O=Ca Inc./CN=CA Inc
|
||||
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,80C7C7A09690757A
|
||||
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,80C7C7A09690757A
|
||||
|
||||
eQp5ZkH6CyHBz7BZfUPxyLCCmftsBJ7HlqGb8Ld21cSwnzWZ4/SIlhyrUtsfw7VR
|
||||
2TTwA+odo9ex7GdxOTaH8oZFumIRoiEjHsk8U7Bhntp+ekkPP79xunnN7hb7hkhr
|
||||
2TTwA+odo9ex7GdxOTaH8oZFumIRoiEjHsk8U7Bhntp+ekkPP79xunnN7hb7hkhr
|
||||
yGDQZgA7s2cQHQ71v3gwT2BACAft26jCjbM1wgNzBnJ8M0Rzn68YWqaPtdBu8qb/
|
||||
zVR5JB1mnqvTSbFsfF5yMc6o2WQ9jJCl6KypnMl+BpL+dlvdjYVK4l9lYsB1Hs3d
|
||||
+zDBbWxos818zzhS8/y6eIfiSG27cqrbhURbmgiSfDXjncK4m/pLcQ7mmBL6mFOr
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
This directory tree contains experimental packages and
|
||||
unfinished code that is subject to even more change than the
|
||||
rest of the Go tree.
|
||||
@@ -1,269 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ebnf is a library for EBNF grammars. The input is text ([]byte)
|
||||
// satisfying the following grammar (represented itself in EBNF):
|
||||
//
|
||||
// Production = name "=" [ Expression ] "." .
|
||||
// Expression = Alternative { "|" Alternative } .
|
||||
// Alternative = Term { Term } .
|
||||
// Term = name | token [ "…" token ] | Group | Option | Repetition .
|
||||
// Group = "(" Expression ")" .
|
||||
// Option = "[" Expression "]" .
|
||||
// Repetition = "{" Expression "}" .
|
||||
//
|
||||
// A name is a Go identifier, a token is a Go string, and comments
|
||||
// and white space follow the same rules as for the Go language.
|
||||
// Production names starting with an uppercase Unicode letter denote
|
||||
// non-terminal productions (i.e., productions which allow white-space
|
||||
// and comments between tokens); all other production names denote
|
||||
// lexical productions.
|
||||
//
|
||||
package ebnf
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"text/scanner"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Error handling
|
||||
|
||||
type errorList []error
|
||||
|
||||
func (list errorList) Err() error {
|
||||
if len(list) == 0 {
|
||||
return nil
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func (list errorList) Error() string {
|
||||
switch len(list) {
|
||||
case 0:
|
||||
return "no errors"
|
||||
case 1:
|
||||
return list[0].Error()
|
||||
}
|
||||
return fmt.Sprintf("%s (and %d more errors)", list[0], len(list)-1)
|
||||
}
|
||||
|
||||
func newError(pos scanner.Position, msg string) error {
|
||||
return errors.New(fmt.Sprintf("%s: %s", pos, msg))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Internal representation
|
||||
|
||||
type (
|
||||
// An Expression node represents a production expression.
|
||||
Expression interface {
|
||||
// Pos is the position of the first character of the syntactic construct
|
||||
Pos() scanner.Position
|
||||
}
|
||||
|
||||
// An Alternative node represents a non-empty list of alternative expressions.
|
||||
Alternative []Expression // x | y | z
|
||||
|
||||
// A Sequence node represents a non-empty list of sequential expressions.
|
||||
Sequence []Expression // x y z
|
||||
|
||||
// A Name node represents a production name.
|
||||
Name struct {
|
||||
StringPos scanner.Position
|
||||
String string
|
||||
}
|
||||
|
||||
// A Token node represents a literal.
|
||||
Token struct {
|
||||
StringPos scanner.Position
|
||||
String string
|
||||
}
|
||||
|
||||
// A List node represents a range of characters.
|
||||
Range struct {
|
||||
Begin, End *Token // begin ... end
|
||||
}
|
||||
|
||||
// A Group node represents a grouped expression.
|
||||
Group struct {
|
||||
Lparen scanner.Position
|
||||
Body Expression // (body)
|
||||
}
|
||||
|
||||
// An Option node represents an optional expression.
|
||||
Option struct {
|
||||
Lbrack scanner.Position
|
||||
Body Expression // [body]
|
||||
}
|
||||
|
||||
// A Repetition node represents a repeated expression.
|
||||
Repetition struct {
|
||||
Lbrace scanner.Position
|
||||
Body Expression // {body}
|
||||
}
|
||||
|
||||
// A Production node represents an EBNF production.
|
||||
Production struct {
|
||||
Name *Name
|
||||
Expr Expression
|
||||
}
|
||||
|
||||
// A Bad node stands for pieces of source code that lead to a parse error.
|
||||
Bad struct {
|
||||
TokPos scanner.Position
|
||||
Error string // parser error message
|
||||
}
|
||||
|
||||
// A Grammar is a set of EBNF productions. The map
|
||||
// is indexed by production name.
|
||||
//
|
||||
Grammar map[string]*Production
|
||||
)
|
||||
|
||||
func (x Alternative) Pos() scanner.Position { return x[0].Pos() } // the parser always generates non-empty Alternative
|
||||
func (x Sequence) Pos() scanner.Position { return x[0].Pos() } // the parser always generates non-empty Sequences
|
||||
func (x *Name) Pos() scanner.Position { return x.StringPos }
|
||||
func (x *Token) Pos() scanner.Position { return x.StringPos }
|
||||
func (x *Range) Pos() scanner.Position { return x.Begin.Pos() }
|
||||
func (x *Group) Pos() scanner.Position { return x.Lparen }
|
||||
func (x *Option) Pos() scanner.Position { return x.Lbrack }
|
||||
func (x *Repetition) Pos() scanner.Position { return x.Lbrace }
|
||||
func (x *Production) Pos() scanner.Position { return x.Name.Pos() }
|
||||
func (x *Bad) Pos() scanner.Position { return x.TokPos }
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Grammar verification
|
||||
|
||||
func isLexical(name string) bool {
|
||||
ch, _ := utf8.DecodeRuneInString(name)
|
||||
return !unicode.IsUpper(ch)
|
||||
}
|
||||
|
||||
type verifier struct {
|
||||
errors errorList
|
||||
worklist []*Production
|
||||
reached Grammar // set of productions reached from (and including) the root production
|
||||
grammar Grammar
|
||||
}
|
||||
|
||||
func (v *verifier) error(pos scanner.Position, msg string) {
|
||||
v.errors = append(v.errors, newError(pos, msg))
|
||||
}
|
||||
|
||||
func (v *verifier) push(prod *Production) {
|
||||
name := prod.Name.String
|
||||
if _, found := v.reached[name]; !found {
|
||||
v.worklist = append(v.worklist, prod)
|
||||
v.reached[name] = prod
|
||||
}
|
||||
}
|
||||
|
||||
func (v *verifier) verifyChar(x *Token) rune {
|
||||
s := x.String
|
||||
if utf8.RuneCountInString(s) != 1 {
|
||||
v.error(x.Pos(), "single char expected, found "+s)
|
||||
return 0
|
||||
}
|
||||
ch, _ := utf8.DecodeRuneInString(s)
|
||||
return ch
|
||||
}
|
||||
|
||||
func (v *verifier) verifyExpr(expr Expression, lexical bool) {
|
||||
switch x := expr.(type) {
|
||||
case nil:
|
||||
// empty expression
|
||||
case Alternative:
|
||||
for _, e := range x {
|
||||
v.verifyExpr(e, lexical)
|
||||
}
|
||||
case Sequence:
|
||||
for _, e := range x {
|
||||
v.verifyExpr(e, lexical)
|
||||
}
|
||||
case *Name:
|
||||
// a production with this name must exist;
|
||||
// add it to the worklist if not yet processed
|
||||
if prod, found := v.grammar[x.String]; found {
|
||||
v.push(prod)
|
||||
} else {
|
||||
v.error(x.Pos(), "missing production "+x.String)
|
||||
}
|
||||
// within a lexical production references
|
||||
// to non-lexical productions are invalid
|
||||
if lexical && !isLexical(x.String) {
|
||||
v.error(x.Pos(), "reference to non-lexical production "+x.String)
|
||||
}
|
||||
case *Token:
|
||||
// nothing to do for now
|
||||
case *Range:
|
||||
i := v.verifyChar(x.Begin)
|
||||
j := v.verifyChar(x.End)
|
||||
if i >= j {
|
||||
v.error(x.Pos(), "decreasing character range")
|
||||
}
|
||||
case *Group:
|
||||
v.verifyExpr(x.Body, lexical)
|
||||
case *Option:
|
||||
v.verifyExpr(x.Body, lexical)
|
||||
case *Repetition:
|
||||
v.verifyExpr(x.Body, lexical)
|
||||
case *Bad:
|
||||
v.error(x.Pos(), x.Error)
|
||||
default:
|
||||
panic(fmt.Sprintf("internal error: unexpected type %T", expr))
|
||||
}
|
||||
}
|
||||
|
||||
func (v *verifier) verify(grammar Grammar, start string) {
|
||||
// find root production
|
||||
root, found := grammar[start]
|
||||
if !found {
|
||||
var noPos scanner.Position
|
||||
v.error(noPos, "no start production "+start)
|
||||
return
|
||||
}
|
||||
|
||||
// initialize verifier
|
||||
v.worklist = v.worklist[0:0]
|
||||
v.reached = make(Grammar)
|
||||
v.grammar = grammar
|
||||
|
||||
// work through the worklist
|
||||
v.push(root)
|
||||
for {
|
||||
n := len(v.worklist) - 1
|
||||
if n < 0 {
|
||||
break
|
||||
}
|
||||
prod := v.worklist[n]
|
||||
v.worklist = v.worklist[0:n]
|
||||
v.verifyExpr(prod.Expr, isLexical(prod.Name.String))
|
||||
}
|
||||
|
||||
// check if all productions were reached
|
||||
if len(v.reached) < len(v.grammar) {
|
||||
for name, prod := range v.grammar {
|
||||
if _, found := v.reached[name]; !found {
|
||||
v.error(prod.Pos(), name+" is unreachable")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify checks that:
|
||||
// - all productions used are defined
|
||||
// - all productions defined are used when beginning at start
|
||||
// - lexical productions refer only to other lexical productions
|
||||
//
|
||||
// Position information is interpreted relative to the file set fset.
|
||||
//
|
||||
func Verify(grammar Grammar, start string) error {
|
||||
var v verifier
|
||||
v.verify(grammar, start)
|
||||
return v.errors.Err()
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ebnf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var goodGrammars = []string{
|
||||
`Program = .`,
|
||||
|
||||
`Program = foo .
|
||||
foo = "foo" .`,
|
||||
|
||||
`Program = "a" | "b" "c" .`,
|
||||
|
||||
`Program = "a" … "z" .`,
|
||||
|
||||
`Program = Song .
|
||||
Song = { Note } .
|
||||
Note = Do | (Re | Mi | Fa | So | La) | Ti .
|
||||
Do = "c" .
|
||||
Re = "d" .
|
||||
Mi = "e" .
|
||||
Fa = "f" .
|
||||
So = "g" .
|
||||
La = "a" .
|
||||
Ti = ti .
|
||||
ti = "b" .`,
|
||||
}
|
||||
|
||||
var badGrammars = []string{
|
||||
`Program = | .`,
|
||||
`Program = | b .`,
|
||||
`Program = a … b .`,
|
||||
`Program = "a" … .`,
|
||||
`Program = … "b" .`,
|
||||
`Program = () .`,
|
||||
`Program = [] .`,
|
||||
`Program = {} .`,
|
||||
}
|
||||
|
||||
func checkGood(t *testing.T, src string) {
|
||||
grammar, err := Parse("", bytes.NewBuffer([]byte(src)))
|
||||
if err != nil {
|
||||
t.Errorf("Parse(%s) failed: %v", src, err)
|
||||
return
|
||||
}
|
||||
if err = Verify(grammar, "Program"); err != nil {
|
||||
t.Errorf("Verify(%s) failed: %v", src, err)
|
||||
}
|
||||
}
|
||||
|
||||
func checkBad(t *testing.T, src string) {
|
||||
_, err := Parse("", bytes.NewBuffer([]byte(src)))
|
||||
if err == nil {
|
||||
t.Errorf("Parse(%s) should have failed", src)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGrammars(t *testing.T) {
|
||||
for _, src := range goodGrammars {
|
||||
checkGood(t, src)
|
||||
}
|
||||
for _, src := range badGrammars {
|
||||
checkBad(t, src)
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ebnf
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
"text/scanner"
|
||||
)
|
||||
|
||||
type parser struct {
|
||||
errors errorList
|
||||
scanner scanner.Scanner
|
||||
pos scanner.Position // token position
|
||||
tok rune // one token look-ahead
|
||||
lit string // token literal
|
||||
}
|
||||
|
||||
func (p *parser) next() {
|
||||
p.tok = p.scanner.Scan()
|
||||
p.pos = p.scanner.Position
|
||||
p.lit = p.scanner.TokenText()
|
||||
}
|
||||
|
||||
func (p *parser) error(pos scanner.Position, msg string) {
|
||||
p.errors = append(p.errors, newError(pos, msg))
|
||||
}
|
||||
|
||||
func (p *parser) errorExpected(pos scanner.Position, msg string) {
|
||||
msg = `expected "` + msg + `"`
|
||||
if pos.Offset == p.pos.Offset {
|
||||
// the error happened at the current position;
|
||||
// make the error message more specific
|
||||
msg += ", found " + scanner.TokenString(p.tok)
|
||||
if p.tok < 0 {
|
||||
msg += " " + p.lit
|
||||
}
|
||||
}
|
||||
p.error(pos, msg)
|
||||
}
|
||||
|
||||
func (p *parser) expect(tok rune) scanner.Position {
|
||||
pos := p.pos
|
||||
if p.tok != tok {
|
||||
p.errorExpected(pos, scanner.TokenString(tok))
|
||||
}
|
||||
p.next() // make progress in any case
|
||||
return pos
|
||||
}
|
||||
|
||||
func (p *parser) parseIdentifier() *Name {
|
||||
pos := p.pos
|
||||
name := p.lit
|
||||
p.expect(scanner.Ident)
|
||||
return &Name{pos, name}
|
||||
}
|
||||
|
||||
func (p *parser) parseToken() *Token {
|
||||
pos := p.pos
|
||||
value := ""
|
||||
if p.tok == scanner.String {
|
||||
value, _ = strconv.Unquote(p.lit)
|
||||
// Unquote may fail with an error, but only if the scanner found
|
||||
// an illegal string in the first place. In this case the error
|
||||
// has already been reported.
|
||||
p.next()
|
||||
} else {
|
||||
p.expect(scanner.String)
|
||||
}
|
||||
return &Token{pos, value}
|
||||
}
|
||||
|
||||
// ParseTerm returns nil if no term was found.
|
||||
func (p *parser) parseTerm() (x Expression) {
|
||||
pos := p.pos
|
||||
|
||||
switch p.tok {
|
||||
case scanner.Ident:
|
||||
x = p.parseIdentifier()
|
||||
|
||||
case scanner.String:
|
||||
tok := p.parseToken()
|
||||
x = tok
|
||||
const ellipsis = '…' // U+2026, the horizontal ellipsis character
|
||||
if p.tok == ellipsis {
|
||||
p.next()
|
||||
x = &Range{tok, p.parseToken()}
|
||||
}
|
||||
|
||||
case '(':
|
||||
p.next()
|
||||
x = &Group{pos, p.parseExpression()}
|
||||
p.expect(')')
|
||||
|
||||
case '[':
|
||||
p.next()
|
||||
x = &Option{pos, p.parseExpression()}
|
||||
p.expect(']')
|
||||
|
||||
case '{':
|
||||
p.next()
|
||||
x = &Repetition{pos, p.parseExpression()}
|
||||
p.expect('}')
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
func (p *parser) parseSequence() Expression {
|
||||
var list Sequence
|
||||
|
||||
for x := p.parseTerm(); x != nil; x = p.parseTerm() {
|
||||
list = append(list, x)
|
||||
}
|
||||
|
||||
// no need for a sequence if list.Len() < 2
|
||||
switch len(list) {
|
||||
case 0:
|
||||
p.errorExpected(p.pos, "term")
|
||||
return &Bad{p.pos, "term expected"}
|
||||
case 1:
|
||||
return list[0]
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
func (p *parser) parseExpression() Expression {
|
||||
var list Alternative
|
||||
|
||||
for {
|
||||
list = append(list, p.parseSequence())
|
||||
if p.tok != '|' {
|
||||
break
|
||||
}
|
||||
p.next()
|
||||
}
|
||||
// len(list) > 0
|
||||
|
||||
// no need for an Alternative node if list.Len() < 2
|
||||
if len(list) == 1 {
|
||||
return list[0]
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
func (p *parser) parseProduction() *Production {
|
||||
name := p.parseIdentifier()
|
||||
p.expect('=')
|
||||
var expr Expression
|
||||
if p.tok != '.' {
|
||||
expr = p.parseExpression()
|
||||
}
|
||||
p.expect('.')
|
||||
return &Production{name, expr}
|
||||
}
|
||||
|
||||
func (p *parser) parse(filename string, src io.Reader) Grammar {
|
||||
p.scanner.Init(src)
|
||||
p.scanner.Filename = filename
|
||||
p.next() // initializes pos, tok, lit
|
||||
|
||||
grammar := make(Grammar)
|
||||
for p.tok != scanner.EOF {
|
||||
prod := p.parseProduction()
|
||||
name := prod.Name.String
|
||||
if _, found := grammar[name]; !found {
|
||||
grammar[name] = prod
|
||||
} else {
|
||||
p.error(prod.Pos(), name+" declared already")
|
||||
}
|
||||
}
|
||||
|
||||
return grammar
|
||||
}
|
||||
|
||||
// Parse parses a set of EBNF productions from source src.
|
||||
// It returns a set of productions. Errors are reported
|
||||
// for incorrect syntax and if a production is declared
|
||||
// more than once; the filename is used only for error
|
||||
// positions.
|
||||
//
|
||||
func Parse(filename string, src io.Reader) (Grammar, error) {
|
||||
var p parser
|
||||
grammar := p.parse(filename, src)
|
||||
return grammar, p.errors.Err()
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
|
||||
Ebnflint verifies that EBNF productions are consistent and grammatically correct.
|
||||
It reads them from an HTML document such as the Go specification.
|
||||
|
||||
Grammar productions are grouped in boxes demarcated by the HTML elements
|
||||
<pre class="ebnf">
|
||||
</pre>
|
||||
|
||||
|
||||
Usage:
|
||||
go tool ebnflint [--start production] [file]
|
||||
|
||||
The --start flag specifies the name of the start production for
|
||||
the grammar; it defaults to "Start".
|
||||
|
||||
*/
|
||||
package documentation
|
||||
@@ -1,122 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"exp/ebnf"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/scanner"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var fset = token.NewFileSet()
|
||||
var start = flag.String("start", "Start", "name of start production")
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "usage: go tool ebnflint [flags] [filename]\n")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Markers around EBNF sections in .html files
|
||||
var (
|
||||
open = []byte(`<pre class="ebnf">`)
|
||||
close = []byte(`</pre>`)
|
||||
)
|
||||
|
||||
func report(err error) {
|
||||
scanner.PrintError(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func extractEBNF(src []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
|
||||
for {
|
||||
// i = beginning of EBNF text
|
||||
i := bytes.Index(src, open)
|
||||
if i < 0 {
|
||||
break // no EBNF found - we are done
|
||||
}
|
||||
i += len(open)
|
||||
|
||||
// write as many newlines as found in the excluded text
|
||||
// to maintain correct line numbers in error messages
|
||||
for _, ch := range src[0:i] {
|
||||
if ch == '\n' {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
}
|
||||
|
||||
// j = end of EBNF text (or end of source)
|
||||
j := bytes.Index(src[i:], close) // close marker
|
||||
if j < 0 {
|
||||
j = len(src) - i
|
||||
}
|
||||
j += i
|
||||
|
||||
// copy EBNF text
|
||||
buf.Write(src[i:j])
|
||||
|
||||
// advance
|
||||
src = src[j:]
|
||||
}
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var (
|
||||
name string
|
||||
r io.Reader
|
||||
)
|
||||
switch flag.NArg() {
|
||||
case 0:
|
||||
name, r = "<stdin>", os.Stdin
|
||||
case 1:
|
||||
name = flag.Arg(0)
|
||||
default:
|
||||
usage()
|
||||
}
|
||||
|
||||
if err := verify(name, *start, r); err != nil {
|
||||
report(err)
|
||||
}
|
||||
}
|
||||
|
||||
func verify(name, start string, r io.Reader) error {
|
||||
if r == nil {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
r = f
|
||||
}
|
||||
|
||||
src, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if filepath.Ext(name) == ".html" || bytes.Index(src, open) >= 0 {
|
||||
src = extractEBNF(src)
|
||||
}
|
||||
|
||||
grammar, err := ebnf.Parse(name, bytes.NewBuffer(src))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ebnf.Verify(grammar, start)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSpec(t *testing.T) {
|
||||
if err := verify(runtime.GOROOT()+"/doc/go_spec.html", "SourceFile", nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
The gotype command does syntactic and semantic analysis of Go files
|
||||
and packages similar to the analysis performed by the front-end of
|
||||
a Go compiler. Errors are reported if the analysis fails; otherwise
|
||||
gotype is quiet (unless -v is set).
|
||||
|
||||
Without a list of paths, gotype processes the standard input, which must
|
||||
be the source of a single package file.
|
||||
|
||||
Given a list of file names, each file must be a source file belonging to
|
||||
the same package unless the package name is explicitly specified with the
|
||||
-p flag.
|
||||
|
||||
Given a directory name, gotype collects all .go files in the directory
|
||||
and processes them as if they were provided as an explicit list of file
|
||||
names. Each directory is processed independently. Files starting with .
|
||||
or not ending in .go are ignored.
|
||||
|
||||
Usage:
|
||||
gotype [flags] [path ...]
|
||||
|
||||
The flags are:
|
||||
-e
|
||||
Print all (including spurious) errors.
|
||||
-p pkgName
|
||||
Process only those files in package pkgName.
|
||||
-r
|
||||
Recursively process subdirectories.
|
||||
-v
|
||||
Verbose mode.
|
||||
|
||||
Debugging flags:
|
||||
-comments
|
||||
Parse comments (ignored if -ast not set).
|
||||
-ast
|
||||
Print AST (disables concurrent parsing).
|
||||
-trace
|
||||
Print parse trace (disables concurrent parsing).
|
||||
|
||||
|
||||
Examples
|
||||
|
||||
To check the files file.go, old.saved, and .ignored:
|
||||
|
||||
gotype file.go old.saved .ignored
|
||||
|
||||
To check all .go files belonging to package main in the current directory
|
||||
and recursively in all subdirectories:
|
||||
|
||||
gotype -p main -r .
|
||||
|
||||
To verify the output of a pipe:
|
||||
|
||||
echo "package foo" | gotype
|
||||
|
||||
*/
|
||||
package documentation
|
||||
|
||||
// BUG(gri): At the moment, only single-file scope analysis is performed.
|
||||
@@ -1,197 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"exp/types"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/scanner"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// main operation modes
|
||||
pkgName = flag.String("p", "", "process only those files in package pkgName")
|
||||
recursive = flag.Bool("r", false, "recursively process subdirectories")
|
||||
verbose = flag.Bool("v", false, "verbose mode")
|
||||
allErrors = flag.Bool("e", false, "print all (including spurious) errors")
|
||||
|
||||
// debugging support
|
||||
parseComments = flag.Bool("comments", false, "parse comments (ignored if -ast not set)")
|
||||
printTrace = flag.Bool("trace", false, "print parse trace")
|
||||
printAST = flag.Bool("ast", false, "print AST")
|
||||
)
|
||||
|
||||
var exitCode = 0
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "usage: gotype [flags] [path ...]\n")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
func report(err error) {
|
||||
scanner.PrintError(os.Stderr, err)
|
||||
exitCode = 2
|
||||
}
|
||||
|
||||
// parse returns the AST for the Go source src.
|
||||
// The filename is for error reporting only.
|
||||
// The result is nil if there were errors or if
|
||||
// the file does not belong to the -p package.
|
||||
func parse(fset *token.FileSet, filename string, src []byte) *ast.File {
|
||||
if *verbose {
|
||||
fmt.Println(filename)
|
||||
}
|
||||
|
||||
// ignore files with different package name
|
||||
if *pkgName != "" {
|
||||
file, err := parser.ParseFile(fset, filename, src, parser.PackageClauseOnly)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return nil
|
||||
}
|
||||
if file.Name.Name != *pkgName {
|
||||
if *verbose {
|
||||
fmt.Printf("\tignored (package %s)\n", file.Name.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// parse entire file
|
||||
mode := parser.DeclarationErrors
|
||||
if *allErrors {
|
||||
mode |= parser.SpuriousErrors
|
||||
}
|
||||
if *parseComments && *printAST {
|
||||
mode |= parser.ParseComments
|
||||
}
|
||||
if *printTrace {
|
||||
mode |= parser.Trace
|
||||
}
|
||||
file, err := parser.ParseFile(fset, filename, src, mode)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return nil
|
||||
}
|
||||
if *printAST {
|
||||
ast.Print(fset, file)
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
func parseStdin(fset *token.FileSet) (files map[string]*ast.File) {
|
||||
files = make(map[string]*ast.File)
|
||||
src, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return
|
||||
}
|
||||
const filename = "<standard input>"
|
||||
if file := parse(fset, filename, src); file != nil {
|
||||
files[filename] = file
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseFiles(fset *token.FileSet, filenames []string) (files map[string]*ast.File) {
|
||||
files = make(map[string]*ast.File)
|
||||
for _, filename := range filenames {
|
||||
src, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
report(err)
|
||||
continue
|
||||
}
|
||||
if file := parse(fset, filename, src); file != nil {
|
||||
if files[filename] != nil {
|
||||
report(errors.New(fmt.Sprintf("%q: duplicate file", filename)))
|
||||
continue
|
||||
}
|
||||
files[filename] = file
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func isGoFilename(filename string) bool {
|
||||
// ignore non-Go files
|
||||
return !strings.HasPrefix(filename, ".") && strings.HasSuffix(filename, ".go")
|
||||
}
|
||||
|
||||
func processDirectory(dirname string) {
|
||||
f, err := os.Open(dirname)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return
|
||||
}
|
||||
filenames, err := f.Readdirnames(-1)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
report(err)
|
||||
// continue since filenames may not be empty
|
||||
}
|
||||
for i, filename := range filenames {
|
||||
filenames[i] = filepath.Join(dirname, filename)
|
||||
}
|
||||
processFiles(filenames, false)
|
||||
}
|
||||
|
||||
func processFiles(filenames []string, allFiles bool) {
|
||||
i := 0
|
||||
for _, filename := range filenames {
|
||||
switch info, err := os.Stat(filename); {
|
||||
case err != nil:
|
||||
report(err)
|
||||
case info.IsDir():
|
||||
if allFiles || *recursive {
|
||||
processDirectory(filename)
|
||||
}
|
||||
default:
|
||||
if allFiles || isGoFilename(info.Name()) {
|
||||
filenames[i] = filename
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
fset := token.NewFileSet()
|
||||
processPackage(fset, parseFiles(fset, filenames[0:i]))
|
||||
}
|
||||
|
||||
func processPackage(fset *token.FileSet, files map[string]*ast.File) {
|
||||
// make a package (resolve all identifiers)
|
||||
pkg, err := ast.NewPackage(fset, files, types.GcImport, types.Universe)
|
||||
if err != nil {
|
||||
report(err)
|
||||
return
|
||||
}
|
||||
_, err = types.Check(fset, pkg)
|
||||
if err != nil {
|
||||
report(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() == 0 {
|
||||
fset := token.NewFileSet()
|
||||
processPackage(fset, parseStdin(fset))
|
||||
} else {
|
||||
processFiles(flag.Args(), true)
|
||||
}
|
||||
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func runTest(t *testing.T, path, pkg string) {
|
||||
exitCode = 0
|
||||
*pkgName = pkg
|
||||
*recursive = false
|
||||
|
||||
if pkg == "" {
|
||||
processFiles([]string{path}, true)
|
||||
} else {
|
||||
processDirectory(path)
|
||||
}
|
||||
|
||||
if exitCode != 0 {
|
||||
t.Errorf("processing %s failed: exitCode = %d", path, exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
path string
|
||||
pkg string
|
||||
}{
|
||||
// individual files
|
||||
{"testdata/test1.go", ""},
|
||||
|
||||
// directories
|
||||
{filepath.Join(runtime.GOROOT(), "src/pkg/go/ast"), "ast"},
|
||||
{filepath.Join(runtime.GOROOT(), "src/pkg/go/doc"), "doc"},
|
||||
{filepath.Join(runtime.GOROOT(), "src/pkg/go/token"), "scanner"},
|
||||
{filepath.Join(runtime.GOROOT(), "src/pkg/go/scanner"), "scanner"},
|
||||
{filepath.Join(runtime.GOROOT(), "src/pkg/go/parser"), "parser"},
|
||||
{filepath.Join(runtime.GOROOT(), "src/pkg/exp/types"), "types"},
|
||||
}
|
||||
|
||||
func Test(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
runTest(t, test.path, test.pkg)
|
||||
}
|
||||
}
|
||||
27
src/pkg/exp/gotype/testdata/test1.go
vendored
27
src/pkg/exp/gotype/testdata/test1.go
vendored
@@ -1,27 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
func _() {
|
||||
// the scope of a local type declaration starts immediately after the type name
|
||||
type T struct{ _ *T }
|
||||
}
|
||||
|
||||
func _(x interface{}) {
|
||||
// the variable defined by a TypeSwitchGuard is declared in each TypeCaseClause
|
||||
switch t := x.(type) {
|
||||
case int:
|
||||
_ = t
|
||||
case float32:
|
||||
_ = t
|
||||
default:
|
||||
_ = t
|
||||
}
|
||||
|
||||
// the variable defined by a TypeSwitchGuard must not conflict with other
|
||||
// variables declared in the initial simple statement
|
||||
switch t := 0; t := x.(type) {
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
// Section 12.2.3.2 of the HTML5 specification says "The following elements
|
||||
// have varying levels of special parsing rules".
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements
|
||||
var isSpecialElementMap = map[string]bool{
|
||||
"address": true,
|
||||
"applet": true,
|
||||
"area": true,
|
||||
"article": true,
|
||||
"aside": true,
|
||||
"base": true,
|
||||
"basefont": true,
|
||||
"bgsound": true,
|
||||
"blockquote": true,
|
||||
"body": true,
|
||||
"br": true,
|
||||
"button": true,
|
||||
"caption": true,
|
||||
"center": true,
|
||||
"col": true,
|
||||
"colgroup": true,
|
||||
"command": true,
|
||||
"dd": true,
|
||||
"details": true,
|
||||
"dir": true,
|
||||
"div": true,
|
||||
"dl": true,
|
||||
"dt": true,
|
||||
"embed": true,
|
||||
"fieldset": true,
|
||||
"figcaption": true,
|
||||
"figure": true,
|
||||
"footer": true,
|
||||
"form": true,
|
||||
"frame": true,
|
||||
"frameset": true,
|
||||
"h1": true,
|
||||
"h2": true,
|
||||
"h3": true,
|
||||
"h4": true,
|
||||
"h5": true,
|
||||
"h6": true,
|
||||
"head": true,
|
||||
"header": true,
|
||||
"hgroup": true,
|
||||
"hr": true,
|
||||
"html": true,
|
||||
"iframe": true,
|
||||
"img": true,
|
||||
"input": true,
|
||||
"isindex": true,
|
||||
"li": true,
|
||||
"link": true,
|
||||
"listing": true,
|
||||
"marquee": true,
|
||||
"menu": true,
|
||||
"meta": true,
|
||||
"nav": true,
|
||||
"noembed": true,
|
||||
"noframes": true,
|
||||
"noscript": true,
|
||||
"object": true,
|
||||
"ol": true,
|
||||
"p": true,
|
||||
"param": true,
|
||||
"plaintext": true,
|
||||
"pre": true,
|
||||
"script": true,
|
||||
"section": true,
|
||||
"select": true,
|
||||
"style": true,
|
||||
"summary": true,
|
||||
"table": true,
|
||||
"tbody": true,
|
||||
"td": true,
|
||||
"textarea": true,
|
||||
"tfoot": true,
|
||||
"th": true,
|
||||
"thead": true,
|
||||
"title": true,
|
||||
"tr": true,
|
||||
"ul": true,
|
||||
"wbr": true,
|
||||
"xmp": true,
|
||||
}
|
||||
|
||||
func isSpecialElement(element *Node) bool {
|
||||
switch element.Namespace {
|
||||
case "", "html":
|
||||
return isSpecialElementMap[element.Data]
|
||||
case "svg":
|
||||
return element.Data == "foreignObject"
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package html implements an HTML5-compliant tokenizer and parser.
|
||||
INCOMPLETE.
|
||||
|
||||
Tokenization is done by creating a Tokenizer for an io.Reader r. It is the
|
||||
caller's responsibility to ensure that r provides UTF-8 encoded HTML.
|
||||
|
||||
z := html.NewTokenizer(r)
|
||||
|
||||
Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(),
|
||||
which parses the next token and returns its type, or an error:
|
||||
|
||||
for {
|
||||
tt := z.Next()
|
||||
if tt == html.ErrorToken {
|
||||
// ...
|
||||
return ...
|
||||
}
|
||||
// Process the current token.
|
||||
}
|
||||
|
||||
There are two APIs for retrieving the current token. The high-level API is to
|
||||
call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs
|
||||
allow optionally calling Raw after Next but before Token, Text, TagName, or
|
||||
TagAttr. In EBNF notation, the valid call sequence per token is:
|
||||
|
||||
Next {Raw} [ Token | Text | TagName {TagAttr} ]
|
||||
|
||||
Token returns an independent data structure that completely describes a token.
|
||||
Entities (such as "<") are unescaped, tag names and attribute keys are
|
||||
lower-cased, and attributes are collected into a []Attribute. For example:
|
||||
|
||||
for {
|
||||
if z.Next() == html.ErrorToken {
|
||||
// Returning io.EOF indicates success.
|
||||
return z.Err()
|
||||
}
|
||||
emitToken(z.Token())
|
||||
}
|
||||
|
||||
The low-level API performs fewer allocations and copies, but the contents of
|
||||
the []byte values returned by Text, TagName and TagAttr may change on the next
|
||||
call to Next. For example, to extract an HTML page's anchor text:
|
||||
|
||||
depth := 0
|
||||
for {
|
||||
tt := z.Next()
|
||||
switch tt {
|
||||
case ErrorToken:
|
||||
return z.Err()
|
||||
case TextToken:
|
||||
if depth > 0 {
|
||||
// emitBytes should copy the []byte it receives,
|
||||
// if it doesn't process it immediately.
|
||||
emitBytes(z.Text())
|
||||
}
|
||||
case StartTagToken, EndTagToken:
|
||||
tn, _ := z.TagName()
|
||||
if len(tn) == 1 && tn[0] == 'a' {
|
||||
if tt == StartTagToken {
|
||||
depth++
|
||||
} else {
|
||||
depth--
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Parsing is done by calling Parse with an io.Reader, which returns the root of
|
||||
the parse tree (the document element) as a *Node. It is the caller's
|
||||
responsibility to ensure that the Reader provides UTF-8 encoded HTML. For
|
||||
example, to process each anchor node in depth-first order:
|
||||
|
||||
doc, err := html.Parse(r)
|
||||
if err != nil {
|
||||
// ...
|
||||
}
|
||||
var f func(*html.Node)
|
||||
f = func(n *html.Node) {
|
||||
if n.Type == html.ElementNode && n.Data == "a" {
|
||||
// Do something with n...
|
||||
}
|
||||
for _, c := range n.Child {
|
||||
f(c)
|
||||
}
|
||||
}
|
||||
f(doc)
|
||||
|
||||
The relevant specifications include:
|
||||
http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html and
|
||||
http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
|
||||
*/
|
||||
package html
|
||||
|
||||
// The tokenization algorithm implemented by this package is not a line-by-line
|
||||
// transliteration of the relatively verbose state-machine in the WHATWG
|
||||
// specification. A more direct approach is used instead, where the program
|
||||
// counter implies the state, such as whether it is tokenizing a tag or a text
|
||||
// node. Specification compliance is verified by checking expected and actual
|
||||
// outputs over a test suite rather than aiming for algorithmic fidelity.
|
||||
|
||||
// TODO(nigeltao): Does a DOM API belong in this package or a separate one?
|
||||
// TODO(nigeltao): How does parsing interact with a JavaScript engine?
|
||||
@@ -1,156 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// parseDoctype parses the data from a DoctypeToken into a name,
|
||||
// public identifier, and system identifier. It returns a Node whose Type
|
||||
// is DoctypeNode, whose Data is the name, and which has attributes
|
||||
// named "system" and "public" for the two identifiers if they were present.
|
||||
// quirks is whether the document should be parsed in "quirks mode".
|
||||
func parseDoctype(s string) (n *Node, quirks bool) {
|
||||
n = &Node{Type: DoctypeNode}
|
||||
|
||||
// Find the name.
|
||||
space := strings.IndexAny(s, whitespace)
|
||||
if space == -1 {
|
||||
space = len(s)
|
||||
}
|
||||
n.Data = s[:space]
|
||||
// The comparison to "html" is case-sensitive.
|
||||
if n.Data != "html" {
|
||||
quirks = true
|
||||
}
|
||||
n.Data = strings.ToLower(n.Data)
|
||||
s = strings.TrimLeft(s[space:], whitespace)
|
||||
|
||||
if len(s) < 6 {
|
||||
// It can't start with "PUBLIC" or "SYSTEM".
|
||||
// Ignore the rest of the string.
|
||||
return n, quirks || s != ""
|
||||
}
|
||||
|
||||
key := strings.ToLower(s[:6])
|
||||
s = s[6:]
|
||||
for key == "public" || key == "system" {
|
||||
s = strings.TrimLeft(s, whitespace)
|
||||
if s == "" {
|
||||
break
|
||||
}
|
||||
quote := s[0]
|
||||
if quote != '"' && quote != '\'' {
|
||||
break
|
||||
}
|
||||
s = s[1:]
|
||||
q := strings.IndexRune(s, rune(quote))
|
||||
var id string
|
||||
if q == -1 {
|
||||
id = s
|
||||
s = ""
|
||||
} else {
|
||||
id = s[:q]
|
||||
s = s[q+1:]
|
||||
}
|
||||
n.Attr = append(n.Attr, Attribute{Key: key, Val: id})
|
||||
if key == "public" {
|
||||
key = "system"
|
||||
} else {
|
||||
key = ""
|
||||
}
|
||||
}
|
||||
|
||||
if key != "" || s != "" {
|
||||
quirks = true
|
||||
} else if len(n.Attr) > 0 {
|
||||
if n.Attr[0].Key == "public" {
|
||||
public := strings.ToLower(n.Attr[0].Val)
|
||||
switch public {
|
||||
case "-//w3o//dtd w3 html strict 3.0//en//", "-/w3d/dtd html 4.0 transitional/en", "html":
|
||||
quirks = true
|
||||
default:
|
||||
for _, q := range quirkyIDs {
|
||||
if strings.HasPrefix(public, q) {
|
||||
quirks = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// The following two public IDs only cause quirks mode if there is no system ID.
|
||||
if len(n.Attr) == 1 && (strings.HasPrefix(public, "-//w3c//dtd html 4.01 frameset//") ||
|
||||
strings.HasPrefix(public, "-//w3c//dtd html 4.01 transitional//")) {
|
||||
quirks = true
|
||||
}
|
||||
}
|
||||
if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" &&
|
||||
strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" {
|
||||
quirks = true
|
||||
}
|
||||
}
|
||||
|
||||
return n, quirks
|
||||
}
|
||||
|
||||
// quirkyIDs is a list of public doctype identifiers that cause a document
|
||||
// to be interpreted in quirks mode. The identifiers should be in lower case.
|
||||
var quirkyIDs = []string{
|
||||
"+//silmaril//dtd html pro v0r11 19970101//",
|
||||
"-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
|
||||
"-//as//dtd html 3.0 aswedit + extensions//",
|
||||
"-//ietf//dtd html 2.0 level 1//",
|
||||
"-//ietf//dtd html 2.0 level 2//",
|
||||
"-//ietf//dtd html 2.0 strict level 1//",
|
||||
"-//ietf//dtd html 2.0 strict level 2//",
|
||||
"-//ietf//dtd html 2.0 strict//",
|
||||
"-//ietf//dtd html 2.0//",
|
||||
"-//ietf//dtd html 2.1e//",
|
||||
"-//ietf//dtd html 3.0//",
|
||||
"-//ietf//dtd html 3.2 final//",
|
||||
"-//ietf//dtd html 3.2//",
|
||||
"-//ietf//dtd html 3//",
|
||||
"-//ietf//dtd html level 0//",
|
||||
"-//ietf//dtd html level 1//",
|
||||
"-//ietf//dtd html level 2//",
|
||||
"-//ietf//dtd html level 3//",
|
||||
"-//ietf//dtd html strict level 0//",
|
||||
"-//ietf//dtd html strict level 1//",
|
||||
"-//ietf//dtd html strict level 2//",
|
||||
"-//ietf//dtd html strict level 3//",
|
||||
"-//ietf//dtd html strict//",
|
||||
"-//ietf//dtd html//",
|
||||
"-//metrius//dtd metrius presentational//",
|
||||
"-//microsoft//dtd internet explorer 2.0 html strict//",
|
||||
"-//microsoft//dtd internet explorer 2.0 html//",
|
||||
"-//microsoft//dtd internet explorer 2.0 tables//",
|
||||
"-//microsoft//dtd internet explorer 3.0 html strict//",
|
||||
"-//microsoft//dtd internet explorer 3.0 html//",
|
||||
"-//microsoft//dtd internet explorer 3.0 tables//",
|
||||
"-//netscape comm. corp.//dtd html//",
|
||||
"-//netscape comm. corp.//dtd strict html//",
|
||||
"-//o'reilly and associates//dtd html 2.0//",
|
||||
"-//o'reilly and associates//dtd html extended 1.0//",
|
||||
"-//o'reilly and associates//dtd html extended relaxed 1.0//",
|
||||
"-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
|
||||
"-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
|
||||
"-//spyglass//dtd html 2.0 extended//",
|
||||
"-//sq//dtd html 2.0 hotmetal + extensions//",
|
||||
"-//sun microsystems corp.//dtd hotjava html//",
|
||||
"-//sun microsystems corp.//dtd hotjava strict html//",
|
||||
"-//w3c//dtd html 3 1995-03-24//",
|
||||
"-//w3c//dtd html 3.2 draft//",
|
||||
"-//w3c//dtd html 3.2 final//",
|
||||
"-//w3c//dtd html 3.2//",
|
||||
"-//w3c//dtd html 3.2s draft//",
|
||||
"-//w3c//dtd html 4.0 frameset//",
|
||||
"-//w3c//dtd html 4.0 transitional//",
|
||||
"-//w3c//dtd html experimental 19960712//",
|
||||
"-//w3c//dtd html experimental 970421//",
|
||||
"-//w3c//dtd w3 html//",
|
||||
"-//w3o//dtd w3 html 3.0//",
|
||||
"-//webtechs//dtd mozilla html 2.0//",
|
||||
"-//webtechs//dtd mozilla html//",
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func TestEntityLength(t *testing.T) {
|
||||
// We verify that the length of UTF-8 encoding of each value is <= 1 + len(key).
|
||||
// The +1 comes from the leading "&". This property implies that the length of
|
||||
// unescaped text is <= the length of escaped text.
|
||||
for k, v := range entity {
|
||||
if 1+len(k) < utf8.RuneLen(v) {
|
||||
t.Error("escaped entity &" + k + " is shorter than its UTF-8 encoding " + string(v))
|
||||
}
|
||||
if len(k) > longestEntityWithoutSemicolon && k[len(k)-1] != ';' {
|
||||
t.Errorf("entity name %s is %d characters, but longestEntityWithoutSemicolon=%d", k, len(k), longestEntityWithoutSemicolon)
|
||||
}
|
||||
}
|
||||
for k, v := range entity2 {
|
||||
if 1+len(k) < utf8.RuneLen(v[0])+utf8.RuneLen(v[1]) {
|
||||
t.Error("escaped entity &" + k + " is shorter than its UTF-8 encoding " + string(v[0]) + string(v[1]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// These replacements permit compatibility with old numeric entities that
|
||||
// assumed Windows-1252 encoding.
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
|
||||
var replacementTable = [...]rune{
|
||||
'\u20AC', // First entry is what 0x80 should be replaced with.
|
||||
'\u0081',
|
||||
'\u201A',
|
||||
'\u0192',
|
||||
'\u201E',
|
||||
'\u2026',
|
||||
'\u2020',
|
||||
'\u2021',
|
||||
'\u02C6',
|
||||
'\u2030',
|
||||
'\u0160',
|
||||
'\u2039',
|
||||
'\u0152',
|
||||
'\u008D',
|
||||
'\u017D',
|
||||
'\u008F',
|
||||
'\u0090',
|
||||
'\u2018',
|
||||
'\u2019',
|
||||
'\u201C',
|
||||
'\u201D',
|
||||
'\u2022',
|
||||
'\u2013',
|
||||
'\u2014',
|
||||
'\u02DC',
|
||||
'\u2122',
|
||||
'\u0161',
|
||||
'\u203A',
|
||||
'\u0153',
|
||||
'\u009D',
|
||||
'\u017E',
|
||||
'\u0178', // Last entry is 0x9F.
|
||||
// 0x00->'\uFFFD' is handled programmatically.
|
||||
// 0x0D->'\u000D' is a no-op.
|
||||
}
|
||||
|
||||
// unescapeEntity reads an entity like "<" from b[src:] and writes the
|
||||
// corresponding "<" to b[dst:], returning the incremented dst and src cursors.
|
||||
// Precondition: b[src] == '&' && dst <= src.
|
||||
// attribute should be true if parsing an attribute value.
|
||||
func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
|
||||
|
||||
// i starts at 1 because we already know that s[0] == '&'.
|
||||
i, s := 1, b[src:]
|
||||
|
||||
if len(s) <= 1 {
|
||||
b[dst] = b[src]
|
||||
return dst + 1, src + 1
|
||||
}
|
||||
|
||||
if s[i] == '#' {
|
||||
if len(s) <= 3 { // We need to have at least "&#.".
|
||||
b[dst] = b[src]
|
||||
return dst + 1, src + 1
|
||||
}
|
||||
i++
|
||||
c := s[i]
|
||||
hex := false
|
||||
if c == 'x' || c == 'X' {
|
||||
hex = true
|
||||
i++
|
||||
}
|
||||
|
||||
x := '\x00'
|
||||
for i < len(s) {
|
||||
c = s[i]
|
||||
i++
|
||||
if hex {
|
||||
if '0' <= c && c <= '9' {
|
||||
x = 16*x + rune(c) - '0'
|
||||
continue
|
||||
} else if 'a' <= c && c <= 'f' {
|
||||
x = 16*x + rune(c) - 'a' + 10
|
||||
continue
|
||||
} else if 'A' <= c && c <= 'F' {
|
||||
x = 16*x + rune(c) - 'A' + 10
|
||||
continue
|
||||
}
|
||||
} else if '0' <= c && c <= '9' {
|
||||
x = 10*x + rune(c) - '0'
|
||||
continue
|
||||
}
|
||||
if c != ';' {
|
||||
i--
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if i <= 3 { // No characters matched.
|
||||
b[dst] = b[src]
|
||||
return dst + 1, src + 1
|
||||
}
|
||||
|
||||
if 0x80 <= x && x <= 0x9F {
|
||||
// Replace characters from Windows-1252 with UTF-8 equivalents.
|
||||
x = replacementTable[x-0x80]
|
||||
} else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF {
|
||||
// Replace invalid characters with the replacement character.
|
||||
x = '\uFFFD'
|
||||
}
|
||||
|
||||
return dst + utf8.EncodeRune(b[dst:], x), src + i
|
||||
}
|
||||
|
||||
// Consume the maximum number of characters possible, with the
|
||||
// consumed characters matching one of the named references.
|
||||
|
||||
for i < len(s) {
|
||||
c := s[i]
|
||||
i++
|
||||
// Lower-cased characters are more common in entities, so we check for them first.
|
||||
if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
|
||||
continue
|
||||
}
|
||||
if c != ';' {
|
||||
i--
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
entityName := string(s[1:i])
|
||||
if entityName == "" {
|
||||
// No-op.
|
||||
} else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' {
|
||||
// No-op.
|
||||
} else if x := entity[entityName]; x != 0 {
|
||||
return dst + utf8.EncodeRune(b[dst:], x), src + i
|
||||
} else if x := entity2[entityName]; x[0] != 0 {
|
||||
dst1 := dst + utf8.EncodeRune(b[dst:], x[0])
|
||||
return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i
|
||||
} else if !attribute {
|
||||
maxLen := len(entityName) - 1
|
||||
if maxLen > longestEntityWithoutSemicolon {
|
||||
maxLen = longestEntityWithoutSemicolon
|
||||
}
|
||||
for j := maxLen; j > 1; j-- {
|
||||
if x := entity[entityName[:j]]; x != 0 {
|
||||
return dst + utf8.EncodeRune(b[dst:], x), src + j + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dst1, src1 = dst+i, src+i
|
||||
copy(b[dst:dst1], b[src:src1])
|
||||
return dst1, src1
|
||||
}
|
||||
|
||||
// unescape unescapes b's entities in-place, so that "a<b" becomes "a<b".
|
||||
func unescape(b []byte) []byte {
|
||||
for i, c := range b {
|
||||
if c == '&' {
|
||||
dst, src := unescapeEntity(b, i, i, false)
|
||||
for src < len(b) {
|
||||
c := b[src]
|
||||
if c == '&' {
|
||||
dst, src = unescapeEntity(b, dst, src, false)
|
||||
} else {
|
||||
b[dst] = c
|
||||
dst, src = dst+1, src+1
|
||||
}
|
||||
}
|
||||
return b[0:dst]
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// lower lower-cases the A-Z bytes in b in-place, so that "aBc" becomes "abc".
|
||||
func lower(b []byte) []byte {
|
||||
for i, c := range b {
|
||||
if 'A' <= c && c <= 'Z' {
|
||||
b[i] = c + 'a' - 'A'
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
const escapedChars = `&'<>"`
|
||||
|
||||
func escape(w writer, s string) error {
|
||||
i := strings.IndexAny(s, escapedChars)
|
||||
for i != -1 {
|
||||
if _, err := w.WriteString(s[:i]); err != nil {
|
||||
return err
|
||||
}
|
||||
var esc string
|
||||
switch s[i] {
|
||||
case '&':
|
||||
esc = "&"
|
||||
case '\'':
|
||||
esc = "'"
|
||||
case '<':
|
||||
esc = "<"
|
||||
case '>':
|
||||
esc = ">"
|
||||
case '"':
|
||||
esc = """
|
||||
default:
|
||||
panic("unrecognized escape character")
|
||||
}
|
||||
s = s[i+1:]
|
||||
if _, err := w.WriteString(esc); err != nil {
|
||||
return err
|
||||
}
|
||||
i = strings.IndexAny(s, escapedChars)
|
||||
}
|
||||
_, err := w.WriteString(s)
|
||||
return err
|
||||
}
|
||||
|
||||
// EscapeString escapes special characters like "<" to become "<". It
|
||||
// escapes only five such characters: amp, apos, lt, gt and quot.
|
||||
// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
|
||||
// always true.
|
||||
func EscapeString(s string) string {
|
||||
if strings.IndexAny(s, escapedChars) == -1 {
|
||||
return s
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
escape(&buf, s)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// UnescapeString unescapes entities like "<" to become "<". It unescapes a
|
||||
// larger range of entities than EscapeString escapes. For example, "á"
|
||||
// unescapes to "á", as does "á" and "&xE1;".
|
||||
// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
|
||||
// always true.
|
||||
func UnescapeString(s string) string {
|
||||
for _, c := range s {
|
||||
if c == '&' {
|
||||
return string(unescape([]byte(s)))
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func adjustForeignAttributes(aa []Attribute) {
|
||||
for i, a := range aa {
|
||||
if a.Key == "" || a.Key[0] != 'x' {
|
||||
continue
|
||||
}
|
||||
switch a.Key {
|
||||
case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show",
|
||||
"xlink:title", "xlink:type", "xml:base", "xml:lang", "xml:space", "xmlns:xlink":
|
||||
j := strings.Index(a.Key, ":")
|
||||
aa[i].Namespace = a.Key[:j]
|
||||
aa[i].Key = a.Key[j+1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func htmlIntegrationPoint(n *Node) bool {
|
||||
if n.Type != ElementNode {
|
||||
return false
|
||||
}
|
||||
switch n.Namespace {
|
||||
case "math":
|
||||
// TODO: annotation-xml elements whose start tags have "text/html" or
|
||||
// "application/xhtml+xml" encodings.
|
||||
case "svg":
|
||||
switch n.Data {
|
||||
case "desc", "foreignObject", "title":
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Section 12.2.5.5.
|
||||
var breakout = map[string]bool{
|
||||
"b": true,
|
||||
"big": true,
|
||||
"blockquote": true,
|
||||
"body": true,
|
||||
"br": true,
|
||||
"center": true,
|
||||
"code": true,
|
||||
"dd": true,
|
||||
"div": true,
|
||||
"dl": true,
|
||||
"dt": true,
|
||||
"em": true,
|
||||
"embed": true,
|
||||
"font": true,
|
||||
"h1": true,
|
||||
"h2": true,
|
||||
"h3": true,
|
||||
"h4": true,
|
||||
"h5": true,
|
||||
"h6": true,
|
||||
"head": true,
|
||||
"hr": true,
|
||||
"i": true,
|
||||
"img": true,
|
||||
"li": true,
|
||||
"listing": true,
|
||||
"menu": true,
|
||||
"meta": true,
|
||||
"nobr": true,
|
||||
"ol": true,
|
||||
"p": true,
|
||||
"pre": true,
|
||||
"ruby": true,
|
||||
"s": true,
|
||||
"small": true,
|
||||
"span": true,
|
||||
"strong": true,
|
||||
"strike": true,
|
||||
"sub": true,
|
||||
"sup": true,
|
||||
"table": true,
|
||||
"tt": true,
|
||||
"u": true,
|
||||
"ul": true,
|
||||
"var": true,
|
||||
}
|
||||
|
||||
// Section 12.2.5.5.
|
||||
var svgTagNameAdjustments = map[string]string{
|
||||
"altglyph": "altGlyph",
|
||||
"altglyphdef": "altGlyphDef",
|
||||
"altglyphitem": "altGlyphItem",
|
||||
"animatecolor": "animateColor",
|
||||
"animatemotion": "animateMotion",
|
||||
"animatetransform": "animateTransform",
|
||||
"clippath": "clipPath",
|
||||
"feblend": "feBlend",
|
||||
"fecolormatrix": "feColorMatrix",
|
||||
"fecomponenttransfer": "feComponentTransfer",
|
||||
"fecomposite": "feComposite",
|
||||
"feconvolvematrix": "feConvolveMatrix",
|
||||
"fediffuselighting": "feDiffuseLighting",
|
||||
"fedisplacementmap": "feDisplacementMap",
|
||||
"fedistantlight": "feDistantLight",
|
||||
"feflood": "feFlood",
|
||||
"fefunca": "feFuncA",
|
||||
"fefuncb": "feFuncB",
|
||||
"fefuncg": "feFuncG",
|
||||
"fefuncr": "feFuncR",
|
||||
"fegaussianblur": "feGaussianBlur",
|
||||
"feimage": "feImage",
|
||||
"femerge": "feMerge",
|
||||
"femergenode": "feMergeNode",
|
||||
"femorphology": "feMorphology",
|
||||
"feoffset": "feOffset",
|
||||
"fepointlight": "fePointLight",
|
||||
"fespecularlighting": "feSpecularLighting",
|
||||
"fespotlight": "feSpotLight",
|
||||
"fetile": "feTile",
|
||||
"feturbulence": "feTurbulence",
|
||||
"foreignobject": "foreignObject",
|
||||
"glyphref": "glyphRef",
|
||||
"lineargradient": "linearGradient",
|
||||
"radialgradient": "radialGradient",
|
||||
"textpath": "textPath",
|
||||
}
|
||||
|
||||
// TODO: add look-up tables for MathML and SVG attribute adjustments.
|
||||
@@ -1,154 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
// A NodeType is the type of a Node.
|
||||
type NodeType int
|
||||
|
||||
const (
|
||||
ErrorNode NodeType = iota
|
||||
TextNode
|
||||
DocumentNode
|
||||
ElementNode
|
||||
CommentNode
|
||||
DoctypeNode
|
||||
scopeMarkerNode
|
||||
)
|
||||
|
||||
// Section 12.2.3.3 says "scope markers are inserted when entering applet
|
||||
// elements, buttons, object elements, marquees, table cells, and table
|
||||
// captions, and are used to prevent formatting from 'leaking'".
|
||||
var scopeMarker = Node{Type: scopeMarkerNode}
|
||||
|
||||
// A Node consists of a NodeType and some Data (tag name for element nodes,
|
||||
// content for text) and are part of a tree of Nodes. Element nodes may also
|
||||
// have a Namespace and contain a slice of Attributes. Data is unescaped, so
|
||||
// that it looks like "a<b" rather than "a<b".
|
||||
//
|
||||
// An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace.
|
||||
// Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and
|
||||
// "svg" is short for "http://www.w3.org/2000/svg".
|
||||
type Node struct {
|
||||
Parent *Node
|
||||
Child []*Node
|
||||
Type NodeType
|
||||
Data string
|
||||
Namespace string
|
||||
Attr []Attribute
|
||||
}
|
||||
|
||||
// Add adds a node as a child of n.
|
||||
// It will panic if the child's parent is not nil.
|
||||
func (n *Node) Add(child *Node) {
|
||||
if child.Parent != nil {
|
||||
panic("html: Node.Add called for a child Node that already has a parent")
|
||||
}
|
||||
child.Parent = n
|
||||
n.Child = append(n.Child, child)
|
||||
}
|
||||
|
||||
// Remove removes a node as a child of n.
|
||||
// It will panic if the child's parent is not n.
|
||||
func (n *Node) Remove(child *Node) {
|
||||
if child.Parent == n {
|
||||
child.Parent = nil
|
||||
for i, m := range n.Child {
|
||||
if m == child {
|
||||
copy(n.Child[i:], n.Child[i+1:])
|
||||
j := len(n.Child) - 1
|
||||
n.Child[j] = nil
|
||||
n.Child = n.Child[:j]
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
panic("html: Node.Remove called for a non-child Node")
|
||||
}
|
||||
|
||||
// reparentChildren reparents all of src's child nodes to dst.
|
||||
func reparentChildren(dst, src *Node) {
|
||||
for _, n := range src.Child {
|
||||
if n.Parent != src {
|
||||
panic("html: nodes have an inconsistent parent/child relationship")
|
||||
}
|
||||
n.Parent = dst
|
||||
}
|
||||
dst.Child = append(dst.Child, src.Child...)
|
||||
src.Child = nil
|
||||
}
|
||||
|
||||
// clone returns a new node with the same type, data and attributes.
|
||||
// The clone has no parent and no children.
|
||||
func (n *Node) clone() *Node {
|
||||
m := &Node{
|
||||
Type: n.Type,
|
||||
Data: n.Data,
|
||||
Attr: make([]Attribute, len(n.Attr)),
|
||||
}
|
||||
copy(m.Attr, n.Attr)
|
||||
return m
|
||||
}
|
||||
|
||||
// nodeStack is a stack of nodes.
|
||||
type nodeStack []*Node
|
||||
|
||||
// pop pops the stack. It will panic if s is empty.
|
||||
func (s *nodeStack) pop() *Node {
|
||||
i := len(*s)
|
||||
n := (*s)[i-1]
|
||||
*s = (*s)[:i-1]
|
||||
return n
|
||||
}
|
||||
|
||||
// top returns the most recently pushed node, or nil if s is empty.
|
||||
func (s *nodeStack) top() *Node {
|
||||
if i := len(*s); i > 0 {
|
||||
return (*s)[i-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// index returns the index of the top-most occurrence of n in the stack, or -1
|
||||
// if n is not present.
|
||||
func (s *nodeStack) index(n *Node) int {
|
||||
for i := len(*s) - 1; i >= 0; i-- {
|
||||
if (*s)[i] == n {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// insert inserts a node at the given index.
|
||||
func (s *nodeStack) insert(i int, n *Node) {
|
||||
(*s) = append(*s, nil)
|
||||
copy((*s)[i+1:], (*s)[i:])
|
||||
(*s)[i] = n
|
||||
}
|
||||
|
||||
// remove removes a node from the stack. It is a no-op if n is not present.
|
||||
func (s *nodeStack) remove(n *Node) {
|
||||
i := s.index(n)
|
||||
if i == -1 {
|
||||
return
|
||||
}
|
||||
copy((*s)[i:], (*s)[i+1:])
|
||||
j := len(*s) - 1
|
||||
(*s)[j] = nil
|
||||
*s = (*s)[:j]
|
||||
}
|
||||
|
||||
// TODO(nigeltao): forTag no longer used. Should it be deleted?
|
||||
|
||||
// forTag returns the top-most element node with the given tag.
|
||||
func (s *nodeStack) forTag(tag string) *Node {
|
||||
for i := len(*s) - 1; i >= 0; i-- {
|
||||
n := (*s)[i]
|
||||
if n.Type == ElementNode && n.Data == tag {
|
||||
return n
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,276 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// readParseTest reads a single test case from r.
|
||||
func readParseTest(r *bufio.Reader) (text, want, context string, err error) {
|
||||
line, err := r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
var b []byte
|
||||
|
||||
// Read the HTML.
|
||||
if string(line) != "#data\n" {
|
||||
return "", "", "", fmt.Errorf(`got %q want "#data\n"`, line)
|
||||
}
|
||||
for {
|
||||
line, err = r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
if line[0] == '#' {
|
||||
break
|
||||
}
|
||||
b = append(b, line...)
|
||||
}
|
||||
text = strings.TrimRight(string(b), "\n")
|
||||
b = b[:0]
|
||||
|
||||
// Skip the error list.
|
||||
if string(line) != "#errors\n" {
|
||||
return "", "", "", fmt.Errorf(`got %q want "#errors\n"`, line)
|
||||
}
|
||||
for {
|
||||
line, err = r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
if line[0] == '#' {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if string(line) == "#document-fragment\n" {
|
||||
line, err = r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
context = strings.TrimSpace(string(line))
|
||||
line, err = r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Read the dump of what the parse tree should be.
|
||||
if string(line) != "#document\n" {
|
||||
return "", "", "", fmt.Errorf(`got %q want "#document\n"`, line)
|
||||
}
|
||||
for {
|
||||
line, err = r.ReadSlice('\n')
|
||||
if err != nil && err != io.EOF {
|
||||
return "", "", "", err
|
||||
}
|
||||
if len(line) == 0 || len(line) == 1 && line[0] == '\n' {
|
||||
break
|
||||
}
|
||||
b = append(b, line...)
|
||||
}
|
||||
return text, string(b), context, nil
|
||||
}
|
||||
|
||||
func dumpIndent(w io.Writer, level int) {
|
||||
io.WriteString(w, "| ")
|
||||
for i := 0; i < level; i++ {
|
||||
io.WriteString(w, " ")
|
||||
}
|
||||
}
|
||||
|
||||
func dumpLevel(w io.Writer, n *Node, level int) error {
|
||||
dumpIndent(w, level)
|
||||
switch n.Type {
|
||||
case ErrorNode:
|
||||
return errors.New("unexpected ErrorNode")
|
||||
case DocumentNode:
|
||||
return errors.New("unexpected DocumentNode")
|
||||
case ElementNode:
|
||||
if n.Namespace != "" {
|
||||
fmt.Fprintf(w, "<%s %s>", n.Namespace, n.Data)
|
||||
} else {
|
||||
fmt.Fprintf(w, "<%s>", n.Data)
|
||||
}
|
||||
attr := n.Attr
|
||||
if len(attr) == 2 && attr[0].Namespace == "xml" && attr[1].Namespace == "xlink" {
|
||||
// Some of the test cases in tests10.dat change the order of adjusted
|
||||
// foreign attributes, but that behavior is not in the spec, and could
|
||||
// simply be an implementation detail of html5lib's python map ordering.
|
||||
attr[0], attr[1] = attr[1], attr[0]
|
||||
}
|
||||
for _, a := range attr {
|
||||
io.WriteString(w, "\n")
|
||||
dumpIndent(w, level+1)
|
||||
if a.Namespace != "" {
|
||||
fmt.Fprintf(w, `%s %s="%s"`, a.Namespace, a.Key, a.Val)
|
||||
} else {
|
||||
fmt.Fprintf(w, `%s="%s"`, a.Key, a.Val)
|
||||
}
|
||||
}
|
||||
case TextNode:
|
||||
fmt.Fprintf(w, `"%s"`, n.Data)
|
||||
case CommentNode:
|
||||
fmt.Fprintf(w, "<!-- %s -->", n.Data)
|
||||
case DoctypeNode:
|
||||
fmt.Fprintf(w, "<!DOCTYPE %s", n.Data)
|
||||
if n.Attr != nil {
|
||||
var p, s string
|
||||
for _, a := range n.Attr {
|
||||
switch a.Key {
|
||||
case "public":
|
||||
p = a.Val
|
||||
case "system":
|
||||
s = a.Val
|
||||
}
|
||||
}
|
||||
if p != "" || s != "" {
|
||||
fmt.Fprintf(w, ` "%s"`, p)
|
||||
fmt.Fprintf(w, ` "%s"`, s)
|
||||
}
|
||||
}
|
||||
io.WriteString(w, ">")
|
||||
case scopeMarkerNode:
|
||||
return errors.New("unexpected scopeMarkerNode")
|
||||
default:
|
||||
return errors.New("unknown node type")
|
||||
}
|
||||
io.WriteString(w, "\n")
|
||||
for _, c := range n.Child {
|
||||
if err := dumpLevel(w, c, level+1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func dump(n *Node) (string, error) {
|
||||
if n == nil || len(n.Child) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
var b bytes.Buffer
|
||||
for _, child := range n.Child {
|
||||
if err := dumpLevel(&b, child, 0); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
testFiles := []struct {
|
||||
filename string
|
||||
// n is the number of test cases to run from that file.
|
||||
// -1 means all test cases.
|
||||
n int
|
||||
}{
|
||||
// TODO(nigeltao): Process all the test cases from all the .dat files.
|
||||
{"adoption01.dat", -1},
|
||||
{"doctype01.dat", -1},
|
||||
{"tests1.dat", -1},
|
||||
{"tests2.dat", -1},
|
||||
{"tests3.dat", -1},
|
||||
{"tests4.dat", -1},
|
||||
{"tests5.dat", -1},
|
||||
{"tests6.dat", -1},
|
||||
{"tests10.dat", 35},
|
||||
}
|
||||
for _, tf := range testFiles {
|
||||
f, err := os.Open("testdata/webkit/" + tf.filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
r := bufio.NewReader(f)
|
||||
for i := 0; i != tf.n; i++ {
|
||||
text, want, context, err := readParseTest(r)
|
||||
if err == io.EOF && tf.n == -1 {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var doc *Node
|
||||
if context == "" {
|
||||
doc, err = Parse(strings.NewReader(text))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
contextNode := &Node{
|
||||
Type: ElementNode,
|
||||
Data: context,
|
||||
}
|
||||
nodes, err := ParseFragment(strings.NewReader(text), contextNode)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
doc = &Node{
|
||||
Type: DocumentNode,
|
||||
}
|
||||
for _, n := range nodes {
|
||||
doc.Add(n)
|
||||
}
|
||||
}
|
||||
|
||||
got, err := dump(doc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Compare the parsed tree to the #document section.
|
||||
if got != want {
|
||||
t.Errorf("%s test #%d %q, got vs want:\n----\n%s----\n%s----", tf.filename, i, text, got, want)
|
||||
continue
|
||||
}
|
||||
if renderTestBlacklist[text] || context != "" {
|
||||
continue
|
||||
}
|
||||
// Check that rendering and re-parsing results in an identical tree.
|
||||
pr, pw := io.Pipe()
|
||||
go func() {
|
||||
pw.CloseWithError(Render(pw, doc))
|
||||
}()
|
||||
doc1, err := Parse(pr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got1, err := dump(doc1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got != got1 {
|
||||
t.Errorf("%s test #%d %q, got vs got1:\n----\n%s----\n%s----", tf.filename, i, text, got, got1)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Some test input result in parse trees are not 'well-formed' despite
|
||||
// following the HTML5 recovery algorithms. Rendering and re-parsing such a
|
||||
// tree will not result in an exact clone of that tree. We blacklist such
|
||||
// inputs from the render test.
|
||||
var renderTestBlacklist = map[string]bool{
|
||||
// The second <a> will be reparented to the first <table>'s parent. This
|
||||
// results in an <a> whose parent is an <a>, which is not 'well-formed'.
|
||||
`<a><table><td><a><table></table><a></tr><a></table><b>X</b>C<a>Y`: true,
|
||||
// More cases of <a> being reparented:
|
||||
`<a href="blah">aba<table><a href="foo">br<tr><td></td></tr>x</table>aoe`: true,
|
||||
`<a><table><a></table><p><a><div><a>`: true,
|
||||
`<a><table><td><a><table></table><a></tr><a></table><a>`: true,
|
||||
// A <plaintext> element is reparented, putting it before a table.
|
||||
// A <plaintext> element can't have anything after it in HTML.
|
||||
`<table><plaintext><td>`: true,
|
||||
}
|
||||
@@ -1,277 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type writer interface {
|
||||
io.Writer
|
||||
WriteByte(byte) error
|
||||
WriteString(string) (int, error)
|
||||
}
|
||||
|
||||
// Render renders the parse tree n to the given writer.
|
||||
//
|
||||
// Rendering is done on a 'best effort' basis: calling Parse on the output of
|
||||
// Render will always result in something similar to the original tree, but it
|
||||
// is not necessarily an exact clone unless the original tree was 'well-formed'.
|
||||
// 'Well-formed' is not easily specified; the HTML5 specification is
|
||||
// complicated.
|
||||
//
|
||||
// Calling Parse on arbitrary input typically results in a 'well-formed' parse
|
||||
// tree. However, it is possible for Parse to yield a 'badly-formed' parse tree.
|
||||
// For example, in a 'well-formed' parse tree, no <a> element is a child of
|
||||
// another <a> element: parsing "<a><a>" results in two sibling elements.
|
||||
// Similarly, in a 'well-formed' parse tree, no <a> element is a child of a
|
||||
// <table> element: parsing "<p><table><a>" results in a <p> with two sibling
|
||||
// children; the <a> is reparented to the <table>'s parent. However, calling
|
||||
// Parse on "<a><table><a>" does not return an error, but the result has an <a>
|
||||
// element with an <a> child, and is therefore not 'well-formed'.
|
||||
//
|
||||
// Programmatically constructed trees are typically also 'well-formed', but it
|
||||
// is possible to construct a tree that looks innocuous but, when rendered and
|
||||
// re-parsed, results in a different tree. A simple example is that a solitary
|
||||
// text node would become a tree containing <html>, <head> and <body> elements.
|
||||
// Another example is that the programmatic equivalent of "a<head>b</head>c"
|
||||
// becomes "<html><head><head/><body>abc</body></html>".
|
||||
func Render(w io.Writer, n *Node) error {
|
||||
if x, ok := w.(writer); ok {
|
||||
return render(x, n)
|
||||
}
|
||||
buf := bufio.NewWriter(w)
|
||||
if err := render(buf, n); err != nil {
|
||||
return err
|
||||
}
|
||||
return buf.Flush()
|
||||
}
|
||||
|
||||
// plaintextAbort is returned from render1 when a <plaintext> element
|
||||
// has been rendered. No more end tags should be rendered after that.
|
||||
var plaintextAbort = errors.New("html: internal error (plaintext abort)")
|
||||
|
||||
func render(w writer, n *Node) error {
|
||||
err := render1(w, n)
|
||||
if err == plaintextAbort {
|
||||
err = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func render1(w writer, n *Node) error {
|
||||
// Render non-element nodes; these are the easy cases.
|
||||
switch n.Type {
|
||||
case ErrorNode:
|
||||
return errors.New("html: cannot render an ErrorNode node")
|
||||
case TextNode:
|
||||
return escape(w, n.Data)
|
||||
case DocumentNode:
|
||||
for _, c := range n.Child {
|
||||
if err := render1(w, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case ElementNode:
|
||||
// No-op.
|
||||
case CommentNode:
|
||||
if _, err := w.WriteString("<!--"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(n.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString("-->"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case DoctypeNode:
|
||||
if _, err := w.WriteString("<!DOCTYPE "); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(n.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
if n.Attr != nil {
|
||||
var p, s string
|
||||
for _, a := range n.Attr {
|
||||
switch a.Key {
|
||||
case "public":
|
||||
p = a.Val
|
||||
case "system":
|
||||
s = a.Val
|
||||
}
|
||||
}
|
||||
if p != "" {
|
||||
if _, err := w.WriteString(" PUBLIC "); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeQuoted(w, p); err != nil {
|
||||
return err
|
||||
}
|
||||
if s != "" {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeQuoted(w, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if s != "" {
|
||||
if _, err := w.WriteString(" SYSTEM "); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeQuoted(w, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return w.WriteByte('>')
|
||||
default:
|
||||
return errors.New("html: unknown node type")
|
||||
}
|
||||
|
||||
// Render the <xxx> opening tag.
|
||||
if err := w.WriteByte('<'); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(n.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, a := range n.Attr {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
if a.Namespace != "" {
|
||||
if _, err := w.WriteString(a.Namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte(':'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := w.WriteString(a.Key); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(`="`); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := escape(w, a.Val); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('"'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if voidElements[n.Data] {
|
||||
if len(n.Child) != 0 {
|
||||
return fmt.Errorf("html: void element <%s> has child nodes", n.Data)
|
||||
}
|
||||
_, err := w.WriteString("/>")
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('>'); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add initial newline where there is danger of a newline beging ignored.
|
||||
if len(n.Child) > 0 && n.Child[0].Type == TextNode && strings.HasPrefix(n.Child[0].Data, "\n") {
|
||||
switch n.Data {
|
||||
case "pre", "listing", "textarea":
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render any child nodes.
|
||||
switch n.Data {
|
||||
case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp":
|
||||
for _, c := range n.Child {
|
||||
if c.Type != TextNode {
|
||||
return fmt.Errorf("html: raw text element <%s> has non-text child node", n.Data)
|
||||
}
|
||||
if _, err := w.WriteString(c.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if n.Data == "plaintext" {
|
||||
// Don't render anything else. <plaintext> must be the
|
||||
// last element in the file, with no closing tag.
|
||||
return plaintextAbort
|
||||
}
|
||||
case "textarea", "title":
|
||||
for _, c := range n.Child {
|
||||
if c.Type != TextNode {
|
||||
return fmt.Errorf("html: RCDATA element <%s> has non-text child node", n.Data)
|
||||
}
|
||||
if err := render1(w, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
default:
|
||||
for _, c := range n.Child {
|
||||
if err := render1(w, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render the </xxx> closing tag.
|
||||
if _, err := w.WriteString("</"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(n.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
return w.WriteByte('>')
|
||||
}
|
||||
|
||||
// writeQuoted writes s to w surrounded by quotes. Normally it will use double
|
||||
// quotes, but if s contains a double quote, it will use single quotes.
|
||||
// It is used for writing the identifiers in a doctype declaration.
|
||||
// In valid HTML, they can't contain both types of quotes.
|
||||
func writeQuoted(w writer, s string) error {
|
||||
var q byte = '"'
|
||||
if strings.Contains(s, `"`) {
|
||||
q = '\''
|
||||
}
|
||||
if err := w.WriteByte(q); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte(q); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Section 12.1.2, "Elements", gives this list of void elements. Void elements
|
||||
// are those that can't have any contents.
|
||||
var voidElements = map[string]bool{
|
||||
"area": true,
|
||||
"base": true,
|
||||
"br": true,
|
||||
"col": true,
|
||||
"command": true,
|
||||
"embed": true,
|
||||
"hr": true,
|
||||
"img": true,
|
||||
"input": true,
|
||||
"keygen": true,
|
||||
"link": true,
|
||||
"meta": true,
|
||||
"param": true,
|
||||
"source": true,
|
||||
"track": true,
|
||||
"wbr": true,
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package html
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRenderer(t *testing.T) {
|
||||
n := &Node{
|
||||
Type: ElementNode,
|
||||
Data: "html",
|
||||
Child: []*Node{
|
||||
{
|
||||
Type: ElementNode,
|
||||
Data: "head",
|
||||
},
|
||||
{
|
||||
Type: ElementNode,
|
||||
Data: "body",
|
||||
Child: []*Node{
|
||||
{
|
||||
Type: TextNode,
|
||||
Data: "0<1",
|
||||
},
|
||||
{
|
||||
Type: ElementNode,
|
||||
Data: "p",
|
||||
Attr: []Attribute{
|
||||
{
|
||||
Key: "id",
|
||||
Val: "A",
|
||||
},
|
||||
{
|
||||
Key: "foo",
|
||||
Val: `abc"def`,
|
||||
},
|
||||
},
|
||||
Child: []*Node{
|
||||
{
|
||||
Type: TextNode,
|
||||
Data: "2",
|
||||
},
|
||||
{
|
||||
Type: ElementNode,
|
||||
Data: "b",
|
||||
Attr: []Attribute{
|
||||
{
|
||||
Key: "empty",
|
||||
Val: "",
|
||||
},
|
||||
},
|
||||
Child: []*Node{
|
||||
{
|
||||
Type: TextNode,
|
||||
Data: "3",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: ElementNode,
|
||||
Data: "i",
|
||||
Attr: []Attribute{
|
||||
{
|
||||
Key: "backslash",
|
||||
Val: `\`,
|
||||
},
|
||||
},
|
||||
Child: []*Node{
|
||||
{
|
||||
Type: TextNode,
|
||||
Data: "&4",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: TextNode,
|
||||
Data: "5",
|
||||
},
|
||||
{
|
||||
Type: ElementNode,
|
||||
Data: "blockquote",
|
||||
},
|
||||
{
|
||||
Type: ElementNode,
|
||||
Data: "br",
|
||||
},
|
||||
{
|
||||
Type: TextNode,
|
||||
Data: "6",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
want := `<html><head></head><body>0<1<p id="A" foo="abc"def">` +
|
||||
`2<b empty="">3</b><i backslash="\">&4</i></p>` +
|
||||
`5<blockquote></blockquote><br/>6</body></html>`
|
||||
b := new(bytes.Buffer)
|
||||
if err := Render(b, n); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := b.String(); got != want {
|
||||
t.Errorf("got vs want:\n%s\n%s\n", got, want)
|
||||
}
|
||||
}
|
||||
28
src/pkg/exp/html/testdata/webkit/README
vendored
28
src/pkg/exp/html/testdata/webkit/README
vendored
@@ -1,28 +0,0 @@
|
||||
The *.dat files in this directory are copied from The WebKit Open Source
|
||||
Project, specifically $WEBKITROOT/LayoutTests/html5lib/resources.
|
||||
WebKit is licensed under a BSD style license.
|
||||
http://webkit.org/coding/bsd-license.html says:
|
||||
|
||||
Copyright (C) 2009 Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
194
src/pkg/exp/html/testdata/webkit/adoption01.dat
vendored
194
src/pkg/exp/html/testdata/webkit/adoption01.dat
vendored
@@ -1,194 +0,0 @@
|
||||
#data
|
||||
<a><p></a></p>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| <p>
|
||||
| <a>
|
||||
|
||||
#data
|
||||
<a>1<p>2</a>3</p>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| "1"
|
||||
| <p>
|
||||
| <a>
|
||||
| "2"
|
||||
| "3"
|
||||
|
||||
#data
|
||||
<a>1<button>2</a>3</button>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| "1"
|
||||
| <button>
|
||||
| <a>
|
||||
| "2"
|
||||
| "3"
|
||||
|
||||
#data
|
||||
<a>1<b>2</a>3</b>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| "1"
|
||||
| <b>
|
||||
| "2"
|
||||
| <b>
|
||||
| "3"
|
||||
|
||||
#data
|
||||
<a>1<div>2<div>3</a>4</div>5</div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| "1"
|
||||
| <div>
|
||||
| <a>
|
||||
| "2"
|
||||
| <div>
|
||||
| <a>
|
||||
| "3"
|
||||
| "4"
|
||||
| "5"
|
||||
|
||||
#data
|
||||
<table><a>1<p>2</a>3</p>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| "1"
|
||||
| <p>
|
||||
| <a>
|
||||
| "2"
|
||||
| "3"
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<b><b><a><p></a>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <b>
|
||||
| <b>
|
||||
| <a>
|
||||
| <p>
|
||||
| <a>
|
||||
|
||||
#data
|
||||
<b><a><b><p></a>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <b>
|
||||
| <a>
|
||||
| <b>
|
||||
| <b>
|
||||
| <p>
|
||||
| <a>
|
||||
|
||||
#data
|
||||
<a><b><b><p></a>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| <b>
|
||||
| <b>
|
||||
| <b>
|
||||
| <b>
|
||||
| <p>
|
||||
| <a>
|
||||
|
||||
#data
|
||||
<p>1<s id="A">2<b id="B">3</p>4</s>5</b>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <p>
|
||||
| "1"
|
||||
| <s>
|
||||
| id="A"
|
||||
| "2"
|
||||
| <b>
|
||||
| id="B"
|
||||
| "3"
|
||||
| <s>
|
||||
| id="A"
|
||||
| <b>
|
||||
| id="B"
|
||||
| "4"
|
||||
| <b>
|
||||
| id="B"
|
||||
| "5"
|
||||
|
||||
#data
|
||||
<table><a>1<td>2</td>3</table>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| "1"
|
||||
| <a>
|
||||
| "3"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| "2"
|
||||
|
||||
#data
|
||||
<table>A<td>B</td>C</table>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "AC"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| "B"
|
||||
|
||||
#data
|
||||
<a><svg><tr><input></a>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| <svg svg>
|
||||
| <svg tr>
|
||||
| <svg input>
|
||||
31
src/pkg/exp/html/testdata/webkit/adoption02.dat
vendored
31
src/pkg/exp/html/testdata/webkit/adoption02.dat
vendored
@@ -1,31 +0,0 @@
|
||||
#data
|
||||
<b>1<i>2<p>3</b>4
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <b>
|
||||
| "1"
|
||||
| <i>
|
||||
| "2"
|
||||
| <i>
|
||||
| <p>
|
||||
| <b>
|
||||
| "3"
|
||||
| "4"
|
||||
|
||||
#data
|
||||
<a><div><style></style><address><a>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| <div>
|
||||
| <a>
|
||||
| <style>
|
||||
| <address>
|
||||
| <a>
|
||||
| <a>
|
||||
135
src/pkg/exp/html/testdata/webkit/comments01.dat
vendored
135
src/pkg/exp/html/testdata/webkit/comments01.dat
vendored
@@ -1,135 +0,0 @@
|
||||
#data
|
||||
FOO<!-- BAR -->BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- BAR -->
|
||||
| "BAZ"
|
||||
|
||||
#data
|
||||
FOO<!-- BAR --!>BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- BAR -->
|
||||
| "BAZ"
|
||||
|
||||
#data
|
||||
FOO<!-- BAR -- >BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- BAR -- >BAZ -->
|
||||
|
||||
#data
|
||||
FOO<!-- BAR -- <QUX> -- MUX -->BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- BAR -- <QUX> -- MUX -->
|
||||
| "BAZ"
|
||||
|
||||
#data
|
||||
FOO<!-- BAR -- <QUX> -- MUX --!>BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- BAR -- <QUX> -- MUX -->
|
||||
| "BAZ"
|
||||
|
||||
#data
|
||||
FOO<!-- BAR -- <QUX> -- MUX -- >BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- BAR -- <QUX> -- MUX -- >BAZ -->
|
||||
|
||||
#data
|
||||
FOO<!---->BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- -->
|
||||
| "BAZ"
|
||||
|
||||
#data
|
||||
FOO<!--->BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- -->
|
||||
| "BAZ"
|
||||
|
||||
#data
|
||||
FOO<!-->BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- -->
|
||||
| "BAZ"
|
||||
|
||||
#data
|
||||
<?xml version="1.0">Hi
|
||||
#errors
|
||||
#document
|
||||
| <!-- ?xml version="1.0" -->
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hi"
|
||||
|
||||
#data
|
||||
<?xml version="1.0">
|
||||
#errors
|
||||
#document
|
||||
| <!-- ?xml version="1.0" -->
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<?xml version
|
||||
#errors
|
||||
#document
|
||||
| <!-- ?xml version -->
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
FOO<!----->BAZ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <!-- - -->
|
||||
| "BAZ"
|
||||
370
src/pkg/exp/html/testdata/webkit/doctype01.dat
vendored
370
src/pkg/exp/html/testdata/webkit/doctype01.dat
vendored
@@ -1,370 +0,0 @@
|
||||
#data
|
||||
<!DOCTYPE html>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!dOctYpE HtMl>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPEhtml>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE >
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE >Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE >
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato >Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato taco>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato taco "ddd>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato sYstEM>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato sYstEM >Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato sYstEM ggg>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato SYSTEM taco >Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato SYSTEM 'taco"'>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato "" "taco"">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato SYSTEM "taco">Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato "" "taco">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato SYSTEM "tai'co">Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato "" "tai'co">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato SYSTEMtaco "ddd">Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato grass SYSTEM taco>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato pUbLIc>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato pUbLIc >Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato pUbLIcgoof>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato PUBLIC goof>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato PUBLIC "go'of">Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato "go'of" "">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato PUBLIC 'go'of'>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato "go" "">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato PUBLIC 'go:hh of' >Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato "go:hh of" "">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE potato PUBLIC "W3C-//dfdf" SYSTEM ggg>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE potato "W3C-//dfdf" "">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE ...>Hello
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE ...>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "Hello"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE root-element [SYSTEM OR PUBLIC FPI] "uri" [
|
||||
<!-- internal declarations -->
|
||||
]>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE root-element>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "]>"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html PUBLIC
|
||||
"-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
|
||||
"http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE HTML SYSTEM "http://www.w3.org/DTD/HTML4-strict.dtd"><body><b>Mine!</b></body>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "" "http://www.w3.org/DTD/HTML4-strict.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <b>
|
||||
| "Mine!"
|
||||
|
||||
#data
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"'http://www.w3.org/TR/html4/strict.dtd'>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01//EN"'http://www.w3.org/TR/html4/strict.dtd'>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE HTML PUBLIC'-//W3C//DTD HTML 4.01//EN''http://www.w3.org/TR/html4/strict.dtd'>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
603
src/pkg/exp/html/testdata/webkit/entities01.dat
vendored
603
src/pkg/exp/html/testdata/webkit/entities01.dat
vendored
@@ -1,603 +0,0 @@
|
||||
#data
|
||||
FOO>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO>BAR"
|
||||
|
||||
#data
|
||||
FOO>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO>BAR"
|
||||
|
||||
#data
|
||||
FOO> BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO> BAR"
|
||||
|
||||
#data
|
||||
FOO>;;BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO>;;BAR"
|
||||
|
||||
#data
|
||||
I'm ¬it; I tell you
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "I'm ¬it; I tell you"
|
||||
|
||||
#data
|
||||
I'm ∉ I tell you
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "I'm ∉ I tell you"
|
||||
|
||||
#data
|
||||
FOO& BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO& BAR"
|
||||
|
||||
#data
|
||||
FOO&<BAR>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO&"
|
||||
| <bar>
|
||||
|
||||
#data
|
||||
FOO&&&>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO&&&>BAR"
|
||||
|
||||
#data
|
||||
FOO)BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO)BAR"
|
||||
|
||||
#data
|
||||
FOOABAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOABAR"
|
||||
|
||||
#data
|
||||
FOOABAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOABAR"
|
||||
|
||||
#data
|
||||
FOO&#BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO&#BAR"
|
||||
|
||||
#data
|
||||
FOO&#ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO&#ZOO"
|
||||
|
||||
#data
|
||||
FOOºR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOºR"
|
||||
|
||||
#data
|
||||
FOO&#xZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO&#xZOO"
|
||||
|
||||
#data
|
||||
FOO&#XZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO&#XZOO"
|
||||
|
||||
#data
|
||||
FOO)BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO)BAR"
|
||||
|
||||
#data
|
||||
FOO䆺R
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO䆺R"
|
||||
|
||||
#data
|
||||
FOOAZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOAZOO"
|
||||
|
||||
#data
|
||||
FOO�ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO<4F>ZOO"
|
||||
|
||||
#data
|
||||
FOOxZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOxZOO"
|
||||
|
||||
#data
|
||||
FOOyZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOyZOO"
|
||||
|
||||
#data
|
||||
FOO€ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO€ZOO"
|
||||
|
||||
#data
|
||||
FOOZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOO‚ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO‚ZOO"
|
||||
|
||||
#data
|
||||
FOOƒZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOƒZOO"
|
||||
|
||||
#data
|
||||
FOO„ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO„ZOO"
|
||||
|
||||
#data
|
||||
FOO…ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO…ZOO"
|
||||
|
||||
#data
|
||||
FOO†ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO†ZOO"
|
||||
|
||||
#data
|
||||
FOO‡ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO‡ZOO"
|
||||
|
||||
#data
|
||||
FOOˆZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOˆZOO"
|
||||
|
||||
#data
|
||||
FOO‰ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO‰ZOO"
|
||||
|
||||
#data
|
||||
FOOŠZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOŠZOO"
|
||||
|
||||
#data
|
||||
FOO‹ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO‹ZOO"
|
||||
|
||||
#data
|
||||
FOOŒZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOŒZOO"
|
||||
|
||||
#data
|
||||
FOOZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOOŽZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOŽZOO"
|
||||
|
||||
#data
|
||||
FOOZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOOZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOO‘ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO‘ZOO"
|
||||
|
||||
#data
|
||||
FOO’ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO’ZOO"
|
||||
|
||||
#data
|
||||
FOO“ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO“ZOO"
|
||||
|
||||
#data
|
||||
FOO”ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO”ZOO"
|
||||
|
||||
#data
|
||||
FOO•ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO•ZOO"
|
||||
|
||||
#data
|
||||
FOO–ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO–ZOO"
|
||||
|
||||
#data
|
||||
FOO—ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO—ZOO"
|
||||
|
||||
#data
|
||||
FOO˜ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO˜ZOO"
|
||||
|
||||
#data
|
||||
FOO™ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO™ZOO"
|
||||
|
||||
#data
|
||||
FOOšZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOšZOO"
|
||||
|
||||
#data
|
||||
FOO›ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO›ZOO"
|
||||
|
||||
#data
|
||||
FOOœZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOœZOO"
|
||||
|
||||
#data
|
||||
FOOZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOOžZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOžZOO"
|
||||
|
||||
#data
|
||||
FOOŸZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOŸZOO"
|
||||
|
||||
#data
|
||||
FOO ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO ZOO"
|
||||
|
||||
#data
|
||||
FOO퟿ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOO�ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO<4F>ZOO"
|
||||
|
||||
#data
|
||||
FOO�ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO<4F>ZOO"
|
||||
|
||||
#data
|
||||
FOO�ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO<4F>ZOO"
|
||||
|
||||
#data
|
||||
FOO�ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO<4F>ZOO"
|
||||
|
||||
#data
|
||||
FOOZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOOZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOO􈟔ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOOZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOOZOO"
|
||||
|
||||
#data
|
||||
FOO�ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO<4F>ZOO"
|
||||
|
||||
#data
|
||||
FOO�ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO<4F>ZOO"
|
||||
249
src/pkg/exp/html/testdata/webkit/entities02.dat
vendored
249
src/pkg/exp/html/testdata/webkit/entities02.dat
vendored
@@ -1,249 +0,0 @@
|
||||
#data
|
||||
<div bar="ZZ>YY"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>YY"
|
||||
|
||||
#data
|
||||
<div bar="ZZ&"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ&"
|
||||
|
||||
#data
|
||||
<div bar='ZZ&'></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ&"
|
||||
|
||||
#data
|
||||
<div bar=ZZ&></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ&"
|
||||
|
||||
#data
|
||||
<div bar="ZZ>=YY"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>=YY"
|
||||
|
||||
#data
|
||||
<div bar="ZZ>0YY"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>0YY"
|
||||
|
||||
#data
|
||||
<div bar="ZZ>9YY"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>9YY"
|
||||
|
||||
#data
|
||||
<div bar="ZZ>aYY"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>aYY"
|
||||
|
||||
#data
|
||||
<div bar="ZZ>ZYY"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>ZYY"
|
||||
|
||||
#data
|
||||
<div bar="ZZ> YY"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ> YY"
|
||||
|
||||
#data
|
||||
<div bar="ZZ>"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>"
|
||||
|
||||
#data
|
||||
<div bar='ZZ>'></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>"
|
||||
|
||||
#data
|
||||
<div bar=ZZ>></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ>"
|
||||
|
||||
#data
|
||||
<div bar="ZZ£_id=23"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ£_id=23"
|
||||
|
||||
#data
|
||||
<div bar="ZZ&prod_id=23"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ&prod_id=23"
|
||||
|
||||
#data
|
||||
<div bar="ZZ£_id=23"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ£_id=23"
|
||||
|
||||
#data
|
||||
<div bar="ZZ∏_id=23"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ∏_id=23"
|
||||
|
||||
#data
|
||||
<div bar="ZZ£=23"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ£=23"
|
||||
|
||||
#data
|
||||
<div bar="ZZ&prod=23"></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| bar="ZZ&prod=23"
|
||||
|
||||
#data
|
||||
<div>ZZ£_id=23</div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| "ZZ£_id=23"
|
||||
|
||||
#data
|
||||
<div>ZZ&prod_id=23</div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| "ZZ&prod_id=23"
|
||||
|
||||
#data
|
||||
<div>ZZ£_id=23</div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| "ZZ£_id=23"
|
||||
|
||||
#data
|
||||
<div>ZZ∏_id=23</div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| "ZZ∏_id=23"
|
||||
|
||||
#data
|
||||
<div>ZZ£=23</div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| "ZZ£=23"
|
||||
|
||||
#data
|
||||
<div>ZZ&prod=23</div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| "ZZ&prod=23"
|
||||
246
src/pkg/exp/html/testdata/webkit/html5test-com.dat
vendored
246
src/pkg/exp/html/testdata/webkit/html5test-com.dat
vendored
@@ -1,246 +0,0 @@
|
||||
#data
|
||||
<div<div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div<div>
|
||||
|
||||
#data
|
||||
<div foo<bar=''>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| foo<bar=""
|
||||
|
||||
#data
|
||||
<div foo=`bar`>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| foo="`bar`"
|
||||
|
||||
#data
|
||||
<div \"foo=''>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| \"foo=""
|
||||
|
||||
#data
|
||||
<a href='\nbar'></a>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <a>
|
||||
| href="\nbar"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
⟨⟩
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "⟨⟩"
|
||||
|
||||
#data
|
||||
'
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "'"
|
||||
|
||||
#data
|
||||
ⅈ
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "ⅈ"
|
||||
|
||||
#data
|
||||
𝕂
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "𝕂"
|
||||
|
||||
#data
|
||||
∉
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "∉"
|
||||
|
||||
#data
|
||||
<?import namespace="foo" implementation="#bar">
|
||||
#errors
|
||||
#document
|
||||
| <!-- ?import namespace="foo" implementation="#bar" -->
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!--foo--bar-->
|
||||
#errors
|
||||
#document
|
||||
| <!-- foo--bar -->
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<![CDATA[x]]>
|
||||
#errors
|
||||
#document
|
||||
| <!-- [CDATA[x]] -->
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<textarea><!--</textarea>--></textarea>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <textarea>
|
||||
| "<!--"
|
||||
| "-->"
|
||||
|
||||
#data
|
||||
<textarea><!--</textarea>-->
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <textarea>
|
||||
| "<!--"
|
||||
| "-->"
|
||||
|
||||
#data
|
||||
<style><!--</style>--></style>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <style>
|
||||
| "<!--"
|
||||
| <body>
|
||||
| "-->"
|
||||
|
||||
#data
|
||||
<style><!--</style>-->
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <style>
|
||||
| "<!--"
|
||||
| <body>
|
||||
| "-->"
|
||||
|
||||
#data
|
||||
<ul><li>A </li> <li>B</li></ul>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ul>
|
||||
| <li>
|
||||
| "A "
|
||||
| " "
|
||||
| <li>
|
||||
| "B"
|
||||
|
||||
#data
|
||||
<table><form><input type=hidden><input></form><div></div></table>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <input>
|
||||
| <div>
|
||||
| <table>
|
||||
| <form>
|
||||
| <input>
|
||||
| type="hidden"
|
||||
|
||||
#data
|
||||
<i>A<b>B<p></i>C</b>D
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <i>
|
||||
| "A"
|
||||
| <b>
|
||||
| "B"
|
||||
| <b>
|
||||
| <p>
|
||||
| <b>
|
||||
| <i>
|
||||
| "C"
|
||||
| "D"
|
||||
|
||||
#data
|
||||
<div></div>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
|
||||
#data
|
||||
<svg></svg>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
|
||||
#data
|
||||
<math></math>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
43
src/pkg/exp/html/testdata/webkit/inbody01.dat
vendored
43
src/pkg/exp/html/testdata/webkit/inbody01.dat
vendored
@@ -1,43 +0,0 @@
|
||||
#data
|
||||
<button>1</foo>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <button>
|
||||
| "1"
|
||||
|
||||
#data
|
||||
<foo>1<p>2</foo>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <foo>
|
||||
| "1"
|
||||
| <p>
|
||||
| "2"
|
||||
|
||||
#data
|
||||
<dd>1</foo>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <dd>
|
||||
| "1"
|
||||
|
||||
#data
|
||||
<foo>1<dd>2</foo>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <foo>
|
||||
| "1"
|
||||
| <dd>
|
||||
| "2"
|
||||
40
src/pkg/exp/html/testdata/webkit/isindex.dat
vendored
40
src/pkg/exp/html/testdata/webkit/isindex.dat
vendored
@@ -1,40 +0,0 @@
|
||||
#data
|
||||
<isindex>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <form>
|
||||
| <hr>
|
||||
| <label>
|
||||
| "This is a searchable index. Enter search keywords: "
|
||||
| <input>
|
||||
| name="isindex"
|
||||
| <hr>
|
||||
|
||||
#data
|
||||
<isindex name="A" action="B" prompt="C" foo="D">
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <form>
|
||||
| action="B"
|
||||
| <hr>
|
||||
| <label>
|
||||
| "C"
|
||||
| <input>
|
||||
| foo="D"
|
||||
| name="isindex"
|
||||
| <hr>
|
||||
|
||||
#data
|
||||
<form><isindex>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <form>
|
||||
Binary file not shown.
@@ -1,28 +0,0 @@
|
||||
#data
|
||||
<input type="hidden"><frameset>
|
||||
#errors
|
||||
21: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
|
||||
31: “frameset” start tag seen.
|
||||
31: End of file seen and there were open elements.
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><table><caption><svg>foo</table>bar
|
||||
#errors
|
||||
47: End tag “table” did not match the name of the current open element (“svg”).
|
||||
47: “table” closed but “caption” was still open.
|
||||
47: End tag “table” seen, but there were open elements.
|
||||
36: Unclosed element “svg”.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <caption>
|
||||
| <svg svg>
|
||||
| "foo"
|
||||
| "bar"
|
||||
@@ -1,8 +0,0 @@
|
||||
#data
|
||||
FOO
ZOO
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO
|
||||
308
src/pkg/exp/html/testdata/webkit/scriptdata01.dat
vendored
308
src/pkg/exp/html/testdata/webkit/scriptdata01.dat
vendored
@@ -1,308 +0,0 @@
|
||||
#data
|
||||
FOO<script>'Hello'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'Hello'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script></script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script></script >BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script></script/>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script></script/ >BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain"></scriptx>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "</scriptx>BAR"
|
||||
|
||||
#data
|
||||
FOO<script></script foo=">" dd>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!-'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!-'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!--'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!--'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!---'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!---'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!-->'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!-->'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!-->'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!-->'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!-- potato'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!-- potato'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!-- <sCrIpt'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!-- <sCrIpt'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt>'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt>'</script>BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt> -'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt> -'</script>BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt> --'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt> --'</script>BAR"
|
||||
|
||||
#data
|
||||
FOO<script>'<!-- <sCrIpt> -->'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| "'<!-- <sCrIpt> -->'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt> --!>'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt> --!>'</script>BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt> -- >'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt> -- >'</script>BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt '</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt '</script>BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt/'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt/'</script>BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt\'</script>BAR
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt\'"
|
||||
| "BAR"
|
||||
|
||||
#data
|
||||
FOO<script type="text/plain">'<!-- <sCrIpt/'</script>BAR</script>QUX
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "FOO"
|
||||
| <script>
|
||||
| type="text/plain"
|
||||
| "'<!-- <sCrIpt/'</script>BAR"
|
||||
| "QUX"
|
||||
@@ -1,15 +0,0 @@
|
||||
#data
|
||||
<p><b id="A"><script>document.getElementById("A").id = "B"</script></p>TEXT</b>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <p>
|
||||
| <b>
|
||||
| id="B"
|
||||
| <script>
|
||||
| "document.getElementById("A").id = "B""
|
||||
| <b>
|
||||
| id="A"
|
||||
| "TEXT"
|
||||
@@ -1,28 +0,0 @@
|
||||
#data
|
||||
1<script>document.write("2")</script>3
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "1"
|
||||
| <script>
|
||||
| "document.write("2")"
|
||||
| "23"
|
||||
|
||||
#data
|
||||
1<script>document.write("<script>document.write('2')</scr"+ "ipt><script>document.write('3')</scr" + "ipt>")</script>4
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "1"
|
||||
| <script>
|
||||
| "document.write("<script>document.write('2')</scr"+ "ipt><script>document.write('3')</scr" + "ipt>")"
|
||||
| <script>
|
||||
| "document.write('2')"
|
||||
| "2"
|
||||
| <script>
|
||||
| "document.write('3')"
|
||||
| "34"
|
||||
197
src/pkg/exp/html/testdata/webkit/tables01.dat
vendored
197
src/pkg/exp/html/testdata/webkit/tables01.dat
vendored
@@ -1,197 +0,0 @@
|
||||
#data
|
||||
<table><th>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <th>
|
||||
|
||||
#data
|
||||
<table><td>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<table><col foo='bar'>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <colgroup>
|
||||
| <col>
|
||||
| foo="bar"
|
||||
|
||||
#data
|
||||
<table><colgroup></html>foo
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "foo"
|
||||
| <table>
|
||||
| <colgroup>
|
||||
|
||||
#data
|
||||
<table></table><p>foo
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <p>
|
||||
| "foo"
|
||||
|
||||
#data
|
||||
<table></body></caption></col></colgroup></html></tbody></td></tfoot></th></thead></tr><td>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<table><select><option>3</select></table>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <option>
|
||||
| "3"
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<table><select><table></table></select></table>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <table>
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<table><select></table>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<table><select><option>A<tr><td>B</td></tr></table>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <option>
|
||||
| "A"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| "B"
|
||||
|
||||
#data
|
||||
<table><td></body></caption></col></colgroup></html>foo
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| "foo"
|
||||
|
||||
#data
|
||||
<table><td>A</table>B
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| "A"
|
||||
| "B"
|
||||
|
||||
#data
|
||||
<table><tr><caption>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <caption>
|
||||
|
||||
#data
|
||||
<table><tr></body></caption></col></colgroup></html></td></th><td>foo
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| "foo"
|
||||
|
||||
#data
|
||||
<table><td><tr>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<table><td><button><td>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <button>
|
||||
| <td>
|
||||
1952
src/pkg/exp/html/testdata/webkit/tests1.dat
vendored
1952
src/pkg/exp/html/testdata/webkit/tests1.dat
vendored
File diff suppressed because it is too large
Load Diff
799
src/pkg/exp/html/testdata/webkit/tests10.dat
vendored
799
src/pkg/exp/html/testdata/webkit/tests10.dat
vendored
@@ -1,799 +0,0 @@
|
||||
#data
|
||||
<!DOCTYPE html><svg></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><svg></svg><![CDATA[a]]>
|
||||
#errors
|
||||
29: Bogus comment
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <!-- [CDATA[a]] -->
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><svg></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><select><svg></svg></select>
|
||||
#errors
|
||||
35: Stray “svg” start tag.
|
||||
42: Stray end tag “svg”
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><select><option><svg></svg></option></select>
|
||||
#errors
|
||||
43: Stray “svg” start tag.
|
||||
50: Stray end tag “svg”
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <option>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><svg></svg></table>
|
||||
#errors
|
||||
34: Start tag “svg” seen in “table”.
|
||||
41: Stray end tag “svg”.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><svg><g>foo</g></svg></table>
|
||||
#errors
|
||||
34: Start tag “svg” seen in “table”.
|
||||
46: Stray end tag “g”.
|
||||
53: Stray end tag “svg”.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><svg><g>foo</g><g>bar</g></svg></table>
|
||||
#errors
|
||||
34: Start tag “svg” seen in “table”.
|
||||
46: Stray end tag “g”.
|
||||
58: Stray end tag “g”.
|
||||
65: Stray end tag “svg”.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tbody><svg><g>foo</g><g>bar</g></svg></tbody></table>
|
||||
#errors
|
||||
41: Start tag “svg” seen in “table”.
|
||||
53: Stray end tag “g”.
|
||||
65: Stray end tag “g”.
|
||||
72: Stray end tag “svg”.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <table>
|
||||
| <tbody>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tbody><tr><svg><g>foo</g><g>bar</g></svg></tr></tbody></table>
|
||||
#errors
|
||||
45: Start tag “svg” seen in “table”.
|
||||
57: Stray end tag “g”.
|
||||
69: Stray end tag “g”.
|
||||
76: Stray end tag “svg”.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg></td></tr></tbody></table>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tbody><tr><td><svg><g>foo</g><g>bar</g></svg><p>baz</td></tr></tbody></table>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <p>
|
||||
| "baz"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g></svg><p>baz</caption></table>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <caption>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <p>
|
||||
| "baz"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
|
||||
#errors
|
||||
70: HTML start tag “p” in a foreign namespace context.
|
||||
81: “table” closed but “caption” was still open.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <caption>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <p>
|
||||
| "baz"
|
||||
| <p>
|
||||
| "quux"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g>baz</table><p>quux
|
||||
#errors
|
||||
78: “table” closed but “caption” was still open.
|
||||
78: Unclosed elements on stack.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <caption>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| "baz"
|
||||
| <p>
|
||||
| "quux"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><colgroup><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
|
||||
#errors
|
||||
44: Start tag “svg” seen in “table”.
|
||||
56: Stray end tag “g”.
|
||||
68: Stray end tag “g”.
|
||||
71: HTML start tag “p” in a foreign namespace context.
|
||||
71: Start tag “p” seen in “table”.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <p>
|
||||
| "baz"
|
||||
| <table>
|
||||
| <colgroup>
|
||||
| <p>
|
||||
| "quux"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><tr><td><select><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
|
||||
#errors
|
||||
50: Stray “svg” start tag.
|
||||
54: Stray “g” start tag.
|
||||
62: Stray end tag “g”
|
||||
66: Stray “g” start tag.
|
||||
74: Stray end tag “g”
|
||||
77: Stray “p” start tag.
|
||||
88: “table” end tag with “select” open.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <select>
|
||||
| "foobarbaz"
|
||||
| <p>
|
||||
| "quux"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><table><select><svg><g>foo</g><g>bar</g><p>baz</table><p>quux
|
||||
#errors
|
||||
36: Start tag “select” seen in “table”.
|
||||
42: Stray “svg” start tag.
|
||||
46: Stray “g” start tag.
|
||||
54: Stray end tag “g”
|
||||
58: Stray “g” start tag.
|
||||
66: Stray end tag “g”
|
||||
69: Stray “p” start tag.
|
||||
80: “table” end tag with “select” open.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| "foobarbaz"
|
||||
| <table>
|
||||
| <p>
|
||||
| "quux"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body></body></html><svg><g>foo</g><g>bar</g><p>baz
|
||||
#errors
|
||||
41: Stray “svg” start tag.
|
||||
68: HTML start tag “p” in a foreign namespace context.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <p>
|
||||
| "baz"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body></body><svg><g>foo</g><g>bar</g><p>baz
|
||||
#errors
|
||||
34: Stray “svg” start tag.
|
||||
61: HTML start tag “p” in a foreign namespace context.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| "foo"
|
||||
| <svg g>
|
||||
| "bar"
|
||||
| <p>
|
||||
| "baz"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><frameset><svg><g></g><g></g><p><span>
|
||||
#errors
|
||||
31: Stray “svg” start tag.
|
||||
35: Stray “g” start tag.
|
||||
40: Stray end tag “g”
|
||||
44: Stray “g” start tag.
|
||||
49: Stray end tag “g”
|
||||
52: Stray “p” start tag.
|
||||
58: Stray “span” start tag.
|
||||
58: End of file seen and there were open elements.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><frameset></frameset><svg><g></g><g></g><p><span>
|
||||
#errors
|
||||
42: Stray “svg” start tag.
|
||||
46: Stray “g” start tag.
|
||||
51: Stray end tag “g”
|
||||
55: Stray “g” start tag.
|
||||
60: Stray end tag “g”
|
||||
63: Stray “p” start tag.
|
||||
69: Stray “span” start tag.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body xlink:href=foo><svg xlink:href=foo></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| xlink:href="foo"
|
||||
| <svg svg>
|
||||
| xlink href="foo"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo></g></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| xlink:href="foo"
|
||||
| xml:lang="en"
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| xlink href="foo"
|
||||
| xml lang="en"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo /></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| xlink:href="foo"
|
||||
| xml:lang="en"
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| xlink href="foo"
|
||||
| xml lang="en"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body xlink:href=foo xml:lang=en><svg><g xml:lang=en xlink:href=foo />bar</svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| xlink:href="foo"
|
||||
| xml:lang="en"
|
||||
| <svg svg>
|
||||
| <svg g>
|
||||
| xlink href="foo"
|
||||
| xml lang="en"
|
||||
| "bar"
|
||||
|
||||
#data
|
||||
<svg></path>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
|
||||
#data
|
||||
<div><svg></div>a
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| <svg svg>
|
||||
| "a"
|
||||
|
||||
#data
|
||||
<div><svg><path></div>a
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| <svg svg>
|
||||
| <svg path>
|
||||
| "a"
|
||||
|
||||
#data
|
||||
<div><svg><path></svg><path>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| <svg svg>
|
||||
| <svg path>
|
||||
| <path>
|
||||
|
||||
#data
|
||||
<div><svg><path><foreignObject><math></div>a
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| <svg svg>
|
||||
| <svg path>
|
||||
| <svg foreignObject>
|
||||
| <math math>
|
||||
| "a"
|
||||
|
||||
#data
|
||||
<div><svg><path><foreignObject><p></div>a
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| <svg svg>
|
||||
| <svg path>
|
||||
| <svg foreignObject>
|
||||
| <p>
|
||||
| "a"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><svg><desc><div><svg><ul>a
|
||||
#errors
|
||||
40: HTML start tag “ul” in a foreign namespace context.
|
||||
41: End of file in a foreign namespace context.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg desc>
|
||||
| <div>
|
||||
| <svg svg>
|
||||
| <ul>
|
||||
| "a"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><svg><desc><svg><ul>a
|
||||
#errors
|
||||
35: HTML start tag “ul” in a foreign namespace context.
|
||||
36: End of file in a foreign namespace context.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg desc>
|
||||
| <svg svg>
|
||||
| <ul>
|
||||
| "a"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><p><svg><desc><p>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <p>
|
||||
| <svg svg>
|
||||
| <svg desc>
|
||||
| <p>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><p><svg><title><p>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <p>
|
||||
| <svg svg>
|
||||
| <svg title>
|
||||
| <p>
|
||||
|
||||
#data
|
||||
<div><svg><path><foreignObject><p></foreignObject><p>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| <svg svg>
|
||||
| <svg path>
|
||||
| <svg foreignObject>
|
||||
| <p>
|
||||
| <p>
|
||||
|
||||
#data
|
||||
<math><mi><div><object><div><span></span></div></object></div></mi><mi>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mi>
|
||||
| <div>
|
||||
| <object>
|
||||
| <div>
|
||||
| <span>
|
||||
| <math mi>
|
||||
|
||||
#data
|
||||
<math><mi><svg><foreignObject><div><div></div></div></foreignObject></svg></mi><mi>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mi>
|
||||
| <svg svg>
|
||||
| <svg foreignObject>
|
||||
| <div>
|
||||
| <div>
|
||||
| <math mi>
|
||||
|
||||
#data
|
||||
<svg><script></script><path>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg script>
|
||||
| <svg path>
|
||||
|
||||
#data
|
||||
<table><svg></svg><tr>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<math><mi><mglyph>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mi>
|
||||
| <math mglyph>
|
||||
|
||||
#data
|
||||
<math><mi><malignmark>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mi>
|
||||
| <math malignmark>
|
||||
|
||||
#data
|
||||
<math><mo><mglyph>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mo>
|
||||
| <math mglyph>
|
||||
|
||||
#data
|
||||
<math><mo><malignmark>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mo>
|
||||
| <math malignmark>
|
||||
|
||||
#data
|
||||
<math><mn><mglyph>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mn>
|
||||
| <math mglyph>
|
||||
|
||||
#data
|
||||
<math><mn><malignmark>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mn>
|
||||
| <math malignmark>
|
||||
|
||||
#data
|
||||
<math><ms><mglyph>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math ms>
|
||||
| <math mglyph>
|
||||
|
||||
#data
|
||||
<math><ms><malignmark>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math ms>
|
||||
| <math malignmark>
|
||||
|
||||
#data
|
||||
<math><mtext><mglyph>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mtext>
|
||||
| <math mglyph>
|
||||
|
||||
#data
|
||||
<math><mtext><malignmark>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math mtext>
|
||||
| <math malignmark>
|
||||
|
||||
#data
|
||||
<math><annotation-xml><svg></svg></annotation-xml><mi>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math annotation-xml>
|
||||
| <svg svg>
|
||||
| <math mi>
|
||||
|
||||
#data
|
||||
<math><annotation-xml><svg><foreignObject><div><math><mi></mi></math><span></span></div></foreignObject><path></path></svg></annotation-xml><mi>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math annotation-xml>
|
||||
| <svg svg>
|
||||
| <svg foreignObject>
|
||||
| <div>
|
||||
| <math math>
|
||||
| <math mi>
|
||||
| <span>
|
||||
| <svg path>
|
||||
| <math mi>
|
||||
|
||||
#data
|
||||
<math><annotation-xml><svg><foreignObject><math><mi><svg></svg></mi><mo></mo></math><span></span></foreignObject><path></path></svg></annotation-xml><mi>
|
||||
#errors
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math annotation-xml>
|
||||
| <svg svg>
|
||||
| <svg foreignObject>
|
||||
| <math math>
|
||||
| <math mi>
|
||||
| <svg svg>
|
||||
| <math mo>
|
||||
| <span>
|
||||
| <svg path>
|
||||
| <math mi>
|
||||
482
src/pkg/exp/html/testdata/webkit/tests11.dat
vendored
482
src/pkg/exp/html/testdata/webkit/tests11.dat
vendored
@@ -1,482 +0,0 @@
|
||||
#data
|
||||
<!DOCTYPE html><body><svg attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterRes='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| attributeName=""
|
||||
| attributeType=""
|
||||
| baseFrequency=""
|
||||
| baseProfile=""
|
||||
| calcMode=""
|
||||
| clipPathUnits=""
|
||||
| contentScriptType=""
|
||||
| contentStyleType=""
|
||||
| diffuseConstant=""
|
||||
| edgeMode=""
|
||||
| externalResourcesRequired=""
|
||||
| filterRes=""
|
||||
| filterUnits=""
|
||||
| glyphRef=""
|
||||
| gradientTransform=""
|
||||
| gradientUnits=""
|
||||
| kernelMatrix=""
|
||||
| kernelUnitLength=""
|
||||
| keyPoints=""
|
||||
| keySplines=""
|
||||
| keyTimes=""
|
||||
| lengthAdjust=""
|
||||
| limitingConeAngle=""
|
||||
| markerHeight=""
|
||||
| markerUnits=""
|
||||
| markerWidth=""
|
||||
| maskContentUnits=""
|
||||
| maskUnits=""
|
||||
| numOctaves=""
|
||||
| pathLength=""
|
||||
| patternContentUnits=""
|
||||
| patternTransform=""
|
||||
| patternUnits=""
|
||||
| pointsAtX=""
|
||||
| pointsAtY=""
|
||||
| pointsAtZ=""
|
||||
| preserveAlpha=""
|
||||
| preserveAspectRatio=""
|
||||
| primitiveUnits=""
|
||||
| refX=""
|
||||
| refY=""
|
||||
| repeatCount=""
|
||||
| repeatDur=""
|
||||
| requiredExtensions=""
|
||||
| requiredFeatures=""
|
||||
| specularConstant=""
|
||||
| specularExponent=""
|
||||
| spreadMethod=""
|
||||
| startOffset=""
|
||||
| stdDeviation=""
|
||||
| stitchTiles=""
|
||||
| surfaceScale=""
|
||||
| systemLanguage=""
|
||||
| tableValues=""
|
||||
| targetX=""
|
||||
| targetY=""
|
||||
| textLength=""
|
||||
| viewBox=""
|
||||
| viewTarget=""
|
||||
| xChannelSelector=""
|
||||
| yChannelSelector=""
|
||||
| zoomAndPan=""
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><BODY><SVG ATTRIBUTENAME='' ATTRIBUTETYPE='' BASEFREQUENCY='' BASEPROFILE='' CALCMODE='' CLIPPATHUNITS='' CONTENTSCRIPTTYPE='' CONTENTSTYLETYPE='' DIFFUSECONSTANT='' EDGEMODE='' EXTERNALRESOURCESREQUIRED='' FILTERRES='' FILTERUNITS='' GLYPHREF='' GRADIENTTRANSFORM='' GRADIENTUNITS='' KERNELMATRIX='' KERNELUNITLENGTH='' KEYPOINTS='' KEYSPLINES='' KEYTIMES='' LENGTHADJUST='' LIMITINGCONEANGLE='' MARKERHEIGHT='' MARKERUNITS='' MARKERWIDTH='' MASKCONTENTUNITS='' MASKUNITS='' NUMOCTAVES='' PATHLENGTH='' PATTERNCONTENTUNITS='' PATTERNTRANSFORM='' PATTERNUNITS='' POINTSATX='' POINTSATY='' POINTSATZ='' PRESERVEALPHA='' PRESERVEASPECTRATIO='' PRIMITIVEUNITS='' REFX='' REFY='' REPEATCOUNT='' REPEATDUR='' REQUIREDEXTENSIONS='' REQUIREDFEATURES='' SPECULARCONSTANT='' SPECULAREXPONENT='' SPREADMETHOD='' STARTOFFSET='' STDDEVIATION='' STITCHTILES='' SURFACESCALE='' SYSTEMLANGUAGE='' TABLEVALUES='' TARGETX='' TARGETY='' TEXTLENGTH='' VIEWBOX='' VIEWTARGET='' XCHANNELSELECTOR='' YCHANNELSELECTOR='' ZOOMANDPAN=''></SVG>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| attributeName=""
|
||||
| attributeType=""
|
||||
| baseFrequency=""
|
||||
| baseProfile=""
|
||||
| calcMode=""
|
||||
| clipPathUnits=""
|
||||
| contentScriptType=""
|
||||
| contentStyleType=""
|
||||
| diffuseConstant=""
|
||||
| edgeMode=""
|
||||
| externalResourcesRequired=""
|
||||
| filterRes=""
|
||||
| filterUnits=""
|
||||
| glyphRef=""
|
||||
| gradientTransform=""
|
||||
| gradientUnits=""
|
||||
| kernelMatrix=""
|
||||
| kernelUnitLength=""
|
||||
| keyPoints=""
|
||||
| keySplines=""
|
||||
| keyTimes=""
|
||||
| lengthAdjust=""
|
||||
| limitingConeAngle=""
|
||||
| markerHeight=""
|
||||
| markerUnits=""
|
||||
| markerWidth=""
|
||||
| maskContentUnits=""
|
||||
| maskUnits=""
|
||||
| numOctaves=""
|
||||
| pathLength=""
|
||||
| patternContentUnits=""
|
||||
| patternTransform=""
|
||||
| patternUnits=""
|
||||
| pointsAtX=""
|
||||
| pointsAtY=""
|
||||
| pointsAtZ=""
|
||||
| preserveAlpha=""
|
||||
| preserveAspectRatio=""
|
||||
| primitiveUnits=""
|
||||
| refX=""
|
||||
| refY=""
|
||||
| repeatCount=""
|
||||
| repeatDur=""
|
||||
| requiredExtensions=""
|
||||
| requiredFeatures=""
|
||||
| specularConstant=""
|
||||
| specularExponent=""
|
||||
| spreadMethod=""
|
||||
| startOffset=""
|
||||
| stdDeviation=""
|
||||
| stitchTiles=""
|
||||
| surfaceScale=""
|
||||
| systemLanguage=""
|
||||
| tableValues=""
|
||||
| targetX=""
|
||||
| targetY=""
|
||||
| textLength=""
|
||||
| viewBox=""
|
||||
| viewTarget=""
|
||||
| xChannelSelector=""
|
||||
| yChannelSelector=""
|
||||
| zoomAndPan=""
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><svg attributename='' attributetype='' basefrequency='' baseprofile='' calcmode='' clippathunits='' contentscripttype='' contentstyletype='' diffuseconstant='' edgemode='' externalresourcesrequired='' filterres='' filterunits='' glyphref='' gradienttransform='' gradientunits='' kernelmatrix='' kernelunitlength='' keypoints='' keysplines='' keytimes='' lengthadjust='' limitingconeangle='' markerheight='' markerunits='' markerwidth='' maskcontentunits='' maskunits='' numoctaves='' pathlength='' patterncontentunits='' patterntransform='' patternunits='' pointsatx='' pointsaty='' pointsatz='' preservealpha='' preserveaspectratio='' primitiveunits='' refx='' refy='' repeatcount='' repeatdur='' requiredextensions='' requiredfeatures='' specularconstant='' specularexponent='' spreadmethod='' startoffset='' stddeviation='' stitchtiles='' surfacescale='' systemlanguage='' tablevalues='' targetx='' targety='' textlength='' viewbox='' viewtarget='' xchannelselector='' ychannelselector='' zoomandpan=''></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| attributeName=""
|
||||
| attributeType=""
|
||||
| baseFrequency=""
|
||||
| baseProfile=""
|
||||
| calcMode=""
|
||||
| clipPathUnits=""
|
||||
| contentScriptType=""
|
||||
| contentStyleType=""
|
||||
| diffuseConstant=""
|
||||
| edgeMode=""
|
||||
| externalResourcesRequired=""
|
||||
| filterRes=""
|
||||
| filterUnits=""
|
||||
| glyphRef=""
|
||||
| gradientTransform=""
|
||||
| gradientUnits=""
|
||||
| kernelMatrix=""
|
||||
| kernelUnitLength=""
|
||||
| keyPoints=""
|
||||
| keySplines=""
|
||||
| keyTimes=""
|
||||
| lengthAdjust=""
|
||||
| limitingConeAngle=""
|
||||
| markerHeight=""
|
||||
| markerUnits=""
|
||||
| markerWidth=""
|
||||
| maskContentUnits=""
|
||||
| maskUnits=""
|
||||
| numOctaves=""
|
||||
| pathLength=""
|
||||
| patternContentUnits=""
|
||||
| patternTransform=""
|
||||
| patternUnits=""
|
||||
| pointsAtX=""
|
||||
| pointsAtY=""
|
||||
| pointsAtZ=""
|
||||
| preserveAlpha=""
|
||||
| preserveAspectRatio=""
|
||||
| primitiveUnits=""
|
||||
| refX=""
|
||||
| refY=""
|
||||
| repeatCount=""
|
||||
| repeatDur=""
|
||||
| requiredExtensions=""
|
||||
| requiredFeatures=""
|
||||
| specularConstant=""
|
||||
| specularExponent=""
|
||||
| spreadMethod=""
|
||||
| startOffset=""
|
||||
| stdDeviation=""
|
||||
| stitchTiles=""
|
||||
| surfaceScale=""
|
||||
| systemLanguage=""
|
||||
| tableValues=""
|
||||
| targetX=""
|
||||
| targetY=""
|
||||
| textLength=""
|
||||
| viewBox=""
|
||||
| viewTarget=""
|
||||
| xChannelSelector=""
|
||||
| yChannelSelector=""
|
||||
| zoomAndPan=""
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><math attributeName='' attributeType='' baseFrequency='' baseProfile='' calcMode='' clipPathUnits='' contentScriptType='' contentStyleType='' diffuseConstant='' edgeMode='' externalResourcesRequired='' filterRes='' filterUnits='' glyphRef='' gradientTransform='' gradientUnits='' kernelMatrix='' kernelUnitLength='' keyPoints='' keySplines='' keyTimes='' lengthAdjust='' limitingConeAngle='' markerHeight='' markerUnits='' markerWidth='' maskContentUnits='' maskUnits='' numOctaves='' pathLength='' patternContentUnits='' patternTransform='' patternUnits='' pointsAtX='' pointsAtY='' pointsAtZ='' preserveAlpha='' preserveAspectRatio='' primitiveUnits='' refX='' refY='' repeatCount='' repeatDur='' requiredExtensions='' requiredFeatures='' specularConstant='' specularExponent='' spreadMethod='' startOffset='' stdDeviation='' stitchTiles='' surfaceScale='' systemLanguage='' tableValues='' targetX='' targetY='' textLength='' viewBox='' viewTarget='' xChannelSelector='' yChannelSelector='' zoomAndPan=''></math>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| attributename=""
|
||||
| attributetype=""
|
||||
| basefrequency=""
|
||||
| baseprofile=""
|
||||
| calcmode=""
|
||||
| clippathunits=""
|
||||
| contentscripttype=""
|
||||
| contentstyletype=""
|
||||
| diffuseconstant=""
|
||||
| edgemode=""
|
||||
| externalresourcesrequired=""
|
||||
| filterres=""
|
||||
| filterunits=""
|
||||
| glyphref=""
|
||||
| gradienttransform=""
|
||||
| gradientunits=""
|
||||
| kernelmatrix=""
|
||||
| kernelunitlength=""
|
||||
| keypoints=""
|
||||
| keysplines=""
|
||||
| keytimes=""
|
||||
| lengthadjust=""
|
||||
| limitingconeangle=""
|
||||
| markerheight=""
|
||||
| markerunits=""
|
||||
| markerwidth=""
|
||||
| maskcontentunits=""
|
||||
| maskunits=""
|
||||
| numoctaves=""
|
||||
| pathlength=""
|
||||
| patterncontentunits=""
|
||||
| patterntransform=""
|
||||
| patternunits=""
|
||||
| pointsatx=""
|
||||
| pointsaty=""
|
||||
| pointsatz=""
|
||||
| preservealpha=""
|
||||
| preserveaspectratio=""
|
||||
| primitiveunits=""
|
||||
| refx=""
|
||||
| refy=""
|
||||
| repeatcount=""
|
||||
| repeatdur=""
|
||||
| requiredextensions=""
|
||||
| requiredfeatures=""
|
||||
| specularconstant=""
|
||||
| specularexponent=""
|
||||
| spreadmethod=""
|
||||
| startoffset=""
|
||||
| stddeviation=""
|
||||
| stitchtiles=""
|
||||
| surfacescale=""
|
||||
| systemlanguage=""
|
||||
| tablevalues=""
|
||||
| targetx=""
|
||||
| targety=""
|
||||
| textlength=""
|
||||
| viewbox=""
|
||||
| viewtarget=""
|
||||
| xchannelselector=""
|
||||
| ychannelselector=""
|
||||
| zoomandpan=""
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><svg><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg altGlyph>
|
||||
| <svg altGlyphDef>
|
||||
| <svg altGlyphItem>
|
||||
| <svg animateColor>
|
||||
| <svg animateMotion>
|
||||
| <svg animateTransform>
|
||||
| <svg clipPath>
|
||||
| <svg feBlend>
|
||||
| <svg feColorMatrix>
|
||||
| <svg feComponentTransfer>
|
||||
| <svg feComposite>
|
||||
| <svg feConvolveMatrix>
|
||||
| <svg feDiffuseLighting>
|
||||
| <svg feDisplacementMap>
|
||||
| <svg feDistantLight>
|
||||
| <svg feFlood>
|
||||
| <svg feFuncA>
|
||||
| <svg feFuncB>
|
||||
| <svg feFuncG>
|
||||
| <svg feFuncR>
|
||||
| <svg feGaussianBlur>
|
||||
| <svg feImage>
|
||||
| <svg feMerge>
|
||||
| <svg feMergeNode>
|
||||
| <svg feMorphology>
|
||||
| <svg feOffset>
|
||||
| <svg fePointLight>
|
||||
| <svg feSpecularLighting>
|
||||
| <svg feSpotLight>
|
||||
| <svg feTile>
|
||||
| <svg feTurbulence>
|
||||
| <svg foreignObject>
|
||||
| <svg glyphRef>
|
||||
| <svg linearGradient>
|
||||
| <svg radialGradient>
|
||||
| <svg textPath>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><svg><altglyph /><altglyphdef /><altglyphitem /><animatecolor /><animatemotion /><animatetransform /><clippath /><feblend /><fecolormatrix /><fecomponenttransfer /><fecomposite /><feconvolvematrix /><fediffuselighting /><fedisplacementmap /><fedistantlight /><feflood /><fefunca /><fefuncb /><fefuncg /><fefuncr /><fegaussianblur /><feimage /><femerge /><femergenode /><femorphology /><feoffset /><fepointlight /><fespecularlighting /><fespotlight /><fetile /><feturbulence /><foreignobject /><glyphref /><lineargradient /><radialgradient /><textpath /></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg altGlyph>
|
||||
| <svg altGlyphDef>
|
||||
| <svg altGlyphItem>
|
||||
| <svg animateColor>
|
||||
| <svg animateMotion>
|
||||
| <svg animateTransform>
|
||||
| <svg clipPath>
|
||||
| <svg feBlend>
|
||||
| <svg feColorMatrix>
|
||||
| <svg feComponentTransfer>
|
||||
| <svg feComposite>
|
||||
| <svg feConvolveMatrix>
|
||||
| <svg feDiffuseLighting>
|
||||
| <svg feDisplacementMap>
|
||||
| <svg feDistantLight>
|
||||
| <svg feFlood>
|
||||
| <svg feFuncA>
|
||||
| <svg feFuncB>
|
||||
| <svg feFuncG>
|
||||
| <svg feFuncR>
|
||||
| <svg feGaussianBlur>
|
||||
| <svg feImage>
|
||||
| <svg feMerge>
|
||||
| <svg feMergeNode>
|
||||
| <svg feMorphology>
|
||||
| <svg feOffset>
|
||||
| <svg fePointLight>
|
||||
| <svg feSpecularLighting>
|
||||
| <svg feSpotLight>
|
||||
| <svg feTile>
|
||||
| <svg feTurbulence>
|
||||
| <svg foreignObject>
|
||||
| <svg glyphRef>
|
||||
| <svg linearGradient>
|
||||
| <svg radialGradient>
|
||||
| <svg textPath>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><BODY><SVG><ALTGLYPH /><ALTGLYPHDEF /><ALTGLYPHITEM /><ANIMATECOLOR /><ANIMATEMOTION /><ANIMATETRANSFORM /><CLIPPATH /><FEBLEND /><FECOLORMATRIX /><FECOMPONENTTRANSFER /><FECOMPOSITE /><FECONVOLVEMATRIX /><FEDIFFUSELIGHTING /><FEDISPLACEMENTMAP /><FEDISTANTLIGHT /><FEFLOOD /><FEFUNCA /><FEFUNCB /><FEFUNCG /><FEFUNCR /><FEGAUSSIANBLUR /><FEIMAGE /><FEMERGE /><FEMERGENODE /><FEMORPHOLOGY /><FEOFFSET /><FEPOINTLIGHT /><FESPECULARLIGHTING /><FESPOTLIGHT /><FETILE /><FETURBULENCE /><FOREIGNOBJECT /><GLYPHREF /><LINEARGRADIENT /><RADIALGRADIENT /><TEXTPATH /></SVG>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg altGlyph>
|
||||
| <svg altGlyphDef>
|
||||
| <svg altGlyphItem>
|
||||
| <svg animateColor>
|
||||
| <svg animateMotion>
|
||||
| <svg animateTransform>
|
||||
| <svg clipPath>
|
||||
| <svg feBlend>
|
||||
| <svg feColorMatrix>
|
||||
| <svg feComponentTransfer>
|
||||
| <svg feComposite>
|
||||
| <svg feConvolveMatrix>
|
||||
| <svg feDiffuseLighting>
|
||||
| <svg feDisplacementMap>
|
||||
| <svg feDistantLight>
|
||||
| <svg feFlood>
|
||||
| <svg feFuncA>
|
||||
| <svg feFuncB>
|
||||
| <svg feFuncG>
|
||||
| <svg feFuncR>
|
||||
| <svg feGaussianBlur>
|
||||
| <svg feImage>
|
||||
| <svg feMerge>
|
||||
| <svg feMergeNode>
|
||||
| <svg feMorphology>
|
||||
| <svg feOffset>
|
||||
| <svg fePointLight>
|
||||
| <svg feSpecularLighting>
|
||||
| <svg feSpotLight>
|
||||
| <svg feTile>
|
||||
| <svg feTurbulence>
|
||||
| <svg foreignObject>
|
||||
| <svg glyphRef>
|
||||
| <svg linearGradient>
|
||||
| <svg radialGradient>
|
||||
| <svg textPath>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><math><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></math>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <math math>
|
||||
| <math altglyph>
|
||||
| <math altglyphdef>
|
||||
| <math altglyphitem>
|
||||
| <math animatecolor>
|
||||
| <math animatemotion>
|
||||
| <math animatetransform>
|
||||
| <math clippath>
|
||||
| <math feblend>
|
||||
| <math fecolormatrix>
|
||||
| <math fecomponenttransfer>
|
||||
| <math fecomposite>
|
||||
| <math feconvolvematrix>
|
||||
| <math fediffuselighting>
|
||||
| <math fedisplacementmap>
|
||||
| <math fedistantlight>
|
||||
| <math feflood>
|
||||
| <math fefunca>
|
||||
| <math fefuncb>
|
||||
| <math fefuncg>
|
||||
| <math fefuncr>
|
||||
| <math fegaussianblur>
|
||||
| <math feimage>
|
||||
| <math femerge>
|
||||
| <math femergenode>
|
||||
| <math femorphology>
|
||||
| <math feoffset>
|
||||
| <math fepointlight>
|
||||
| <math fespecularlighting>
|
||||
| <math fespotlight>
|
||||
| <math fetile>
|
||||
| <math feturbulence>
|
||||
| <math foreignobject>
|
||||
| <math glyphref>
|
||||
| <math lineargradient>
|
||||
| <math radialgradient>
|
||||
| <math textpath>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body><svg><solidColor /></svg>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <svg svg>
|
||||
| <svg solidcolor>
|
||||
62
src/pkg/exp/html/testdata/webkit/tests12.dat
vendored
62
src/pkg/exp/html/testdata/webkit/tests12.dat
vendored
@@ -1,62 +0,0 @@
|
||||
#data
|
||||
<!DOCTYPE html><body><p>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><P>spam<TABLE><tr><td><img></td></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <p>
|
||||
| "foo"
|
||||
| <math math>
|
||||
| <math mtext>
|
||||
| <i>
|
||||
| "baz"
|
||||
| <math annotation-xml>
|
||||
| <svg svg>
|
||||
| <svg desc>
|
||||
| <b>
|
||||
| "eggs"
|
||||
| <svg g>
|
||||
| <svg foreignObject>
|
||||
| <p>
|
||||
| "spam"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <img>
|
||||
| <svg g>
|
||||
| "quux"
|
||||
| "bar"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><body>foo<math><mtext><i>baz</i></mtext><annotation-xml><svg><desc><b>eggs</b></desc><g><foreignObject><P>spam<TABLE><tr><td><img></td></table></foreignObject></g><g>quux</g></svg></annotation-xml></math>bar
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "foo"
|
||||
| <math math>
|
||||
| <math mtext>
|
||||
| <i>
|
||||
| "baz"
|
||||
| <math annotation-xml>
|
||||
| <svg svg>
|
||||
| <svg desc>
|
||||
| <b>
|
||||
| "eggs"
|
||||
| <svg g>
|
||||
| <svg foreignObject>
|
||||
| <p>
|
||||
| "spam"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <img>
|
||||
| <svg g>
|
||||
| "quux"
|
||||
| "bar"
|
||||
74
src/pkg/exp/html/testdata/webkit/tests14.dat
vendored
74
src/pkg/exp/html/testdata/webkit/tests14.dat
vendored
@@ -1,74 +0,0 @@
|
||||
#data
|
||||
<!DOCTYPE html><html><body><xyz:abc></xyz:abc>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <xyz:abc>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html><body><xyz:abc></xyz:abc><span></span>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <xyz:abc>
|
||||
| <span>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html><html abc:def=gh><xyz:abc></xyz:abc>
|
||||
#errors
|
||||
15: Unexpected start tag html
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| abc:def="gh"
|
||||
| <head>
|
||||
| <body>
|
||||
| <xyz:abc>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html xml:lang=bar><html xml:lang=foo>
|
||||
#errors
|
||||
15: Unexpected start tag html
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| xml:lang="bar"
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html 123=456>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| 123="456"
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html 123=456><html 789=012>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| 123="456"
|
||||
| 789="012"
|
||||
| <head>
|
||||
| <body>
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><html><body 789=012>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| 789="012"
|
||||
208
src/pkg/exp/html/testdata/webkit/tests15.dat
vendored
208
src/pkg/exp/html/testdata/webkit/tests15.dat
vendored
@@ -1,208 +0,0 @@
|
||||
#data
|
||||
<!DOCTYPE html><p><b><i><u></p> <p>X
|
||||
#errors
|
||||
Line: 1 Col: 31 Unexpected end tag (p). Ignored.
|
||||
Line: 1 Col: 36 Expected closing tag. Unexpected end of file.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <p>
|
||||
| <b>
|
||||
| <i>
|
||||
| <u>
|
||||
| <b>
|
||||
| <i>
|
||||
| <u>
|
||||
| " "
|
||||
| <p>
|
||||
| "X"
|
||||
|
||||
#data
|
||||
<p><b><i><u></p>
|
||||
<p>X
|
||||
#errors
|
||||
Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE.
|
||||
Line: 1 Col: 16 Unexpected end tag (p). Ignored.
|
||||
Line: 2 Col: 4 Expected closing tag. Unexpected end of file.
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <p>
|
||||
| <b>
|
||||
| <i>
|
||||
| <u>
|
||||
| <b>
|
||||
| <i>
|
||||
| <u>
|
||||
| "
|
||||
"
|
||||
| <p>
|
||||
| "X"
|
||||
|
||||
#data
|
||||
<!doctype html></html> <head>
|
||||
#errors
|
||||
Line: 1 Col: 22 Unexpected end tag (html) after the (implied) root element.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| " "
|
||||
|
||||
#data
|
||||
<!doctype html></body><meta>
|
||||
#errors
|
||||
Line: 1 Col: 22 Unexpected end tag (body) after the (implied) root element.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <meta>
|
||||
|
||||
#data
|
||||
<html></html><!-- foo -->
|
||||
#errors
|
||||
Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
|
||||
Line: 1 Col: 13 Unexpected end tag (html) after the (implied) root element.
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <!-- foo -->
|
||||
|
||||
#data
|
||||
<!doctype html></body><title>X</title>
|
||||
#errors
|
||||
Line: 1 Col: 22 Unexpected end tag (body) after the (implied) root element.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <title>
|
||||
| "X"
|
||||
|
||||
#data
|
||||
<!doctype html><table> X<meta></table>
|
||||
#errors
|
||||
Line: 1 Col: 24 Unexpected non-space characters in table context caused voodoo mode.
|
||||
Line: 1 Col: 30 Unexpected start tag (meta) in table context caused voodoo mode.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| " X"
|
||||
| <meta>
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<!doctype html><table> x</table>
|
||||
#errors
|
||||
Line: 1 Col: 24 Unexpected non-space characters in table context caused voodoo mode.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| " x"
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<!doctype html><table> x </table>
|
||||
#errors
|
||||
Line: 1 Col: 25 Unexpected non-space characters in table context caused voodoo mode.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| " x "
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr> x</table>
|
||||
#errors
|
||||
Line: 1 Col: 28 Unexpected non-space characters in table context caused voodoo mode.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| " x"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<!doctype html><table>X<style> <tr>x </style> </table>
|
||||
#errors
|
||||
Line: 1 Col: 23 Unexpected non-space characters in table context caused voodoo mode.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "X"
|
||||
| <table>
|
||||
| <style>
|
||||
| " <tr>x "
|
||||
| " "
|
||||
|
||||
#data
|
||||
<!doctype html><div><table><a>foo</a> <tr><td>bar</td> </tr></table></div>
|
||||
#errors
|
||||
Line: 1 Col: 30 Unexpected start tag (a) in table context caused voodoo mode.
|
||||
Line: 1 Col: 37 Unexpected end tag (a) in table context caused voodoo mode.
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <div>
|
||||
| <a>
|
||||
| "foo"
|
||||
| <table>
|
||||
| " "
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| "bar"
|
||||
| " "
|
||||
|
||||
#data
|
||||
<frame></frame></frame><frameset><frame><frameset><frame></frameset><noframes></frameset><noframes>
|
||||
#errors
|
||||
6: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
|
||||
13: Stray start tag “frame”.
|
||||
21: Stray end tag “frame”.
|
||||
29: Stray end tag “frame”.
|
||||
39: “frameset” start tag after “body” already open.
|
||||
105: End of file seen inside an [R]CDATA element.
|
||||
105: End of file seen and there were open elements.
|
||||
XXX: These errors are wrong, please fix me!
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
| <frame>
|
||||
| <frameset>
|
||||
| <frame>
|
||||
| <noframes>
|
||||
| "</frameset><noframes>"
|
||||
|
||||
#data
|
||||
<!DOCTYPE html><object></html>
|
||||
#errors
|
||||
1: Expected closing tag. Unexpected end of file
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <object>
|
||||
2277
src/pkg/exp/html/testdata/webkit/tests16.dat
vendored
2277
src/pkg/exp/html/testdata/webkit/tests16.dat
vendored
File diff suppressed because it is too large
Load Diff
153
src/pkg/exp/html/testdata/webkit/tests17.dat
vendored
153
src/pkg/exp/html/testdata/webkit/tests17.dat
vendored
@@ -1,153 +0,0 @@
|
||||
#data
|
||||
<!doctype html><table><tbody><select><tr>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr><select><td>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr><td><select><td>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <select>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr><th><select><td>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <th>
|
||||
| <select>
|
||||
| <td>
|
||||
|
||||
#data
|
||||
<!doctype html><table><caption><select><tr>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <caption>
|
||||
| <select>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<!doctype html><select><tr>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
|
||||
#data
|
||||
<!doctype html><select><td>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
|
||||
#data
|
||||
<!doctype html><select><th>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
|
||||
#data
|
||||
<!doctype html><select><tbody>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
|
||||
#data
|
||||
<!doctype html><select><thead>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
|
||||
#data
|
||||
<!doctype html><select><tfoot>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
|
||||
#data
|
||||
<!doctype html><select><caption>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr></table>a
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| "a"
|
||||
269
src/pkg/exp/html/testdata/webkit/tests18.dat
vendored
269
src/pkg/exp/html/testdata/webkit/tests18.dat
vendored
@@ -1,269 +0,0 @@
|
||||
#data
|
||||
<!doctype html><plaintext></plaintext>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <plaintext>
|
||||
| "</plaintext>"
|
||||
|
||||
#data
|
||||
<!doctype html><table><plaintext></plaintext>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <plaintext>
|
||||
| "</plaintext>"
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tbody><plaintext></plaintext>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <plaintext>
|
||||
| "</plaintext>"
|
||||
| <table>
|
||||
| <tbody>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tbody><tr><plaintext></plaintext>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <plaintext>
|
||||
| "</plaintext>"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tbody><tr><plaintext></plaintext>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <plaintext>
|
||||
| "</plaintext>"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<!doctype html><table><td><plaintext></plaintext>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <plaintext>
|
||||
| "</plaintext>"
|
||||
|
||||
#data
|
||||
<!doctype html><table><caption><plaintext></plaintext>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <caption>
|
||||
| <plaintext>
|
||||
| "</plaintext>"
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr><style></script></style>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "abc"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <style>
|
||||
| "</script>"
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr><script></style></script>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| "abc"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <script>
|
||||
| "</style>"
|
||||
|
||||
#data
|
||||
<!doctype html><table><caption><style></script></style>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <caption>
|
||||
| <style>
|
||||
| "</script>"
|
||||
| "abc"
|
||||
|
||||
#data
|
||||
<!doctype html><table><td><style></script></style>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <style>
|
||||
| "</script>"
|
||||
| "abc"
|
||||
|
||||
#data
|
||||
<!doctype html><select><script></style></script>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <script>
|
||||
| "</style>"
|
||||
| "abc"
|
||||
|
||||
#data
|
||||
<!doctype html><table><select><script></style></script>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <script>
|
||||
| "</style>"
|
||||
| "abc"
|
||||
| <table>
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr><select><script></style></script>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <select>
|
||||
| <script>
|
||||
| "</style>"
|
||||
| "abc"
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
|
||||
#data
|
||||
<!doctype html><frameset></frameset><noframes>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
| <noframes>
|
||||
| "abc"
|
||||
|
||||
#data
|
||||
<!doctype html><frameset></frameset><noframes>abc</noframes><!--abc-->
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
| <noframes>
|
||||
| "abc"
|
||||
| <!-- abc -->
|
||||
|
||||
#data
|
||||
<!doctype html><frameset></frameset></html><noframes>abc
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
| <noframes>
|
||||
| "abc"
|
||||
|
||||
#data
|
||||
<!doctype html><frameset></frameset></html><noframes>abc</noframes><!--abc-->
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <frameset>
|
||||
| <noframes>
|
||||
| "abc"
|
||||
| <!-- abc -->
|
||||
|
||||
#data
|
||||
<!doctype html><table><tr></tbody><tfoot>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <tfoot>
|
||||
|
||||
#data
|
||||
<!doctype html><table><td><svg></svg>abc<td>
|
||||
#errors
|
||||
#document
|
||||
| <!DOCTYPE html>
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <table>
|
||||
| <tbody>
|
||||
| <tr>
|
||||
| <td>
|
||||
| <svg svg>
|
||||
| "abc"
|
||||
| <td>
|
||||
1220
src/pkg/exp/html/testdata/webkit/tests19.dat
vendored
1220
src/pkg/exp/html/testdata/webkit/tests19.dat
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user