mirror of https://github.com/k3s-io/k3s
trash/prune golang/x/net
Signed-off-by: William Zhang <warmchang@outlook.com>pull/736/head
parent
602562963b
commit
2a0e453675
|
@ -1,41 +0,0 @@
|
||||||
// Copyright 2016 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 bpf
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// Assemble converts insts into raw instructions suitable for loading
|
|
||||||
// into a BPF virtual machine.
|
|
||||||
//
|
|
||||||
// Currently, no optimization is attempted, the assembled program flow
|
|
||||||
// is exactly as provided.
|
|
||||||
func Assemble(insts []Instruction) ([]RawInstruction, error) {
|
|
||||||
ret := make([]RawInstruction, len(insts))
|
|
||||||
var err error
|
|
||||||
for i, inst := range insts {
|
|
||||||
ret[i], err = inst.Assemble()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("assembling instruction %d: %s", i+1, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disassemble attempts to parse raw back into
|
|
||||||
// Instructions. Unrecognized RawInstructions are assumed to be an
|
|
||||||
// extension not implemented by this package, and are passed through
|
|
||||||
// unchanged to the output. The allDecoded value reports whether insts
|
|
||||||
// contains no RawInstructions.
|
|
||||||
func Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool) {
|
|
||||||
insts = make([]Instruction, len(raw))
|
|
||||||
allDecoded = true
|
|
||||||
for i, r := range raw {
|
|
||||||
insts[i] = r.Disassemble()
|
|
||||||
if _, ok := insts[i].(RawInstruction); ok {
|
|
||||||
allDecoded = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return insts, allDecoded
|
|
||||||
}
|
|
|
@ -1,222 +0,0 @@
|
||||||
// Copyright 2016 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 bpf
|
|
||||||
|
|
||||||
// A Register is a register of the BPF virtual machine.
|
|
||||||
type Register uint16
|
|
||||||
|
|
||||||
const (
|
|
||||||
// RegA is the accumulator register. RegA is always the
|
|
||||||
// destination register of ALU operations.
|
|
||||||
RegA Register = iota
|
|
||||||
// RegX is the indirection register, used by LoadIndirect
|
|
||||||
// operations.
|
|
||||||
RegX
|
|
||||||
)
|
|
||||||
|
|
||||||
// An ALUOp is an arithmetic or logic operation.
|
|
||||||
type ALUOp uint16
|
|
||||||
|
|
||||||
// ALU binary operation types.
|
|
||||||
const (
|
|
||||||
ALUOpAdd ALUOp = iota << 4
|
|
||||||
ALUOpSub
|
|
||||||
ALUOpMul
|
|
||||||
ALUOpDiv
|
|
||||||
ALUOpOr
|
|
||||||
ALUOpAnd
|
|
||||||
ALUOpShiftLeft
|
|
||||||
ALUOpShiftRight
|
|
||||||
aluOpNeg // Not exported because it's the only unary ALU operation, and gets its own instruction type.
|
|
||||||
ALUOpMod
|
|
||||||
ALUOpXor
|
|
||||||
)
|
|
||||||
|
|
||||||
// A JumpTest is a comparison operator used in conditional jumps.
|
|
||||||
type JumpTest uint16
|
|
||||||
|
|
||||||
// Supported operators for conditional jumps.
|
|
||||||
// K can be RegX for JumpIfX
|
|
||||||
const (
|
|
||||||
// K == A
|
|
||||||
JumpEqual JumpTest = iota
|
|
||||||
// K != A
|
|
||||||
JumpNotEqual
|
|
||||||
// K > A
|
|
||||||
JumpGreaterThan
|
|
||||||
// K < A
|
|
||||||
JumpLessThan
|
|
||||||
// K >= A
|
|
||||||
JumpGreaterOrEqual
|
|
||||||
// K <= A
|
|
||||||
JumpLessOrEqual
|
|
||||||
// K & A != 0
|
|
||||||
JumpBitsSet
|
|
||||||
// K & A == 0
|
|
||||||
JumpBitsNotSet
|
|
||||||
)
|
|
||||||
|
|
||||||
// An Extension is a function call provided by the kernel that
|
|
||||||
// performs advanced operations that are expensive or impossible
|
|
||||||
// within the BPF virtual machine.
|
|
||||||
//
|
|
||||||
// Extensions are only implemented by the Linux kernel.
|
|
||||||
//
|
|
||||||
// TODO: should we prune this list? Some of these extensions seem
|
|
||||||
// either broken or near-impossible to use correctly, whereas other
|
|
||||||
// (len, random, ifindex) are quite useful.
|
|
||||||
type Extension int
|
|
||||||
|
|
||||||
// Extension functions available in the Linux kernel.
|
|
||||||
const (
|
|
||||||
// extOffset is the negative maximum number of instructions used
|
|
||||||
// to load instructions by overloading the K argument.
|
|
||||||
extOffset = -0x1000
|
|
||||||
// ExtLen returns the length of the packet.
|
|
||||||
ExtLen Extension = 1
|
|
||||||
// ExtProto returns the packet's L3 protocol type.
|
|
||||||
ExtProto Extension = 0
|
|
||||||
// ExtType returns the packet's type (skb->pkt_type in the kernel)
|
|
||||||
//
|
|
||||||
// TODO: better documentation. How nice an API do we want to
|
|
||||||
// provide for these esoteric extensions?
|
|
||||||
ExtType Extension = 4
|
|
||||||
// ExtPayloadOffset returns the offset of the packet payload, or
|
|
||||||
// the first protocol header that the kernel does not know how to
|
|
||||||
// parse.
|
|
||||||
ExtPayloadOffset Extension = 52
|
|
||||||
// ExtInterfaceIndex returns the index of the interface on which
|
|
||||||
// the packet was received.
|
|
||||||
ExtInterfaceIndex Extension = 8
|
|
||||||
// ExtNetlinkAttr returns the netlink attribute of type X at
|
|
||||||
// offset A.
|
|
||||||
ExtNetlinkAttr Extension = 12
|
|
||||||
// ExtNetlinkAttrNested returns the nested netlink attribute of
|
|
||||||
// type X at offset A.
|
|
||||||
ExtNetlinkAttrNested Extension = 16
|
|
||||||
// ExtMark returns the packet's mark value.
|
|
||||||
ExtMark Extension = 20
|
|
||||||
// ExtQueue returns the packet's assigned hardware queue.
|
|
||||||
ExtQueue Extension = 24
|
|
||||||
// ExtLinkLayerType returns the packet's hardware address type
|
|
||||||
// (e.g. Ethernet, Infiniband).
|
|
||||||
ExtLinkLayerType Extension = 28
|
|
||||||
// ExtRXHash returns the packets receive hash.
|
|
||||||
//
|
|
||||||
// TODO: figure out what this rxhash actually is.
|
|
||||||
ExtRXHash Extension = 32
|
|
||||||
// ExtCPUID returns the ID of the CPU processing the current
|
|
||||||
// packet.
|
|
||||||
ExtCPUID Extension = 36
|
|
||||||
// ExtVLANTag returns the packet's VLAN tag.
|
|
||||||
ExtVLANTag Extension = 44
|
|
||||||
// ExtVLANTagPresent returns non-zero if the packet has a VLAN
|
|
||||||
// tag.
|
|
||||||
//
|
|
||||||
// TODO: I think this might be a lie: it reads bit 0x1000 of the
|
|
||||||
// VLAN header, which changed meaning in recent revisions of the
|
|
||||||
// spec - this extension may now return meaningless information.
|
|
||||||
ExtVLANTagPresent Extension = 48
|
|
||||||
// ExtVLANProto returns 0x8100 if the frame has a VLAN header,
|
|
||||||
// 0x88a8 if the frame has a "Q-in-Q" double VLAN header, or some
|
|
||||||
// other value if no VLAN information is present.
|
|
||||||
ExtVLANProto Extension = 60
|
|
||||||
// ExtRand returns a uniformly random uint32.
|
|
||||||
ExtRand Extension = 56
|
|
||||||
)
|
|
||||||
|
|
||||||
// The following gives names to various bit patterns used in opcode construction.
|
|
||||||
|
|
||||||
const (
|
|
||||||
opMaskCls uint16 = 0x7
|
|
||||||
// opClsLoad masks
|
|
||||||
opMaskLoadDest = 0x01
|
|
||||||
opMaskLoadWidth = 0x18
|
|
||||||
opMaskLoadMode = 0xe0
|
|
||||||
// opClsALU & opClsJump
|
|
||||||
opMaskOperand = 0x08
|
|
||||||
opMaskOperator = 0xf0
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// +---------------+-----------------+---+---+---+
|
|
||||||
// | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 0 |
|
|
||||||
// +---------------+-----------------+---+---+---+
|
|
||||||
opClsLoadA uint16 = iota
|
|
||||||
// +---------------+-----------------+---+---+---+
|
|
||||||
// | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 1 |
|
|
||||||
// +---------------+-----------------+---+---+---+
|
|
||||||
opClsLoadX
|
|
||||||
// +---+---+---+---+---+---+---+---+
|
|
||||||
// | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
|
|
||||||
// +---+---+---+---+---+---+---+---+
|
|
||||||
opClsStoreA
|
|
||||||
// +---+---+---+---+---+---+---+---+
|
|
||||||
// | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
|
|
||||||
// +---+---+---+---+---+---+---+---+
|
|
||||||
opClsStoreX
|
|
||||||
// +---------------+-----------------+---+---+---+
|
|
||||||
// | Operator (4b) | OperandSrc (1b) | 1 | 0 | 0 |
|
|
||||||
// +---------------+-----------------+---+---+---+
|
|
||||||
opClsALU
|
|
||||||
// +-----------------------------+---+---+---+---+
|
|
||||||
// | TestOperator (4b) | 0 | 1 | 0 | 1 |
|
|
||||||
// +-----------------------------+---+---+---+---+
|
|
||||||
opClsJump
|
|
||||||
// +---+-------------------------+---+---+---+---+
|
|
||||||
// | 0 | 0 | 0 | RetSrc (1b) | 0 | 1 | 1 | 0 |
|
|
||||||
// +---+-------------------------+---+---+---+---+
|
|
||||||
opClsReturn
|
|
||||||
// +---+-------------------------+---+---+---+---+
|
|
||||||
// | 0 | 0 | 0 | TXAorTAX (1b) | 0 | 1 | 1 | 1 |
|
|
||||||
// +---+-------------------------+---+---+---+---+
|
|
||||||
opClsMisc
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
opAddrModeImmediate uint16 = iota << 5
|
|
||||||
opAddrModeAbsolute
|
|
||||||
opAddrModeIndirect
|
|
||||||
opAddrModeScratch
|
|
||||||
opAddrModePacketLen // actually an extension, not an addressing mode.
|
|
||||||
opAddrModeMemShift
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
opLoadWidth4 uint16 = iota << 3
|
|
||||||
opLoadWidth2
|
|
||||||
opLoadWidth1
|
|
||||||
)
|
|
||||||
|
|
||||||
// Operand for ALU and Jump instructions
|
|
||||||
type opOperand uint16
|
|
||||||
|
|
||||||
// Supported operand sources.
|
|
||||||
const (
|
|
||||||
opOperandConstant opOperand = iota << 3
|
|
||||||
opOperandX
|
|
||||||
)
|
|
||||||
|
|
||||||
// An jumpOp is a conditional jump condition.
|
|
||||||
type jumpOp uint16
|
|
||||||
|
|
||||||
// Supported jump conditions.
|
|
||||||
const (
|
|
||||||
opJumpAlways jumpOp = iota << 4
|
|
||||||
opJumpEqual
|
|
||||||
opJumpGT
|
|
||||||
opJumpGE
|
|
||||||
opJumpSet
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
opRetSrcConstant uint16 = iota << 4
|
|
||||||
opRetSrcA
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
opMiscTAX = 0x00
|
|
||||||
opMiscTXA = 0x80
|
|
||||||
)
|
|
|
@ -1,82 +0,0 @@
|
||||||
// Copyright 2016 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 bpf implements marshaling and unmarshaling of programs for the
|
|
||||||
Berkeley Packet Filter virtual machine, and provides a Go implementation
|
|
||||||
of the virtual machine.
|
|
||||||
|
|
||||||
BPF's main use is to specify a packet filter for network taps, so that
|
|
||||||
the kernel doesn't have to expensively copy every packet it sees to
|
|
||||||
userspace. However, it's been repurposed to other areas where running
|
|
||||||
user code in-kernel is needed. For example, Linux's seccomp uses BPF
|
|
||||||
to apply security policies to system calls. For simplicity, this
|
|
||||||
documentation refers only to packets, but other uses of BPF have their
|
|
||||||
own data payloads.
|
|
||||||
|
|
||||||
BPF programs run in a restricted virtual machine. It has almost no
|
|
||||||
access to kernel functions, and while conditional branches are
|
|
||||||
allowed, they can only jump forwards, to guarantee that there are no
|
|
||||||
infinite loops.
|
|
||||||
|
|
||||||
The virtual machine
|
|
||||||
|
|
||||||
The BPF VM is an accumulator machine. Its main register, called
|
|
||||||
register A, is an implicit source and destination in all arithmetic
|
|
||||||
and logic operations. The machine also has 16 scratch registers for
|
|
||||||
temporary storage, and an indirection register (register X) for
|
|
||||||
indirect memory access. All registers are 32 bits wide.
|
|
||||||
|
|
||||||
Each run of a BPF program is given one packet, which is placed in the
|
|
||||||
VM's read-only "main memory". LoadAbsolute and LoadIndirect
|
|
||||||
instructions can fetch up to 32 bits at a time into register A for
|
|
||||||
examination.
|
|
||||||
|
|
||||||
The goal of a BPF program is to produce and return a verdict (uint32),
|
|
||||||
which tells the kernel what to do with the packet. In the context of
|
|
||||||
packet filtering, the returned value is the number of bytes of the
|
|
||||||
packet to forward to userspace, or 0 to ignore the packet. Other
|
|
||||||
contexts like seccomp define their own return values.
|
|
||||||
|
|
||||||
In order to simplify programs, attempts to read past the end of the
|
|
||||||
packet terminate the program execution with a verdict of 0 (ignore
|
|
||||||
packet). This means that the vast majority of BPF programs don't need
|
|
||||||
to do any explicit bounds checking.
|
|
||||||
|
|
||||||
In addition to the bytes of the packet, some BPF programs have access
|
|
||||||
to extensions, which are essentially calls to kernel utility
|
|
||||||
functions. Currently, the only extensions supported by this package
|
|
||||||
are the Linux packet filter extensions.
|
|
||||||
|
|
||||||
Examples
|
|
||||||
|
|
||||||
This packet filter selects all ARP packets.
|
|
||||||
|
|
||||||
bpf.Assemble([]bpf.Instruction{
|
|
||||||
// Load "EtherType" field from the ethernet header.
|
|
||||||
bpf.LoadAbsolute{Off: 12, Size: 2},
|
|
||||||
// Skip over the next instruction if EtherType is not ARP.
|
|
||||||
bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: 0x0806, SkipTrue: 1},
|
|
||||||
// Verdict is "send up to 4k of the packet to userspace."
|
|
||||||
bpf.RetConstant{Val: 4096},
|
|
||||||
// Verdict is "ignore packet."
|
|
||||||
bpf.RetConstant{Val: 0},
|
|
||||||
})
|
|
||||||
|
|
||||||
This packet filter captures a random 1% sample of traffic.
|
|
||||||
|
|
||||||
bpf.Assemble([]bpf.Instruction{
|
|
||||||
// Get a 32-bit random number from the Linux kernel.
|
|
||||||
bpf.LoadExtension{Num: bpf.ExtRand},
|
|
||||||
// 1% dice roll?
|
|
||||||
bpf.JumpIf{Cond: bpf.JumpLessThan, Val: 2^32/100, SkipFalse: 1},
|
|
||||||
// Capture.
|
|
||||||
bpf.RetConstant{Val: 4096},
|
|
||||||
// Ignore.
|
|
||||||
bpf.RetConstant{Val: 0},
|
|
||||||
})
|
|
||||||
|
|
||||||
*/
|
|
||||||
package bpf // import "golang.org/x/net/bpf"
|
|
|
@ -1,726 +0,0 @@
|
||||||
// Copyright 2016 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 bpf
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// An Instruction is one instruction executed by the BPF virtual
|
|
||||||
// machine.
|
|
||||||
type Instruction interface {
|
|
||||||
// Assemble assembles the Instruction into a RawInstruction.
|
|
||||||
Assemble() (RawInstruction, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A RawInstruction is a raw BPF virtual machine instruction.
|
|
||||||
type RawInstruction struct {
|
|
||||||
// Operation to execute.
|
|
||||||
Op uint16
|
|
||||||
// For conditional jump instructions, the number of instructions
|
|
||||||
// to skip if the condition is true/false.
|
|
||||||
Jt uint8
|
|
||||||
Jf uint8
|
|
||||||
// Constant parameter. The meaning depends on the Op.
|
|
||||||
K uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (ri RawInstruction) Assemble() (RawInstruction, error) { return ri, nil }
|
|
||||||
|
|
||||||
// Disassemble parses ri into an Instruction and returns it. If ri is
|
|
||||||
// not recognized by this package, ri itself is returned.
|
|
||||||
func (ri RawInstruction) Disassemble() Instruction {
|
|
||||||
switch ri.Op & opMaskCls {
|
|
||||||
case opClsLoadA, opClsLoadX:
|
|
||||||
reg := Register(ri.Op & opMaskLoadDest)
|
|
||||||
sz := 0
|
|
||||||
switch ri.Op & opMaskLoadWidth {
|
|
||||||
case opLoadWidth4:
|
|
||||||
sz = 4
|
|
||||||
case opLoadWidth2:
|
|
||||||
sz = 2
|
|
||||||
case opLoadWidth1:
|
|
||||||
sz = 1
|
|
||||||
default:
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
switch ri.Op & opMaskLoadMode {
|
|
||||||
case opAddrModeImmediate:
|
|
||||||
if sz != 4 {
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
return LoadConstant{Dst: reg, Val: ri.K}
|
|
||||||
case opAddrModeScratch:
|
|
||||||
if sz != 4 || ri.K > 15 {
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
return LoadScratch{Dst: reg, N: int(ri.K)}
|
|
||||||
case opAddrModeAbsolute:
|
|
||||||
if ri.K > extOffset+0xffffffff {
|
|
||||||
return LoadExtension{Num: Extension(-extOffset + ri.K)}
|
|
||||||
}
|
|
||||||
return LoadAbsolute{Size: sz, Off: ri.K}
|
|
||||||
case opAddrModeIndirect:
|
|
||||||
return LoadIndirect{Size: sz, Off: ri.K}
|
|
||||||
case opAddrModePacketLen:
|
|
||||||
if sz != 4 {
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
return LoadExtension{Num: ExtLen}
|
|
||||||
case opAddrModeMemShift:
|
|
||||||
return LoadMemShift{Off: ri.K}
|
|
||||||
default:
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
|
|
||||||
case opClsStoreA:
|
|
||||||
if ri.Op != opClsStoreA || ri.K > 15 {
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
return StoreScratch{Src: RegA, N: int(ri.K)}
|
|
||||||
|
|
||||||
case opClsStoreX:
|
|
||||||
if ri.Op != opClsStoreX || ri.K > 15 {
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
return StoreScratch{Src: RegX, N: int(ri.K)}
|
|
||||||
|
|
||||||
case opClsALU:
|
|
||||||
switch op := ALUOp(ri.Op & opMaskOperator); op {
|
|
||||||
case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor:
|
|
||||||
switch operand := opOperand(ri.Op & opMaskOperand); operand {
|
|
||||||
case opOperandX:
|
|
||||||
return ALUOpX{Op: op}
|
|
||||||
case opOperandConstant:
|
|
||||||
return ALUOpConstant{Op: op, Val: ri.K}
|
|
||||||
default:
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
case aluOpNeg:
|
|
||||||
return NegateA{}
|
|
||||||
default:
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
|
|
||||||
case opClsJump:
|
|
||||||
switch op := jumpOp(ri.Op & opMaskOperator); op {
|
|
||||||
case opJumpAlways:
|
|
||||||
return Jump{Skip: ri.K}
|
|
||||||
case opJumpEqual, opJumpGT, opJumpGE, opJumpSet:
|
|
||||||
cond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf)
|
|
||||||
switch operand := opOperand(ri.Op & opMaskOperand); operand {
|
|
||||||
case opOperandX:
|
|
||||||
return JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse}
|
|
||||||
case opOperandConstant:
|
|
||||||
return JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse}
|
|
||||||
default:
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
|
|
||||||
case opClsReturn:
|
|
||||||
switch ri.Op {
|
|
||||||
case opClsReturn | opRetSrcA:
|
|
||||||
return RetA{}
|
|
||||||
case opClsReturn | opRetSrcConstant:
|
|
||||||
return RetConstant{Val: ri.K}
|
|
||||||
default:
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
|
|
||||||
case opClsMisc:
|
|
||||||
switch ri.Op {
|
|
||||||
case opClsMisc | opMiscTAX:
|
|
||||||
return TAX{}
|
|
||||||
case opClsMisc | opMiscTXA:
|
|
||||||
return TXA{}
|
|
||||||
default:
|
|
||||||
return ri
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic("unreachable") // switch is exhaustive on the bit pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) {
|
|
||||||
var test JumpTest
|
|
||||||
|
|
||||||
// Decode "fake" jump conditions that don't appear in machine code
|
|
||||||
// Ensures the Assemble -> Disassemble stage recreates the same instructions
|
|
||||||
// See https://github.com/golang/go/issues/18470
|
|
||||||
if skipTrue == 0 {
|
|
||||||
switch op {
|
|
||||||
case opJumpEqual:
|
|
||||||
test = JumpNotEqual
|
|
||||||
case opJumpGT:
|
|
||||||
test = JumpLessOrEqual
|
|
||||||
case opJumpGE:
|
|
||||||
test = JumpLessThan
|
|
||||||
case opJumpSet:
|
|
||||||
test = JumpBitsNotSet
|
|
||||||
}
|
|
||||||
|
|
||||||
return test, skipFalse, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
switch op {
|
|
||||||
case opJumpEqual:
|
|
||||||
test = JumpEqual
|
|
||||||
case opJumpGT:
|
|
||||||
test = JumpGreaterThan
|
|
||||||
case opJumpGE:
|
|
||||||
test = JumpGreaterOrEqual
|
|
||||||
case opJumpSet:
|
|
||||||
test = JumpBitsSet
|
|
||||||
}
|
|
||||||
|
|
||||||
return test, skipTrue, skipFalse
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadConstant loads Val into register Dst.
|
|
||||||
type LoadConstant struct {
|
|
||||||
Dst Register
|
|
||||||
Val uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a LoadConstant) Assemble() (RawInstruction, error) {
|
|
||||||
return assembleLoad(a.Dst, 4, opAddrModeImmediate, a.Val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a LoadConstant) String() string {
|
|
||||||
switch a.Dst {
|
|
||||||
case RegA:
|
|
||||||
return fmt.Sprintf("ld #%d", a.Val)
|
|
||||||
case RegX:
|
|
||||||
return fmt.Sprintf("ldx #%d", a.Val)
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadScratch loads scratch[N] into register Dst.
|
|
||||||
type LoadScratch struct {
|
|
||||||
Dst Register
|
|
||||||
N int // 0-15
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a LoadScratch) Assemble() (RawInstruction, error) {
|
|
||||||
if a.N < 0 || a.N > 15 {
|
|
||||||
return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N)
|
|
||||||
}
|
|
||||||
return assembleLoad(a.Dst, 4, opAddrModeScratch, uint32(a.N))
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a LoadScratch) String() string {
|
|
||||||
switch a.Dst {
|
|
||||||
case RegA:
|
|
||||||
return fmt.Sprintf("ld M[%d]", a.N)
|
|
||||||
case RegX:
|
|
||||||
return fmt.Sprintf("ldx M[%d]", a.N)
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadAbsolute loads packet[Off:Off+Size] as an integer value into
|
|
||||||
// register A.
|
|
||||||
type LoadAbsolute struct {
|
|
||||||
Off uint32
|
|
||||||
Size int // 1, 2 or 4
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a LoadAbsolute) Assemble() (RawInstruction, error) {
|
|
||||||
return assembleLoad(RegA, a.Size, opAddrModeAbsolute, a.Off)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a LoadAbsolute) String() string {
|
|
||||||
switch a.Size {
|
|
||||||
case 1: // byte
|
|
||||||
return fmt.Sprintf("ldb [%d]", a.Off)
|
|
||||||
case 2: // half word
|
|
||||||
return fmt.Sprintf("ldh [%d]", a.Off)
|
|
||||||
case 4: // word
|
|
||||||
if a.Off > extOffset+0xffffffff {
|
|
||||||
return LoadExtension{Num: Extension(a.Off + 0x1000)}.String()
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("ld [%d]", a.Off)
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value
|
|
||||||
// into register A.
|
|
||||||
type LoadIndirect struct {
|
|
||||||
Off uint32
|
|
||||||
Size int // 1, 2 or 4
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a LoadIndirect) Assemble() (RawInstruction, error) {
|
|
||||||
return assembleLoad(RegA, a.Size, opAddrModeIndirect, a.Off)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a LoadIndirect) String() string {
|
|
||||||
switch a.Size {
|
|
||||||
case 1: // byte
|
|
||||||
return fmt.Sprintf("ldb [x + %d]", a.Off)
|
|
||||||
case 2: // half word
|
|
||||||
return fmt.Sprintf("ldh [x + %d]", a.Off)
|
|
||||||
case 4: // word
|
|
||||||
return fmt.Sprintf("ld [x + %d]", a.Off)
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadMemShift multiplies the first 4 bits of the byte at packet[Off]
|
|
||||||
// by 4 and stores the result in register X.
|
|
||||||
//
|
|
||||||
// This instruction is mainly useful to load into X the length of an
|
|
||||||
// IPv4 packet header in a single instruction, rather than have to do
|
|
||||||
// the arithmetic on the header's first byte by hand.
|
|
||||||
type LoadMemShift struct {
|
|
||||||
Off uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a LoadMemShift) Assemble() (RawInstruction, error) {
|
|
||||||
return assembleLoad(RegX, 1, opAddrModeMemShift, a.Off)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a LoadMemShift) String() string {
|
|
||||||
return fmt.Sprintf("ldx 4*([%d]&0xf)", a.Off)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadExtension invokes a linux-specific extension and stores the
|
|
||||||
// result in register A.
|
|
||||||
type LoadExtension struct {
|
|
||||||
Num Extension
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a LoadExtension) Assemble() (RawInstruction, error) {
|
|
||||||
if a.Num == ExtLen {
|
|
||||||
return assembleLoad(RegA, 4, opAddrModePacketLen, 0)
|
|
||||||
}
|
|
||||||
return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num))
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a LoadExtension) String() string {
|
|
||||||
switch a.Num {
|
|
||||||
case ExtLen:
|
|
||||||
return "ld #len"
|
|
||||||
case ExtProto:
|
|
||||||
return "ld #proto"
|
|
||||||
case ExtType:
|
|
||||||
return "ld #type"
|
|
||||||
case ExtPayloadOffset:
|
|
||||||
return "ld #poff"
|
|
||||||
case ExtInterfaceIndex:
|
|
||||||
return "ld #ifidx"
|
|
||||||
case ExtNetlinkAttr:
|
|
||||||
return "ld #nla"
|
|
||||||
case ExtNetlinkAttrNested:
|
|
||||||
return "ld #nlan"
|
|
||||||
case ExtMark:
|
|
||||||
return "ld #mark"
|
|
||||||
case ExtQueue:
|
|
||||||
return "ld #queue"
|
|
||||||
case ExtLinkLayerType:
|
|
||||||
return "ld #hatype"
|
|
||||||
case ExtRXHash:
|
|
||||||
return "ld #rxhash"
|
|
||||||
case ExtCPUID:
|
|
||||||
return "ld #cpu"
|
|
||||||
case ExtVLANTag:
|
|
||||||
return "ld #vlan_tci"
|
|
||||||
case ExtVLANTagPresent:
|
|
||||||
return "ld #vlan_avail"
|
|
||||||
case ExtVLANProto:
|
|
||||||
return "ld #vlan_tpid"
|
|
||||||
case ExtRand:
|
|
||||||
return "ld #rand"
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StoreScratch stores register Src into scratch[N].
|
|
||||||
type StoreScratch struct {
|
|
||||||
Src Register
|
|
||||||
N int // 0-15
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a StoreScratch) Assemble() (RawInstruction, error) {
|
|
||||||
if a.N < 0 || a.N > 15 {
|
|
||||||
return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N)
|
|
||||||
}
|
|
||||||
var op uint16
|
|
||||||
switch a.Src {
|
|
||||||
case RegA:
|
|
||||||
op = opClsStoreA
|
|
||||||
case RegX:
|
|
||||||
op = opClsStoreX
|
|
||||||
default:
|
|
||||||
return RawInstruction{}, fmt.Errorf("invalid source register %v", a.Src)
|
|
||||||
}
|
|
||||||
|
|
||||||
return RawInstruction{
|
|
||||||
Op: op,
|
|
||||||
K: uint32(a.N),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a StoreScratch) String() string {
|
|
||||||
switch a.Src {
|
|
||||||
case RegA:
|
|
||||||
return fmt.Sprintf("st M[%d]", a.N)
|
|
||||||
case RegX:
|
|
||||||
return fmt.Sprintf("stx M[%d]", a.N)
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ALUOpConstant executes A = A <Op> Val.
|
|
||||||
type ALUOpConstant struct {
|
|
||||||
Op ALUOp
|
|
||||||
Val uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a ALUOpConstant) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsALU | uint16(opOperandConstant) | uint16(a.Op),
|
|
||||||
K: a.Val,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a ALUOpConstant) String() string {
|
|
||||||
switch a.Op {
|
|
||||||
case ALUOpAdd:
|
|
||||||
return fmt.Sprintf("add #%d", a.Val)
|
|
||||||
case ALUOpSub:
|
|
||||||
return fmt.Sprintf("sub #%d", a.Val)
|
|
||||||
case ALUOpMul:
|
|
||||||
return fmt.Sprintf("mul #%d", a.Val)
|
|
||||||
case ALUOpDiv:
|
|
||||||
return fmt.Sprintf("div #%d", a.Val)
|
|
||||||
case ALUOpMod:
|
|
||||||
return fmt.Sprintf("mod #%d", a.Val)
|
|
||||||
case ALUOpAnd:
|
|
||||||
return fmt.Sprintf("and #%d", a.Val)
|
|
||||||
case ALUOpOr:
|
|
||||||
return fmt.Sprintf("or #%d", a.Val)
|
|
||||||
case ALUOpXor:
|
|
||||||
return fmt.Sprintf("xor #%d", a.Val)
|
|
||||||
case ALUOpShiftLeft:
|
|
||||||
return fmt.Sprintf("lsh #%d", a.Val)
|
|
||||||
case ALUOpShiftRight:
|
|
||||||
return fmt.Sprintf("rsh #%d", a.Val)
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ALUOpX executes A = A <Op> X
|
|
||||||
type ALUOpX struct {
|
|
||||||
Op ALUOp
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a ALUOpX) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsALU | uint16(opOperandX) | uint16(a.Op),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a ALUOpX) String() string {
|
|
||||||
switch a.Op {
|
|
||||||
case ALUOpAdd:
|
|
||||||
return "add x"
|
|
||||||
case ALUOpSub:
|
|
||||||
return "sub x"
|
|
||||||
case ALUOpMul:
|
|
||||||
return "mul x"
|
|
||||||
case ALUOpDiv:
|
|
||||||
return "div x"
|
|
||||||
case ALUOpMod:
|
|
||||||
return "mod x"
|
|
||||||
case ALUOpAnd:
|
|
||||||
return "and x"
|
|
||||||
case ALUOpOr:
|
|
||||||
return "or x"
|
|
||||||
case ALUOpXor:
|
|
||||||
return "xor x"
|
|
||||||
case ALUOpShiftLeft:
|
|
||||||
return "lsh x"
|
|
||||||
case ALUOpShiftRight:
|
|
||||||
return "rsh x"
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NegateA executes A = -A.
|
|
||||||
type NegateA struct{}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a NegateA) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsALU | uint16(aluOpNeg),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a NegateA) String() string {
|
|
||||||
return fmt.Sprintf("neg")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jump skips the following Skip instructions in the program.
|
|
||||||
type Jump struct {
|
|
||||||
Skip uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a Jump) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsJump | uint16(opJumpAlways),
|
|
||||||
K: a.Skip,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a Jump) String() string {
|
|
||||||
return fmt.Sprintf("ja %d", a.Skip)
|
|
||||||
}
|
|
||||||
|
|
||||||
// JumpIf skips the following Skip instructions in the program if A
|
|
||||||
// <Cond> Val is true.
|
|
||||||
type JumpIf struct {
|
|
||||||
Cond JumpTest
|
|
||||||
Val uint32
|
|
||||||
SkipTrue uint8
|
|
||||||
SkipFalse uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a JumpIf) Assemble() (RawInstruction, error) {
|
|
||||||
return jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a JumpIf) String() string {
|
|
||||||
return jumpToString(a.Cond, fmt.Sprintf("#%d", a.Val), a.SkipTrue, a.SkipFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// JumpIfX skips the following Skip instructions in the program if A
|
|
||||||
// <Cond> X is true.
|
|
||||||
type JumpIfX struct {
|
|
||||||
Cond JumpTest
|
|
||||||
SkipTrue uint8
|
|
||||||
SkipFalse uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a JumpIfX) Assemble() (RawInstruction, error) {
|
|
||||||
return jumpToRaw(a.Cond, opOperandX, 0, a.SkipTrue, a.SkipFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a JumpIfX) String() string {
|
|
||||||
return jumpToString(a.Cond, "x", a.SkipTrue, a.SkipFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// jumpToRaw assembles a jump instruction into a RawInstruction
|
|
||||||
func jumpToRaw(test JumpTest, operand opOperand, k uint32, skipTrue, skipFalse uint8) (RawInstruction, error) {
|
|
||||||
var (
|
|
||||||
cond jumpOp
|
|
||||||
flip bool
|
|
||||||
)
|
|
||||||
switch test {
|
|
||||||
case JumpEqual:
|
|
||||||
cond = opJumpEqual
|
|
||||||
case JumpNotEqual:
|
|
||||||
cond, flip = opJumpEqual, true
|
|
||||||
case JumpGreaterThan:
|
|
||||||
cond = opJumpGT
|
|
||||||
case JumpLessThan:
|
|
||||||
cond, flip = opJumpGE, true
|
|
||||||
case JumpGreaterOrEqual:
|
|
||||||
cond = opJumpGE
|
|
||||||
case JumpLessOrEqual:
|
|
||||||
cond, flip = opJumpGT, true
|
|
||||||
case JumpBitsSet:
|
|
||||||
cond = opJumpSet
|
|
||||||
case JumpBitsNotSet:
|
|
||||||
cond, flip = opJumpSet, true
|
|
||||||
default:
|
|
||||||
return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", test)
|
|
||||||
}
|
|
||||||
jt, jf := skipTrue, skipFalse
|
|
||||||
if flip {
|
|
||||||
jt, jf = jf, jt
|
|
||||||
}
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsJump | uint16(cond) | uint16(operand),
|
|
||||||
Jt: jt,
|
|
||||||
Jf: jf,
|
|
||||||
K: k,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// jumpToString converts a jump instruction to assembler notation
|
|
||||||
func jumpToString(cond JumpTest, operand string, skipTrue, skipFalse uint8) string {
|
|
||||||
switch cond {
|
|
||||||
// K == A
|
|
||||||
case JumpEqual:
|
|
||||||
return conditionalJump(operand, skipTrue, skipFalse, "jeq", "jneq")
|
|
||||||
// K != A
|
|
||||||
case JumpNotEqual:
|
|
||||||
return fmt.Sprintf("jneq %s,%d", operand, skipTrue)
|
|
||||||
// K > A
|
|
||||||
case JumpGreaterThan:
|
|
||||||
return conditionalJump(operand, skipTrue, skipFalse, "jgt", "jle")
|
|
||||||
// K < A
|
|
||||||
case JumpLessThan:
|
|
||||||
return fmt.Sprintf("jlt %s,%d", operand, skipTrue)
|
|
||||||
// K >= A
|
|
||||||
case JumpGreaterOrEqual:
|
|
||||||
return conditionalJump(operand, skipTrue, skipFalse, "jge", "jlt")
|
|
||||||
// K <= A
|
|
||||||
case JumpLessOrEqual:
|
|
||||||
return fmt.Sprintf("jle %s,%d", operand, skipTrue)
|
|
||||||
// K & A != 0
|
|
||||||
case JumpBitsSet:
|
|
||||||
if skipFalse > 0 {
|
|
||||||
return fmt.Sprintf("jset %s,%d,%d", operand, skipTrue, skipFalse)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("jset %s,%d", operand, skipTrue)
|
|
||||||
// K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips
|
|
||||||
case JumpBitsNotSet:
|
|
||||||
return jumpToString(JumpBitsSet, operand, skipFalse, skipTrue)
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("unknown JumpTest %#v", cond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func conditionalJump(operand string, skipTrue, skipFalse uint8, positiveJump, negativeJump string) string {
|
|
||||||
if skipTrue > 0 {
|
|
||||||
if skipFalse > 0 {
|
|
||||||
return fmt.Sprintf("%s %s,%d,%d", positiveJump, operand, skipTrue, skipFalse)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s %s,%d", positiveJump, operand, skipTrue)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s %s,%d", negativeJump, operand, skipFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetA exits the BPF program, returning the value of register A.
|
|
||||||
type RetA struct{}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a RetA) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsReturn | opRetSrcA,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a RetA) String() string {
|
|
||||||
return fmt.Sprintf("ret a")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetConstant exits the BPF program, returning a constant value.
|
|
||||||
type RetConstant struct {
|
|
||||||
Val uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a RetConstant) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsReturn | opRetSrcConstant,
|
|
||||||
K: a.Val,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a RetConstant) String() string {
|
|
||||||
return fmt.Sprintf("ret #%d", a.Val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TXA copies the value of register X to register A.
|
|
||||||
type TXA struct{}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a TXA) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsMisc | opMiscTXA,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a TXA) String() string {
|
|
||||||
return fmt.Sprintf("txa")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TAX copies the value of register A to register X.
|
|
||||||
type TAX struct{}
|
|
||||||
|
|
||||||
// Assemble implements the Instruction Assemble method.
|
|
||||||
func (a TAX) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{
|
|
||||||
Op: opClsMisc | opMiscTAX,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the instruction in assembler notation.
|
|
||||||
func (a TAX) String() string {
|
|
||||||
return fmt.Sprintf("tax")
|
|
||||||
}
|
|
||||||
|
|
||||||
func assembleLoad(dst Register, loadSize int, mode uint16, k uint32) (RawInstruction, error) {
|
|
||||||
var (
|
|
||||||
cls uint16
|
|
||||||
sz uint16
|
|
||||||
)
|
|
||||||
switch dst {
|
|
||||||
case RegA:
|
|
||||||
cls = opClsLoadA
|
|
||||||
case RegX:
|
|
||||||
cls = opClsLoadX
|
|
||||||
default:
|
|
||||||
return RawInstruction{}, fmt.Errorf("invalid target register %v", dst)
|
|
||||||
}
|
|
||||||
switch loadSize {
|
|
||||||
case 1:
|
|
||||||
sz = opLoadWidth1
|
|
||||||
case 2:
|
|
||||||
sz = opLoadWidth2
|
|
||||||
case 4:
|
|
||||||
sz = opLoadWidth4
|
|
||||||
default:
|
|
||||||
return RawInstruction{}, fmt.Errorf("invalid load byte length %d", sz)
|
|
||||||
}
|
|
||||||
return RawInstruction{
|
|
||||||
Op: cls | sz | mode,
|
|
||||||
K: k,
|
|
||||||
}, nil
|
|
||||||
}
|
|
|
@ -1,593 +0,0 @@
|
||||||
// Copyright 2016 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 bpf
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a direct translation of the program in
|
|
||||||
// testdata/all_instructions.txt.
|
|
||||||
var allInstructions = []Instruction{
|
|
||||||
LoadConstant{Dst: RegA, Val: 42},
|
|
||||||
LoadConstant{Dst: RegX, Val: 42},
|
|
||||||
|
|
||||||
LoadScratch{Dst: RegA, N: 3},
|
|
||||||
LoadScratch{Dst: RegX, N: 3},
|
|
||||||
|
|
||||||
LoadAbsolute{Off: 42, Size: 1},
|
|
||||||
LoadAbsolute{Off: 42, Size: 2},
|
|
||||||
LoadAbsolute{Off: 42, Size: 4},
|
|
||||||
|
|
||||||
LoadIndirect{Off: 42, Size: 1},
|
|
||||||
LoadIndirect{Off: 42, Size: 2},
|
|
||||||
LoadIndirect{Off: 42, Size: 4},
|
|
||||||
|
|
||||||
LoadMemShift{Off: 42},
|
|
||||||
|
|
||||||
LoadExtension{Num: ExtLen},
|
|
||||||
LoadExtension{Num: ExtProto},
|
|
||||||
LoadExtension{Num: ExtType},
|
|
||||||
LoadExtension{Num: ExtRand},
|
|
||||||
|
|
||||||
StoreScratch{Src: RegA, N: 3},
|
|
||||||
StoreScratch{Src: RegX, N: 3},
|
|
||||||
|
|
||||||
ALUOpConstant{Op: ALUOpAdd, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpSub, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpMul, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpDiv, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpOr, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpAnd, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpShiftLeft, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpShiftRight, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpMod, Val: 42},
|
|
||||||
ALUOpConstant{Op: ALUOpXor, Val: 42},
|
|
||||||
|
|
||||||
ALUOpX{Op: ALUOpAdd},
|
|
||||||
ALUOpX{Op: ALUOpSub},
|
|
||||||
ALUOpX{Op: ALUOpMul},
|
|
||||||
ALUOpX{Op: ALUOpDiv},
|
|
||||||
ALUOpX{Op: ALUOpOr},
|
|
||||||
ALUOpX{Op: ALUOpAnd},
|
|
||||||
ALUOpX{Op: ALUOpShiftLeft},
|
|
||||||
ALUOpX{Op: ALUOpShiftRight},
|
|
||||||
ALUOpX{Op: ALUOpMod},
|
|
||||||
ALUOpX{Op: ALUOpXor},
|
|
||||||
|
|
||||||
NegateA{},
|
|
||||||
|
|
||||||
Jump{Skip: 17},
|
|
||||||
JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 15, SkipFalse: 16},
|
|
||||||
JumpIf{Cond: JumpNotEqual, Val: 42, SkipTrue: 15},
|
|
||||||
JumpIf{Cond: JumpLessThan, Val: 42, SkipTrue: 14},
|
|
||||||
JumpIf{Cond: JumpLessOrEqual, Val: 42, SkipTrue: 13},
|
|
||||||
JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 11, SkipFalse: 12},
|
|
||||||
JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 10, SkipFalse: 11},
|
|
||||||
JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 9, SkipFalse: 10},
|
|
||||||
|
|
||||||
JumpIfX{Cond: JumpEqual, SkipTrue: 8, SkipFalse: 9},
|
|
||||||
JumpIfX{Cond: JumpNotEqual, SkipTrue: 8},
|
|
||||||
JumpIfX{Cond: JumpLessThan, SkipTrue: 7},
|
|
||||||
JumpIfX{Cond: JumpLessOrEqual, SkipTrue: 6},
|
|
||||||
JumpIfX{Cond: JumpGreaterThan, SkipTrue: 4, SkipFalse: 5},
|
|
||||||
JumpIfX{Cond: JumpGreaterOrEqual, SkipTrue: 3, SkipFalse: 4},
|
|
||||||
JumpIfX{Cond: JumpBitsSet, SkipTrue: 2, SkipFalse: 3},
|
|
||||||
|
|
||||||
TAX{},
|
|
||||||
TXA{},
|
|
||||||
|
|
||||||
RetA{},
|
|
||||||
RetConstant{Val: 42},
|
|
||||||
}
|
|
||||||
var allInstructionsExpected = "testdata/all_instructions.bpf"
|
|
||||||
|
|
||||||
// Check that we produce the same output as the canonical bpf_asm
|
|
||||||
// linux kernel tool.
|
|
||||||
func TestInterop(t *testing.T) {
|
|
||||||
out, err := Assemble(allInstructions)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("assembly of allInstructions program failed: %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("Assembled program is %d instructions long", len(out))
|
|
||||||
|
|
||||||
bs, err := ioutil.ReadFile(allInstructionsExpected)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("reading %s: %s", allInstructionsExpected, err)
|
|
||||||
}
|
|
||||||
// First statement is the number of statements, last statement is
|
|
||||||
// empty. We just ignore both and rely on slice length.
|
|
||||||
stmts := strings.Split(string(bs), ",")
|
|
||||||
if len(stmts)-2 != len(out) {
|
|
||||||
t.Fatalf("test program lengths don't match: %s has %d, Go implementation has %d", allInstructionsExpected, len(stmts)-2, len(allInstructions))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, stmt := range stmts[1 : len(stmts)-2] {
|
|
||||||
nums := strings.Split(stmt, " ")
|
|
||||||
if len(nums) != 4 {
|
|
||||||
t.Fatalf("malformed instruction %d in %s: %s", i+1, allInstructionsExpected, stmt)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := out[i]
|
|
||||||
|
|
||||||
op, err := strconv.ParseUint(nums[0], 10, 16)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("malformed opcode %s in instruction %d of %s", nums[0], i+1, allInstructionsExpected)
|
|
||||||
}
|
|
||||||
if actual.Op != uint16(op) {
|
|
||||||
t.Errorf("opcode mismatch on instruction %d (%#v): got 0x%02x, want 0x%02x", i+1, allInstructions[i], actual.Op, op)
|
|
||||||
}
|
|
||||||
|
|
||||||
jt, err := strconv.ParseUint(nums[1], 10, 8)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("malformed jt offset %s in instruction %d of %s", nums[1], i+1, allInstructionsExpected)
|
|
||||||
}
|
|
||||||
if actual.Jt != uint8(jt) {
|
|
||||||
t.Errorf("jt mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.Jt, jt)
|
|
||||||
}
|
|
||||||
|
|
||||||
jf, err := strconv.ParseUint(nums[2], 10, 8)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("malformed jf offset %s in instruction %d of %s", nums[2], i+1, allInstructionsExpected)
|
|
||||||
}
|
|
||||||
if actual.Jf != uint8(jf) {
|
|
||||||
t.Errorf("jf mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.Jf, jf)
|
|
||||||
}
|
|
||||||
|
|
||||||
k, err := strconv.ParseUint(nums[3], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("malformed constant %s in instruction %d of %s", nums[3], i+1, allInstructionsExpected)
|
|
||||||
}
|
|
||||||
if actual.K != uint32(k) {
|
|
||||||
t.Errorf("constant mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.K, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that assembly and disassembly match each other.
|
|
||||||
func TestAsmDisasm(t *testing.T) {
|
|
||||||
prog1, err := Assemble(allInstructions)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("assembly of allInstructions program failed: %s", err)
|
|
||||||
}
|
|
||||||
t.Logf("Assembled program is %d instructions long", len(prog1))
|
|
||||||
|
|
||||||
got, allDecoded := Disassemble(prog1)
|
|
||||||
if !allDecoded {
|
|
||||||
t.Errorf("Disassemble(Assemble(allInstructions)) produced unrecognized instructions:")
|
|
||||||
for i, inst := range got {
|
|
||||||
if r, ok := inst.(RawInstruction); ok {
|
|
||||||
t.Logf(" insn %d, %#v --> %#v", i+1, allInstructions[i], r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(allInstructions) != len(got) {
|
|
||||||
t.Fatalf("disassembly changed program size: %d insns before, %d insns after", len(allInstructions), len(got))
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(allInstructions, got) {
|
|
||||||
t.Errorf("program mutated by disassembly:")
|
|
||||||
for i := range got {
|
|
||||||
if !reflect.DeepEqual(allInstructions[i], got[i]) {
|
|
||||||
t.Logf(" insn %d, s: %#v, p1: %#v, got: %#v", i+1, allInstructions[i], prog1[i], got[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type InvalidInstruction struct{}
|
|
||||||
|
|
||||||
func (a InvalidInstruction) Assemble() (RawInstruction, error) {
|
|
||||||
return RawInstruction{}, fmt.Errorf("Invalid Instruction")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a InvalidInstruction) String() string {
|
|
||||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestString(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
instruction Instruction
|
|
||||||
assembler string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
instruction: LoadConstant{Dst: RegA, Val: 42},
|
|
||||||
assembler: "ld #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadConstant{Dst: RegX, Val: 42},
|
|
||||||
assembler: "ldx #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadConstant{Dst: 0xffff, Val: 42},
|
|
||||||
assembler: "unknown instruction: bpf.LoadConstant{Dst:0xffff, Val:0x2a}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadScratch{Dst: RegA, N: 3},
|
|
||||||
assembler: "ld M[3]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadScratch{Dst: RegX, N: 3},
|
|
||||||
assembler: "ldx M[3]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadScratch{Dst: 0xffff, N: 3},
|
|
||||||
assembler: "unknown instruction: bpf.LoadScratch{Dst:0xffff, N:3}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 42, Size: 1},
|
|
||||||
assembler: "ldb [42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 42, Size: 2},
|
|
||||||
assembler: "ldh [42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 42, Size: 4},
|
|
||||||
assembler: "ld [42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 42, Size: -1},
|
|
||||||
assembler: "unknown instruction: bpf.LoadAbsolute{Off:0x2a, Size:-1}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadIndirect{Off: 42, Size: 1},
|
|
||||||
assembler: "ldb [x + 42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadIndirect{Off: 42, Size: 2},
|
|
||||||
assembler: "ldh [x + 42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadIndirect{Off: 42, Size: 4},
|
|
||||||
assembler: "ld [x + 42]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadIndirect{Off: 42, Size: -1},
|
|
||||||
assembler: "unknown instruction: bpf.LoadIndirect{Off:0x2a, Size:-1}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadMemShift{Off: 42},
|
|
||||||
assembler: "ldx 4*([42]&0xf)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtLen},
|
|
||||||
assembler: "ld #len",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtProto},
|
|
||||||
assembler: "ld #proto",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtType},
|
|
||||||
assembler: "ld #type",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtPayloadOffset},
|
|
||||||
assembler: "ld #poff",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtInterfaceIndex},
|
|
||||||
assembler: "ld #ifidx",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtNetlinkAttr},
|
|
||||||
assembler: "ld #nla",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtNetlinkAttrNested},
|
|
||||||
assembler: "ld #nlan",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtMark},
|
|
||||||
assembler: "ld #mark",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtQueue},
|
|
||||||
assembler: "ld #queue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtLinkLayerType},
|
|
||||||
assembler: "ld #hatype",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtRXHash},
|
|
||||||
assembler: "ld #rxhash",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtCPUID},
|
|
||||||
assembler: "ld #cpu",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtVLANTag},
|
|
||||||
assembler: "ld #vlan_tci",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtVLANTagPresent},
|
|
||||||
assembler: "ld #vlan_avail",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtVLANProto},
|
|
||||||
assembler: "ld #vlan_tpid",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: ExtRand},
|
|
||||||
assembler: "ld #rand",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadAbsolute{Off: 0xfffff038, Size: 4},
|
|
||||||
assembler: "ld #rand",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: LoadExtension{Num: 0xfff},
|
|
||||||
assembler: "unknown instruction: bpf.LoadExtension{Num:4095}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: StoreScratch{Src: RegA, N: 3},
|
|
||||||
assembler: "st M[3]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: StoreScratch{Src: RegX, N: 3},
|
|
||||||
assembler: "stx M[3]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: StoreScratch{Src: 0xffff, N: 3},
|
|
||||||
assembler: "unknown instruction: bpf.StoreScratch{Src:0xffff, N:3}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpAdd, Val: 42},
|
|
||||||
assembler: "add #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpSub, Val: 42},
|
|
||||||
assembler: "sub #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpMul, Val: 42},
|
|
||||||
assembler: "mul #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpDiv, Val: 42},
|
|
||||||
assembler: "div #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpOr, Val: 42},
|
|
||||||
assembler: "or #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpAnd, Val: 42},
|
|
||||||
assembler: "and #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpShiftLeft, Val: 42},
|
|
||||||
assembler: "lsh #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpShiftRight, Val: 42},
|
|
||||||
assembler: "rsh #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpMod, Val: 42},
|
|
||||||
assembler: "mod #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: ALUOpXor, Val: 42},
|
|
||||||
assembler: "xor #42",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpConstant{Op: 0xffff, Val: 42},
|
|
||||||
assembler: "unknown instruction: bpf.ALUOpConstant{Op:0xffff, Val:0x2a}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpAdd},
|
|
||||||
assembler: "add x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpSub},
|
|
||||||
assembler: "sub x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpMul},
|
|
||||||
assembler: "mul x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpDiv},
|
|
||||||
assembler: "div x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpOr},
|
|
||||||
assembler: "or x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpAnd},
|
|
||||||
assembler: "and x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpShiftLeft},
|
|
||||||
assembler: "lsh x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpShiftRight},
|
|
||||||
assembler: "rsh x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpMod},
|
|
||||||
assembler: "mod x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: ALUOpXor},
|
|
||||||
assembler: "xor x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: ALUOpX{Op: 0xffff},
|
|
||||||
assembler: "unknown instruction: bpf.ALUOpX{Op:0xffff}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: NegateA{},
|
|
||||||
assembler: "neg",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: Jump{Skip: 10},
|
|
||||||
assembler: "ja 10",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8, SkipFalse: 9},
|
|
||||||
assembler: "jeq #42,8,9",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8},
|
|
||||||
assembler: "jeq #42,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipFalse: 8},
|
|
||||||
assembler: "jneq #42,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpNotEqual, Val: 42, SkipTrue: 8},
|
|
||||||
assembler: "jneq #42,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpLessThan, Val: 42, SkipTrue: 7},
|
|
||||||
assembler: "jlt #42,7",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpLessOrEqual, Val: 42, SkipTrue: 6},
|
|
||||||
assembler: "jle #42,6",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4, SkipFalse: 5},
|
|
||||||
assembler: "jgt #42,4,5",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4},
|
|
||||||
assembler: "jgt #42,4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3, SkipFalse: 4},
|
|
||||||
assembler: "jge #42,3,4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3},
|
|
||||||
assembler: "jge #42,3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
|
|
||||||
assembler: "jset #42,2,3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2},
|
|
||||||
assembler: "jset #42,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpBitsNotSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
|
|
||||||
assembler: "jset #42,3,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: JumpBitsNotSet, Val: 42, SkipTrue: 2},
|
|
||||||
assembler: "jset #42,0,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIf{Cond: 0xffff, Val: 42, SkipTrue: 1, SkipFalse: 2},
|
|
||||||
assembler: "unknown JumpTest 0xffff",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpEqual, SkipTrue: 8, SkipFalse: 9},
|
|
||||||
assembler: "jeq x,8,9",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpEqual, SkipTrue: 8},
|
|
||||||
assembler: "jeq x,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpEqual, SkipFalse: 8},
|
|
||||||
assembler: "jneq x,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpNotEqual, SkipTrue: 8},
|
|
||||||
assembler: "jneq x,8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpLessThan, SkipTrue: 7},
|
|
||||||
assembler: "jlt x,7",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpLessOrEqual, SkipTrue: 6},
|
|
||||||
assembler: "jle x,6",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpGreaterThan, SkipTrue: 4, SkipFalse: 5},
|
|
||||||
assembler: "jgt x,4,5",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpGreaterThan, SkipTrue: 4},
|
|
||||||
assembler: "jgt x,4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpGreaterOrEqual, SkipTrue: 3, SkipFalse: 4},
|
|
||||||
assembler: "jge x,3,4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpGreaterOrEqual, SkipTrue: 3},
|
|
||||||
assembler: "jge x,3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpBitsSet, SkipTrue: 2, SkipFalse: 3},
|
|
||||||
assembler: "jset x,2,3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpBitsSet, SkipTrue: 2},
|
|
||||||
assembler: "jset x,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpBitsNotSet, SkipTrue: 2, SkipFalse: 3},
|
|
||||||
assembler: "jset x,3,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: JumpBitsNotSet, SkipTrue: 2},
|
|
||||||
assembler: "jset x,0,2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: JumpIfX{Cond: 0xffff, SkipTrue: 1, SkipFalse: 2},
|
|
||||||
assembler: "unknown JumpTest 0xffff",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: TAX{},
|
|
||||||
assembler: "tax",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: TXA{},
|
|
||||||
assembler: "txa",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: RetA{},
|
|
||||||
assembler: "ret a",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instruction: RetConstant{Val: 42},
|
|
||||||
assembler: "ret #42",
|
|
||||||
},
|
|
||||||
// Invalid instruction
|
|
||||||
{
|
|
||||||
instruction: InvalidInstruction{},
|
|
||||||
assembler: "unknown instruction: bpf.InvalidInstruction{}",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
|
||||||
if input, ok := testCase.instruction.(fmt.Stringer); ok {
|
|
||||||
got := input.String()
|
|
||||||
if got != testCase.assembler {
|
|
||||||
t.Errorf("String did not return expected assembler notation, expected: %s, got: %s", testCase.assembler, got)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Errorf("Instruction %#v is not a fmt.Stringer", testCase.instruction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
// Copyright 2017 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 bpf
|
|
||||||
|
|
||||||
// A Setter is a type which can attach a compiled BPF filter to itself.
|
|
||||||
type Setter interface {
|
|
||||||
SetBPF(filter []RawInstruction) error
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
57,0 0 0 42,1 0 0 42,96 0 0 3,97 0 0 3,48 0 0 42,40 0 0 42,32 0 0 42,80 0 0 42,72 0 0 42,64 0 0 42,177 0 0 42,128 0 0 0,32 0 0 4294963200,32 0 0 4294963204,32 0 0 4294963256,2 0 0 3,3 0 0 3,4 0 0 42,20 0 0 42,36 0 0 42,52 0 0 42,68 0 0 42,84 0 0 42,100 0 0 42,116 0 0 42,148 0 0 42,164 0 0 42,12 0 0 0,28 0 0 0,44 0 0 0,60 0 0 0,76 0 0 0,92 0 0 0,108 0 0 0,124 0 0 0,156 0 0 0,172 0 0 0,132 0 0 0,5 0 0 17,21 15 16 42,21 0 15 42,53 0 14 42,37 0 13 42,37 11 12 42,53 10 11 42,69 9 10 42,29 8 9 0,29 0 8 0,61 0 7 0,45 0 6 0,45 4 5 0,61 3 4 0,77 2 3 0,7 0 0 0,135 0 0 0,22 0 0 0,6 0 0 42,
|
|
|
@ -1,88 +0,0 @@
|
||||||
# This filter is compiled to all_instructions.bpf by the `bpf_asm`
|
|
||||||
# tool, which can be found in the linux kernel source tree under
|
|
||||||
# tools/bpf.
|
|
||||||
|
|
||||||
# Load immediate
|
|
||||||
ld #42
|
|
||||||
ldx #42
|
|
||||||
|
|
||||||
# Load scratch
|
|
||||||
ld M[3]
|
|
||||||
ldx M[3]
|
|
||||||
|
|
||||||
# Load absolute
|
|
||||||
ldb [42]
|
|
||||||
ldh [42]
|
|
||||||
ld [42]
|
|
||||||
|
|
||||||
# Load indirect
|
|
||||||
ldb [x + 42]
|
|
||||||
ldh [x + 42]
|
|
||||||
ld [x + 42]
|
|
||||||
|
|
||||||
# Load IPv4 header length
|
|
||||||
ldx 4*([42]&0xf)
|
|
||||||
|
|
||||||
# Run extension function
|
|
||||||
ld #len
|
|
||||||
ld #proto
|
|
||||||
ld #type
|
|
||||||
ld #rand
|
|
||||||
|
|
||||||
# Store scratch
|
|
||||||
st M[3]
|
|
||||||
stx M[3]
|
|
||||||
|
|
||||||
# A <op> constant
|
|
||||||
add #42
|
|
||||||
sub #42
|
|
||||||
mul #42
|
|
||||||
div #42
|
|
||||||
or #42
|
|
||||||
and #42
|
|
||||||
lsh #42
|
|
||||||
rsh #42
|
|
||||||
mod #42
|
|
||||||
xor #42
|
|
||||||
|
|
||||||
# A <op> X
|
|
||||||
add x
|
|
||||||
sub x
|
|
||||||
mul x
|
|
||||||
div x
|
|
||||||
or x
|
|
||||||
and x
|
|
||||||
lsh x
|
|
||||||
rsh x
|
|
||||||
mod x
|
|
||||||
xor x
|
|
||||||
|
|
||||||
# !A
|
|
||||||
neg
|
|
||||||
|
|
||||||
# Jump A <op> constant
|
|
||||||
ja end
|
|
||||||
jeq #42,prev,end
|
|
||||||
jne #42,end
|
|
||||||
jlt #42,end
|
|
||||||
jle #42,end
|
|
||||||
jgt #42,prev,end
|
|
||||||
jge #42,prev,end
|
|
||||||
jset #42,prev,end
|
|
||||||
|
|
||||||
# Jump A <op> X
|
|
||||||
jeq x,prev,end
|
|
||||||
jne x,end
|
|
||||||
jlt x,end
|
|
||||||
jle x,end
|
|
||||||
jgt x,prev,end
|
|
||||||
jge x,prev,end
|
|
||||||
jset x,prev,end
|
|
||||||
|
|
||||||
# Register transfers
|
|
||||||
tax
|
|
||||||
txa
|
|
||||||
|
|
||||||
# Returns
|
|
||||||
prev: ret a
|
|
||||||
end: ret #42
|
|
|
@ -1,150 +0,0 @@
|
||||||
// Copyright 2016 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 bpf
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A VM is an emulated BPF virtual machine.
|
|
||||||
type VM struct {
|
|
||||||
filter []Instruction
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewVM returns a new VM using the input BPF program.
|
|
||||||
func NewVM(filter []Instruction) (*VM, error) {
|
|
||||||
if len(filter) == 0 {
|
|
||||||
return nil, errors.New("one or more Instructions must be specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, ins := range filter {
|
|
||||||
check := len(filter) - (i + 1)
|
|
||||||
switch ins := ins.(type) {
|
|
||||||
// Check for out-of-bounds jumps in instructions
|
|
||||||
case Jump:
|
|
||||||
if check <= int(ins.Skip) {
|
|
||||||
return nil, fmt.Errorf("cannot jump %d instructions; jumping past program bounds", ins.Skip)
|
|
||||||
}
|
|
||||||
case JumpIf:
|
|
||||||
if check <= int(ins.SkipTrue) {
|
|
||||||
return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue)
|
|
||||||
}
|
|
||||||
if check <= int(ins.SkipFalse) {
|
|
||||||
return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
|
|
||||||
}
|
|
||||||
case JumpIfX:
|
|
||||||
if check <= int(ins.SkipTrue) {
|
|
||||||
return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue)
|
|
||||||
}
|
|
||||||
if check <= int(ins.SkipFalse) {
|
|
||||||
return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
|
|
||||||
}
|
|
||||||
// Check for division or modulus by zero
|
|
||||||
case ALUOpConstant:
|
|
||||||
if ins.Val != 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ins.Op {
|
|
||||||
case ALUOpDiv, ALUOpMod:
|
|
||||||
return nil, errors.New("cannot divide by zero using ALUOpConstant")
|
|
||||||
}
|
|
||||||
// Check for unknown extensions
|
|
||||||
case LoadExtension:
|
|
||||||
switch ins.Num {
|
|
||||||
case ExtLen:
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("extension %d not implemented", ins.Num)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure last instruction is a return instruction
|
|
||||||
switch filter[len(filter)-1].(type) {
|
|
||||||
case RetA, RetConstant:
|
|
||||||
default:
|
|
||||||
return nil, errors.New("BPF program must end with RetA or RetConstant")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Though our VM works using disassembled instructions, we
|
|
||||||
// attempt to assemble the input filter anyway to ensure it is compatible
|
|
||||||
// with an operating system VM.
|
|
||||||
_, err := Assemble(filter)
|
|
||||||
|
|
||||||
return &VM{
|
|
||||||
filter: filter,
|
|
||||||
}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run runs the VM's BPF program against the input bytes.
|
|
||||||
// Run returns the number of bytes accepted by the BPF program, and any errors
|
|
||||||
// which occurred while processing the program.
|
|
||||||
func (v *VM) Run(in []byte) (int, error) {
|
|
||||||
var (
|
|
||||||
// Registers of the virtual machine
|
|
||||||
regA uint32
|
|
||||||
regX uint32
|
|
||||||
regScratch [16]uint32
|
|
||||||
|
|
||||||
// OK is true if the program should continue processing the next
|
|
||||||
// instruction, or false if not, causing the loop to break
|
|
||||||
ok = true
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(mdlayher): implement:
|
|
||||||
// - NegateA:
|
|
||||||
// - would require a change from uint32 registers to int32
|
|
||||||
// registers
|
|
||||||
|
|
||||||
// TODO(mdlayher): add interop tests that check signedness of ALU
|
|
||||||
// operations against kernel implementation, and make sure Go
|
|
||||||
// implementation matches behavior
|
|
||||||
|
|
||||||
for i := 0; i < len(v.filter) && ok; i++ {
|
|
||||||
ins := v.filter[i]
|
|
||||||
|
|
||||||
switch ins := ins.(type) {
|
|
||||||
case ALUOpConstant:
|
|
||||||
regA = aluOpConstant(ins, regA)
|
|
||||||
case ALUOpX:
|
|
||||||
regA, ok = aluOpX(ins, regA, regX)
|
|
||||||
case Jump:
|
|
||||||
i += int(ins.Skip)
|
|
||||||
case JumpIf:
|
|
||||||
jump := jumpIf(ins, regA)
|
|
||||||
i += jump
|
|
||||||
case JumpIfX:
|
|
||||||
jump := jumpIfX(ins, regA, regX)
|
|
||||||
i += jump
|
|
||||||
case LoadAbsolute:
|
|
||||||
regA, ok = loadAbsolute(ins, in)
|
|
||||||
case LoadConstant:
|
|
||||||
regA, regX = loadConstant(ins, regA, regX)
|
|
||||||
case LoadExtension:
|
|
||||||
regA = loadExtension(ins, in)
|
|
||||||
case LoadIndirect:
|
|
||||||
regA, ok = loadIndirect(ins, in, regX)
|
|
||||||
case LoadMemShift:
|
|
||||||
regX, ok = loadMemShift(ins, in)
|
|
||||||
case LoadScratch:
|
|
||||||
regA, regX = loadScratch(ins, regScratch, regA, regX)
|
|
||||||
case RetA:
|
|
||||||
return int(regA), nil
|
|
||||||
case RetConstant:
|
|
||||||
return int(ins.Val), nil
|
|
||||||
case StoreScratch:
|
|
||||||
regScratch = storeScratch(ins, regScratch, regA, regX)
|
|
||||||
case TAX:
|
|
||||||
regX = regA
|
|
||||||
case TXA:
|
|
||||||
regA = regX
|
|
||||||
default:
|
|
||||||
return 0, fmt.Errorf("unknown Instruction at index %d: %T", i, ins)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
|
@ -1,512 +0,0 @@
|
||||||
// Copyright 2016 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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMALUOpAdd(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpAdd,
|
|
||||||
Val: 3,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
8, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 3, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpSub(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.TAX{},
|
|
||||||
bpf.ALUOpX{
|
|
||||||
Op: bpf.ALUOpSub,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpMul(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpMul,
|
|
||||||
Val: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
6, 2, 3, 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpDiv(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpDiv,
|
|
||||||
Val: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
20, 2, 3, 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpDivByZeroALUOpConstant(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpDiv,
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot divide by zero using ALUOpConstant" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpDivByZeroALUOpX(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load byte 0 into X
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.TAX{},
|
|
||||||
// Load byte 1 into A
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 9,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Attempt to perform 1/0
|
|
||||||
bpf.ALUOpX{
|
|
||||||
Op: bpf.ALUOpDiv,
|
|
||||||
},
|
|
||||||
// Return 4 bytes if program does not terminate
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 3, 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpOr(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpOr,
|
|
||||||
Val: 0x01,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x10, 0x03, 0x04,
|
|
||||||
0x05, 0x06, 0x07, 0x08,
|
|
||||||
0x09, 0xff,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 9, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpAnd(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpAnd,
|
|
||||||
Val: 0x0019,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xaa, 0x09,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpShiftLeft(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpShiftLeft,
|
|
||||||
Val: 0x01,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 0x02,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x01, 0xaa,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpShiftRight(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpShiftRight,
|
|
||||||
Val: 0x01,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 0x04,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x08, 0xff, 0xff,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpMod(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpMod,
|
|
||||||
Val: 20,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
30, 0, 0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpModByZeroALUOpConstant(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpMod,
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot divide by zero using ALUOpConstant" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpModByZeroALUOpX(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load byte 0 into X
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.TAX{},
|
|
||||||
// Load byte 1 into A
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 9,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Attempt to perform 1%0
|
|
||||||
bpf.ALUOpX{
|
|
||||||
Op: bpf.ALUOpMod,
|
|
||||||
},
|
|
||||||
// Return 4 bytes if program does not terminate
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 3, 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpXor(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpXor,
|
|
||||||
Val: 0x0a,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 0x01,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x0b, 0x00, 0x00, 0x00,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMALUOpUnknown(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: bpf.ALUOpAdd,
|
|
||||||
Val: 1,
|
|
||||||
},
|
|
||||||
// Verify that an unknown operation is a no-op
|
|
||||||
bpf.ALUOpConstant{
|
|
||||||
Op: 100,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 0x02,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,192 +0,0 @@
|
||||||
// Copyright 2016 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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A virtualMachine is a BPF virtual machine which can process an
|
|
||||||
// input packet against a BPF program and render a verdict.
|
|
||||||
type virtualMachine interface {
|
|
||||||
Run(in []byte) (int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// canUseOSVM indicates if the OS BPF VM is available on this platform.
|
|
||||||
func canUseOSVM() bool {
|
|
||||||
// OS BPF VM can only be used on platforms where x/net/ipv4 supports
|
|
||||||
// attaching a BPF program to a socket.
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "linux":
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// All BPF tests against both the Go VM and OS VM are assumed to
|
|
||||||
// be used with a UDP socket. As a result, the entire contents
|
|
||||||
// of a UDP datagram is sent through the BPF program, but only
|
|
||||||
// the body after the UDP header will ever be returned in output.
|
|
||||||
|
|
||||||
// testVM sets up a Go BPF VM, and if available, a native OS BPF VM
|
|
||||||
// for integration testing.
|
|
||||||
func testVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func(), error) {
|
|
||||||
goVM, err := bpf.NewVM(filter)
|
|
||||||
if err != nil {
|
|
||||||
// Some tests expect an error, so this error must be returned
|
|
||||||
// instead of fatally exiting the test
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
mvm := &multiVirtualMachine{
|
|
||||||
goVM: goVM,
|
|
||||||
|
|
||||||
t: t,
|
|
||||||
}
|
|
||||||
|
|
||||||
// If available, add the OS VM for tests which verify that both the Go
|
|
||||||
// VM and OS VM have exactly the same output for the same input program
|
|
||||||
// and packet.
|
|
||||||
done := func() {}
|
|
||||||
if canUseOSVM() {
|
|
||||||
osVM, osVMDone := testOSVM(t, filter)
|
|
||||||
done = func() { osVMDone() }
|
|
||||||
mvm.osVM = osVM
|
|
||||||
}
|
|
||||||
|
|
||||||
return mvm, done, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// udpHeaderLen is the length of a UDP header.
|
|
||||||
const udpHeaderLen = 8
|
|
||||||
|
|
||||||
// A multiVirtualMachine is a virtualMachine which can call out to both the Go VM
|
|
||||||
// and the native OS VM, if the OS VM is available.
|
|
||||||
type multiVirtualMachine struct {
|
|
||||||
goVM virtualMachine
|
|
||||||
osVM virtualMachine
|
|
||||||
|
|
||||||
t *testing.T
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mvm *multiVirtualMachine) Run(in []byte) (int, error) {
|
|
||||||
if len(in) < udpHeaderLen {
|
|
||||||
mvm.t.Fatalf("input must be at least length of UDP header (%d), got: %d",
|
|
||||||
udpHeaderLen, len(in))
|
|
||||||
}
|
|
||||||
|
|
||||||
// All tests have a UDP header as part of input, because the OS VM
|
|
||||||
// packets always will. For the Go VM, this output is trimmed before
|
|
||||||
// being sent back to tests.
|
|
||||||
goOut, goErr := mvm.goVM.Run(in)
|
|
||||||
if goOut >= udpHeaderLen {
|
|
||||||
goOut -= udpHeaderLen
|
|
||||||
}
|
|
||||||
|
|
||||||
// If Go output is larger than the size of the packet, packet filtering
|
|
||||||
// interop tests must trim the output bytes to the length of the packet.
|
|
||||||
// The BPF VM should not do this on its own, as other uses of it do
|
|
||||||
// not trim the output byte count.
|
|
||||||
trim := len(in) - udpHeaderLen
|
|
||||||
if goOut > trim {
|
|
||||||
goOut = trim
|
|
||||||
}
|
|
||||||
|
|
||||||
// When the OS VM is not available, process using the Go VM alone
|
|
||||||
if mvm.osVM == nil {
|
|
||||||
return goOut, goErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// The OS VM will apply its own UDP header, so remove the pseudo header
|
|
||||||
// that the Go VM needs.
|
|
||||||
osOut, err := mvm.osVM.Run(in[udpHeaderLen:])
|
|
||||||
if err != nil {
|
|
||||||
mvm.t.Fatalf("error while running OS VM: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify both VMs return same number of bytes
|
|
||||||
var mismatch bool
|
|
||||||
if goOut != osOut {
|
|
||||||
mismatch = true
|
|
||||||
mvm.t.Logf("output byte count does not match:\n- go: %v\n- os: %v", goOut, osOut)
|
|
||||||
}
|
|
||||||
|
|
||||||
if mismatch {
|
|
||||||
mvm.t.Fatal("Go BPF and OS BPF packet outputs do not match")
|
|
||||||
}
|
|
||||||
|
|
||||||
return goOut, goErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// An osVirtualMachine is a virtualMachine which uses the OS's BPF VM for
|
|
||||||
// processing BPF programs.
|
|
||||||
type osVirtualMachine struct {
|
|
||||||
l net.PacketConn
|
|
||||||
s net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
// testOSVM creates a virtualMachine which uses the OS's BPF VM by injecting
|
|
||||||
// packets into a UDP listener with a BPF program attached to it.
|
|
||||||
func testOSVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func()) {
|
|
||||||
l, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to open OS VM UDP listener: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
prog, err := bpf.Assemble(filter)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to compile BPF program: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p := ipv4.NewPacketConn(l)
|
|
||||||
if err = p.SetBPF(prog); err != nil {
|
|
||||||
t.Fatalf("failed to attach BPF program to listener: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s, err := net.Dial("udp4", l.LocalAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to dial connection to listener: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
done := func() {
|
|
||||||
_ = s.Close()
|
|
||||||
_ = l.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
return &osVirtualMachine{
|
|
||||||
l: l,
|
|
||||||
s: s,
|
|
||||||
}, done
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run sends the input bytes into the OS's BPF VM and returns its verdict.
|
|
||||||
func (vm *osVirtualMachine) Run(in []byte) (int, error) {
|
|
||||||
go func() {
|
|
||||||
_, _ = vm.s.Write(in)
|
|
||||||
}()
|
|
||||||
|
|
||||||
vm.l.SetDeadline(time.Now().Add(50 * time.Millisecond))
|
|
||||||
|
|
||||||
var b [512]byte
|
|
||||||
n, _, err := vm.l.ReadFrom(b[:])
|
|
||||||
if err != nil {
|
|
||||||
// A timeout indicates that BPF filtered out the packet, and thus,
|
|
||||||
// no input should be returned.
|
|
||||||
if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
// Copyright 2016 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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMLoadExtensionNotImplemented(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadExtension{
|
|
||||||
Num: 100,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "extension 100 not implemented" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadExtensionExtLen(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadExtension{
|
|
||||||
Num: bpf.ExtLen,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,181 +0,0 @@
|
||||||
// Copyright 2016 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 bpf
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func aluOpConstant(ins ALUOpConstant, regA uint32) uint32 {
|
|
||||||
return aluOpCommon(ins.Op, regA, ins.Val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func aluOpX(ins ALUOpX, regA uint32, regX uint32) (uint32, bool) {
|
|
||||||
// Guard against division or modulus by zero by terminating
|
|
||||||
// the program, as the OS BPF VM does
|
|
||||||
if regX == 0 {
|
|
||||||
switch ins.Op {
|
|
||||||
case ALUOpDiv, ALUOpMod:
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return aluOpCommon(ins.Op, regA, regX), true
|
|
||||||
}
|
|
||||||
|
|
||||||
func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 {
|
|
||||||
switch op {
|
|
||||||
case ALUOpAdd:
|
|
||||||
return regA + value
|
|
||||||
case ALUOpSub:
|
|
||||||
return regA - value
|
|
||||||
case ALUOpMul:
|
|
||||||
return regA * value
|
|
||||||
case ALUOpDiv:
|
|
||||||
// Division by zero not permitted by NewVM and aluOpX checks
|
|
||||||
return regA / value
|
|
||||||
case ALUOpOr:
|
|
||||||
return regA | value
|
|
||||||
case ALUOpAnd:
|
|
||||||
return regA & value
|
|
||||||
case ALUOpShiftLeft:
|
|
||||||
return regA << value
|
|
||||||
case ALUOpShiftRight:
|
|
||||||
return regA >> value
|
|
||||||
case ALUOpMod:
|
|
||||||
// Modulus by zero not permitted by NewVM and aluOpX checks
|
|
||||||
return regA % value
|
|
||||||
case ALUOpXor:
|
|
||||||
return regA ^ value
|
|
||||||
default:
|
|
||||||
return regA
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func jumpIf(ins JumpIf, regA uint32) int {
|
|
||||||
return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, ins.Val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func jumpIfX(ins JumpIfX, regA uint32, regX uint32) int {
|
|
||||||
return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, regX)
|
|
||||||
}
|
|
||||||
|
|
||||||
func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value uint32) int {
|
|
||||||
var ok bool
|
|
||||||
|
|
||||||
switch cond {
|
|
||||||
case JumpEqual:
|
|
||||||
ok = regA == value
|
|
||||||
case JumpNotEqual:
|
|
||||||
ok = regA != value
|
|
||||||
case JumpGreaterThan:
|
|
||||||
ok = regA > value
|
|
||||||
case JumpLessThan:
|
|
||||||
ok = regA < value
|
|
||||||
case JumpGreaterOrEqual:
|
|
||||||
ok = regA >= value
|
|
||||||
case JumpLessOrEqual:
|
|
||||||
ok = regA <= value
|
|
||||||
case JumpBitsSet:
|
|
||||||
ok = (regA & value) != 0
|
|
||||||
case JumpBitsNotSet:
|
|
||||||
ok = (regA & value) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
return int(skipTrue)
|
|
||||||
}
|
|
||||||
|
|
||||||
return int(skipFalse)
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {
|
|
||||||
offset := int(ins.Off)
|
|
||||||
size := int(ins.Size)
|
|
||||||
|
|
||||||
return loadCommon(in, offset, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) {
|
|
||||||
switch ins.Dst {
|
|
||||||
case RegA:
|
|
||||||
regA = ins.Val
|
|
||||||
case RegX:
|
|
||||||
regX = ins.Val
|
|
||||||
}
|
|
||||||
|
|
||||||
return regA, regX
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadExtension(ins LoadExtension, in []byte) uint32 {
|
|
||||||
switch ins.Num {
|
|
||||||
case ExtLen:
|
|
||||||
return uint32(len(in))
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unimplemented extension: %d", ins.Num))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {
|
|
||||||
offset := int(ins.Off) + int(regX)
|
|
||||||
size := int(ins.Size)
|
|
||||||
|
|
||||||
return loadCommon(in, offset, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) {
|
|
||||||
offset := int(ins.Off)
|
|
||||||
|
|
||||||
if !inBounds(len(in), offset, 0) {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mask off high 4 bits and multiply low 4 bits by 4
|
|
||||||
return uint32(in[offset]&0x0f) * 4, true
|
|
||||||
}
|
|
||||||
|
|
||||||
func inBounds(inLen int, offset int, size int) bool {
|
|
||||||
return offset+size <= inLen
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadCommon(in []byte, offset int, size int) (uint32, bool) {
|
|
||||||
if !inBounds(len(in), offset, size) {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch size {
|
|
||||||
case 1:
|
|
||||||
return uint32(in[offset]), true
|
|
||||||
case 2:
|
|
||||||
return uint32(binary.BigEndian.Uint16(in[offset : offset+size])), true
|
|
||||||
case 4:
|
|
||||||
return uint32(binary.BigEndian.Uint32(in[offset : offset+size])), true
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("invalid load size: %d", size))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadScratch(ins LoadScratch, regScratch [16]uint32, regA uint32, regX uint32) (uint32, uint32) {
|
|
||||||
switch ins.Dst {
|
|
||||||
case RegA:
|
|
||||||
regA = regScratch[ins.N]
|
|
||||||
case RegX:
|
|
||||||
regX = regScratch[ins.N]
|
|
||||||
}
|
|
||||||
|
|
||||||
return regA, regX
|
|
||||||
}
|
|
||||||
|
|
||||||
func storeScratch(ins StoreScratch, regScratch [16]uint32, regA uint32, regX uint32) [16]uint32 {
|
|
||||||
switch ins.Src {
|
|
||||||
case RegA:
|
|
||||||
regScratch[ins.N] = regA
|
|
||||||
case RegX:
|
|
||||||
regScratch[ins.N] = regX
|
|
||||||
}
|
|
||||||
|
|
||||||
return regScratch
|
|
||||||
}
|
|
|
@ -1,726 +0,0 @@
|
||||||
// Copyright 2016 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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMJumpOne(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.Jump{
|
|
||||||
Skip: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpOutOfProgram(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.Jump{
|
|
||||||
Skip: 1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot jump 1 instructions; jumping past program bounds" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfTrueOutOfProgram(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
SkipTrue: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfFalseOutOfProgram(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
SkipFalse: 3,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXTrueOutOfProgram(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
SkipTrue: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXFalseOutOfProgram(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
SkipFalse: 3,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 1,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfNotEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpNotEqual,
|
|
||||||
Val: 1,
|
|
||||||
SkipFalse: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfGreaterThan(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpGreaterThan,
|
|
||||||
Val: 0x00010202,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfLessThan(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpLessThan,
|
|
||||||
Val: 0xff010203,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfGreaterOrEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpGreaterOrEqual,
|
|
||||||
Val: 0x00010203,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfLessOrEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpLessOrEqual,
|
|
||||||
Val: 0xff010203,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfBitsSet(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpBitsSet,
|
|
||||||
Val: 0x1122,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x01, 0x02,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfBitsNotSet(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpBitsNotSet,
|
|
||||||
Val: 0x1221,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x01, 0x02,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 1,
|
|
||||||
},
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXNotEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 1,
|
|
||||||
},
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpNotEqual,
|
|
||||||
SkipFalse: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXGreaterThan(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 0x00010202,
|
|
||||||
},
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpGreaterThan,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXLessThan(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 0xff010203,
|
|
||||||
},
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpLessThan,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXGreaterOrEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 0x00010203,
|
|
||||||
},
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpGreaterOrEqual,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXLessOrEqual(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 4,
|
|
||||||
},
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 0xff010203,
|
|
||||||
},
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpLessOrEqual,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 12,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 4, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXBitsSet(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 0x1122,
|
|
||||||
},
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpBitsSet,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x01, 0x02,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMJumpIfXBitsNotSet(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 0x1221,
|
|
||||||
},
|
|
||||||
bpf.JumpIfX{
|
|
||||||
Cond: bpf.JumpBitsNotSet,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x01, 0x02,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,246 +0,0 @@
|
||||||
// Copyright 2016 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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMLoadAbsoluteOffsetOutOfBounds(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 100,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1, 2, 3,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadAbsoluteOffsetPlusSizeOutOfBounds(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadAbsoluteBadInstructionSize(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Size: 5,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid load byte length 0" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadConstantOK(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
bpf.TXA{},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadIndirectOutOfBounds(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadIndirect{
|
|
||||||
Off: 100,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadMemShiftOutOfBounds(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadMemShift{
|
|
||||||
Off: 100,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
dhcp4Port = 53
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMLoadMemShiftLoadIndirectNoResult(t *testing.T) {
|
|
||||||
vm, in, done := testDHCPv4(t)
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
// Append mostly empty UDP header with incorrect DHCPv4 port
|
|
||||||
in = append(in, []byte{
|
|
||||||
0, 0,
|
|
||||||
0, dhcp4Port + 1,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
}...)
|
|
||||||
|
|
||||||
out, err := vm.Run(in)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 0, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadMemShiftLoadIndirectOK(t *testing.T) {
|
|
||||||
vm, in, done := testDHCPv4(t)
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
// Append mostly empty UDP header with correct DHCPv4 port
|
|
||||||
in = append(in, []byte{
|
|
||||||
0, 0,
|
|
||||||
0, dhcp4Port,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
}...)
|
|
||||||
|
|
||||||
out, err := vm.Run(in)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := len(in)-8, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDHCPv4(t *testing.T) (virtualMachine, []byte, func()) {
|
|
||||||
// DHCPv4 test data courtesy of David Anderson:
|
|
||||||
// https://github.com/google/netboot/blob/master/dhcp4/conn_linux.go#L59-L70
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load IPv4 packet length
|
|
||||||
bpf.LoadMemShift{Off: 8},
|
|
||||||
// Get UDP dport
|
|
||||||
bpf.LoadIndirect{Off: 8 + 2, Size: 2},
|
|
||||||
// Correct dport?
|
|
||||||
bpf.JumpIf{Cond: bpf.JumpEqual, Val: dhcp4Port, SkipFalse: 1},
|
|
||||||
// Accept
|
|
||||||
bpf.RetConstant{Val: 1500},
|
|
||||||
// Ignore
|
|
||||||
bpf.RetConstant{Val: 0},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minimal requirements to make a valid IPv4 header
|
|
||||||
h := &ipv4.Header{
|
|
||||||
Len: ipv4.HeaderLen,
|
|
||||||
Src: net.IPv4(192, 168, 1, 1),
|
|
||||||
Dst: net.IPv4(192, 168, 1, 2),
|
|
||||||
}
|
|
||||||
hb, err := h.Marshal()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to marshal IPv4 header: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
hb = append([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
}, hb...)
|
|
||||||
|
|
||||||
return vm, hb, done
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
// Copyright 2016 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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMRetA(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
9,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMRetALargerThanInput(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 2,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 255,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMRetConstant(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 9,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 1, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMRetConstantLargerThanInput(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 16,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0, 1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,247 +0,0 @@
|
||||||
// Copyright 2016 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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVMStoreScratchInvalidScratchRegisterTooSmall(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: -1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMStoreScratchInvalidScratchRegisterTooLarge(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 16,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMStoreScratchUnknownSourceRegister(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: 100,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid source register 100" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadScratchInvalidScratchRegisterTooSmall(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
N: -1,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadScratchInvalidScratchRegisterTooLarge(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
N: 16,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMLoadScratchUnknownDestinationRegister(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: 100,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if errStr(err) != "assembling instruction 1: invalid target register 100" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMStoreScratchLoadScratchOneValue(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load byte 255
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Copy to X and store in scratch[0]
|
|
||||||
bpf.TAX{},
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegX,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
// Load byte 1
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 9,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Overwrite 1 with 255 from scratch[0]
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
// Return 255
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
255, 1, 2,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 3, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMStoreScratchLoadScratchMultipleValues(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
// Load byte 10
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 8,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Store in scratch[0]
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
// Load byte 20
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 9,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Store in scratch[1]
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 1,
|
|
||||||
},
|
|
||||||
// Load byte 30
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 10,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Store in scratch[2]
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 2,
|
|
||||||
},
|
|
||||||
// Load byte 1
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: 11,
|
|
||||||
Size: 1,
|
|
||||||
},
|
|
||||||
// Store in scratch[3]
|
|
||||||
bpf.StoreScratch{
|
|
||||||
Src: bpf.RegA,
|
|
||||||
N: 3,
|
|
||||||
},
|
|
||||||
// Load in byte 10 to X
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegX,
|
|
||||||
N: 0,
|
|
||||||
},
|
|
||||||
// Copy X -> A
|
|
||||||
bpf.TXA{},
|
|
||||||
// Verify value is 10
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 10,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
// Fail test if incorrect
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
// Load in byte 20 to A
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
N: 1,
|
|
||||||
},
|
|
||||||
// Verify value is 20
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 20,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
// Fail test if incorrect
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
// Load in byte 30 to A
|
|
||||||
bpf.LoadScratch{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
N: 2,
|
|
||||||
},
|
|
||||||
// Verify value is 30
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: 30,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
// Fail test if incorrect
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
// Return first two bytes on success
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 10,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to load BPF program: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
out, err := vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
10, 20, 30, 1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
if want, got := 2, out; want != got {
|
|
||||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
|
||||||
want, got)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,144 +0,0 @@
|
||||||
// Copyright 2016 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 bpf_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/bpf"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ bpf.Instruction = unknown{}
|
|
||||||
|
|
||||||
type unknown struct{}
|
|
||||||
|
|
||||||
func (unknown) Assemble() (bpf.RawInstruction, error) {
|
|
||||||
return bpf.RawInstruction{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMUnknownInstruction(t *testing.T) {
|
|
||||||
vm, done, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
Val: 100,
|
|
||||||
},
|
|
||||||
// Should terminate the program with an error immediately
|
|
||||||
unknown{},
|
|
||||||
bpf.RetA{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
defer done()
|
|
||||||
|
|
||||||
_, err = vm.Run([]byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x00,
|
|
||||||
})
|
|
||||||
if errStr(err) != "unknown Instruction at index 1: bpf_test.unknown" {
|
|
||||||
t.Fatalf("unexpected error while running program: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMNoReturnInstruction(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{
|
|
||||||
bpf.LoadConstant{
|
|
||||||
Dst: bpf.RegA,
|
|
||||||
Val: 1,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if errStr(err) != "BPF program must end with RetA or RetConstant" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMNoInputInstructions(t *testing.T) {
|
|
||||||
_, _, err := testVM(t, []bpf.Instruction{})
|
|
||||||
if errStr(err) != "one or more Instructions must be specified" {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExampleNewVM demonstrates usage of a VM, using an Ethernet frame
|
|
||||||
// as input and checking its EtherType to determine if it should be accepted.
|
|
||||||
func ExampleNewVM() {
|
|
||||||
// Offset | Length | Comment
|
|
||||||
// -------------------------
|
|
||||||
// 00 | 06 | Ethernet destination MAC address
|
|
||||||
// 06 | 06 | Ethernet source MAC address
|
|
||||||
// 12 | 02 | Ethernet EtherType
|
|
||||||
const (
|
|
||||||
etOff = 12
|
|
||||||
etLen = 2
|
|
||||||
|
|
||||||
etARP = 0x0806
|
|
||||||
)
|
|
||||||
|
|
||||||
// Set up a VM to filter traffic based on if its EtherType
|
|
||||||
// matches the ARP EtherType.
|
|
||||||
vm, err := bpf.NewVM([]bpf.Instruction{
|
|
||||||
// Load EtherType value from Ethernet header
|
|
||||||
bpf.LoadAbsolute{
|
|
||||||
Off: etOff,
|
|
||||||
Size: etLen,
|
|
||||||
},
|
|
||||||
// If EtherType is equal to the ARP EtherType, jump to allow
|
|
||||||
// packet to be accepted
|
|
||||||
bpf.JumpIf{
|
|
||||||
Cond: bpf.JumpEqual,
|
|
||||||
Val: etARP,
|
|
||||||
SkipTrue: 1,
|
|
||||||
},
|
|
||||||
// EtherType does not match the ARP EtherType
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 0,
|
|
||||||
},
|
|
||||||
// EtherType matches the ARP EtherType, accept up to 1500
|
|
||||||
// bytes of packet
|
|
||||||
bpf.RetConstant{
|
|
||||||
Val: 1500,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("failed to load BPF program: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an Ethernet frame with the ARP EtherType for testing
|
|
||||||
frame := []byte{
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
|
|
||||||
0x08, 0x06,
|
|
||||||
// Payload omitted for brevity
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run our VM's BPF program using the Ethernet frame as input
|
|
||||||
out, err := vm.Run(frame)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("failed to accept Ethernet frame: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// BPF VM can return a byte count greater than the number of input
|
|
||||||
// bytes, so trim the output to match the input byte length
|
|
||||||
if out > len(frame) {
|
|
||||||
out = len(frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("out: %d bytes", out)
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// out: 14 bytes
|
|
||||||
}
|
|
||||||
|
|
||||||
// errStr returns the string representation of an error, or
|
|
||||||
// "<nil>" if it is nil.
|
|
||||||
func errStr(err error) string {
|
|
||||||
if err == nil {
|
|
||||||
return "<nil>"
|
|
||||||
}
|
|
||||||
|
|
||||||
return err.Error()
|
|
||||||
}
|
|
|
@ -1,583 +0,0 @@
|
||||||
// Copyright 2014 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.
|
|
||||||
|
|
||||||
// +build !go1.7
|
|
||||||
|
|
||||||
package context
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// otherContext is a Context that's not one of the types defined in context.go.
|
|
||||||
// This lets us test code paths that differ based on the underlying type of the
|
|
||||||
// Context.
|
|
||||||
type otherContext struct {
|
|
||||||
Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBackground(t *testing.T) {
|
|
||||||
c := Background()
|
|
||||||
if c == nil {
|
|
||||||
t.Fatalf("Background returned nil")
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case x := <-c.Done():
|
|
||||||
t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
if got, want := fmt.Sprint(c), "context.Background"; got != want {
|
|
||||||
t.Errorf("Background().String() = %q want %q", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTODO(t *testing.T) {
|
|
||||||
c := TODO()
|
|
||||||
if c == nil {
|
|
||||||
t.Fatalf("TODO returned nil")
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case x := <-c.Done():
|
|
||||||
t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
if got, want := fmt.Sprint(c), "context.TODO"; got != want {
|
|
||||||
t.Errorf("TODO().String() = %q want %q", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWithCancel(t *testing.T) {
|
|
||||||
c1, cancel := WithCancel(Background())
|
|
||||||
|
|
||||||
if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want {
|
|
||||||
t.Errorf("c1.String() = %q want %q", got, want)
|
|
||||||
}
|
|
||||||
|
|
||||||
o := otherContext{c1}
|
|
||||||
c2, _ := WithCancel(o)
|
|
||||||
contexts := []Context{c1, o, c2}
|
|
||||||
|
|
||||||
for i, c := range contexts {
|
|
||||||
if d := c.Done(); d == nil {
|
|
||||||
t.Errorf("c[%d].Done() == %v want non-nil", i, d)
|
|
||||||
}
|
|
||||||
if e := c.Err(); e != nil {
|
|
||||||
t.Errorf("c[%d].Err() == %v want nil", i, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case x := <-c.Done():
|
|
||||||
t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel()
|
|
||||||
time.Sleep(100 * time.Millisecond) // let cancelation propagate
|
|
||||||
|
|
||||||
for i, c := range contexts {
|
|
||||||
select {
|
|
||||||
case <-c.Done():
|
|
||||||
default:
|
|
||||||
t.Errorf("<-c[%d].Done() blocked, but shouldn't have", i)
|
|
||||||
}
|
|
||||||
if e := c.Err(); e != Canceled {
|
|
||||||
t.Errorf("c[%d].Err() == %v want %v", i, e, Canceled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParentFinishesChild(t *testing.T) {
|
|
||||||
// Context tree:
|
|
||||||
// parent -> cancelChild
|
|
||||||
// parent -> valueChild -> timerChild
|
|
||||||
parent, cancel := WithCancel(Background())
|
|
||||||
cancelChild, stop := WithCancel(parent)
|
|
||||||
defer stop()
|
|
||||||
valueChild := WithValue(parent, "key", "value")
|
|
||||||
timerChild, stop := WithTimeout(valueChild, 10000*time.Hour)
|
|
||||||
defer stop()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case x := <-parent.Done():
|
|
||||||
t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
|
|
||||||
case x := <-cancelChild.Done():
|
|
||||||
t.Errorf("<-cancelChild.Done() == %v want nothing (it should block)", x)
|
|
||||||
case x := <-timerChild.Done():
|
|
||||||
t.Errorf("<-timerChild.Done() == %v want nothing (it should block)", x)
|
|
||||||
case x := <-valueChild.Done():
|
|
||||||
t.Errorf("<-valueChild.Done() == %v want nothing (it should block)", x)
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
// The parent's children should contain the two cancelable children.
|
|
||||||
pc := parent.(*cancelCtx)
|
|
||||||
cc := cancelChild.(*cancelCtx)
|
|
||||||
tc := timerChild.(*timerCtx)
|
|
||||||
pc.mu.Lock()
|
|
||||||
if len(pc.children) != 2 || !pc.children[cc] || !pc.children[tc] {
|
|
||||||
t.Errorf("bad linkage: pc.children = %v, want %v and %v",
|
|
||||||
pc.children, cc, tc)
|
|
||||||
}
|
|
||||||
pc.mu.Unlock()
|
|
||||||
|
|
||||||
if p, ok := parentCancelCtx(cc.Context); !ok || p != pc {
|
|
||||||
t.Errorf("bad linkage: parentCancelCtx(cancelChild.Context) = %v, %v want %v, true", p, ok, pc)
|
|
||||||
}
|
|
||||||
if p, ok := parentCancelCtx(tc.Context); !ok || p != pc {
|
|
||||||
t.Errorf("bad linkage: parentCancelCtx(timerChild.Context) = %v, %v want %v, true", p, ok, pc)
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel()
|
|
||||||
|
|
||||||
pc.mu.Lock()
|
|
||||||
if len(pc.children) != 0 {
|
|
||||||
t.Errorf("pc.cancel didn't clear pc.children = %v", pc.children)
|
|
||||||
}
|
|
||||||
pc.mu.Unlock()
|
|
||||||
|
|
||||||
// parent and children should all be finished.
|
|
||||||
check := func(ctx Context, name string) {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
default:
|
|
||||||
t.Errorf("<-%s.Done() blocked, but shouldn't have", name)
|
|
||||||
}
|
|
||||||
if e := ctx.Err(); e != Canceled {
|
|
||||||
t.Errorf("%s.Err() == %v want %v", name, e, Canceled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
check(parent, "parent")
|
|
||||||
check(cancelChild, "cancelChild")
|
|
||||||
check(valueChild, "valueChild")
|
|
||||||
check(timerChild, "timerChild")
|
|
||||||
|
|
||||||
// WithCancel should return a canceled context on a canceled parent.
|
|
||||||
precanceledChild := WithValue(parent, "key", "value")
|
|
||||||
select {
|
|
||||||
case <-precanceledChild.Done():
|
|
||||||
default:
|
|
||||||
t.Errorf("<-precanceledChild.Done() blocked, but shouldn't have")
|
|
||||||
}
|
|
||||||
if e := precanceledChild.Err(); e != Canceled {
|
|
||||||
t.Errorf("precanceledChild.Err() == %v want %v", e, Canceled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChildFinishesFirst(t *testing.T) {
|
|
||||||
cancelable, stop := WithCancel(Background())
|
|
||||||
defer stop()
|
|
||||||
for _, parent := range []Context{Background(), cancelable} {
|
|
||||||
child, cancel := WithCancel(parent)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case x := <-parent.Done():
|
|
||||||
t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
|
|
||||||
case x := <-child.Done():
|
|
||||||
t.Errorf("<-child.Done() == %v want nothing (it should block)", x)
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
cc := child.(*cancelCtx)
|
|
||||||
pc, pcok := parent.(*cancelCtx) // pcok == false when parent == Background()
|
|
||||||
if p, ok := parentCancelCtx(cc.Context); ok != pcok || (ok && pc != p) {
|
|
||||||
t.Errorf("bad linkage: parentCancelCtx(cc.Context) = %v, %v want %v, %v", p, ok, pc, pcok)
|
|
||||||
}
|
|
||||||
|
|
||||||
if pcok {
|
|
||||||
pc.mu.Lock()
|
|
||||||
if len(pc.children) != 1 || !pc.children[cc] {
|
|
||||||
t.Errorf("bad linkage: pc.children = %v, cc = %v", pc.children, cc)
|
|
||||||
}
|
|
||||||
pc.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel()
|
|
||||||
|
|
||||||
if pcok {
|
|
||||||
pc.mu.Lock()
|
|
||||||
if len(pc.children) != 0 {
|
|
||||||
t.Errorf("child's cancel didn't remove self from pc.children = %v", pc.children)
|
|
||||||
}
|
|
||||||
pc.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// child should be finished.
|
|
||||||
select {
|
|
||||||
case <-child.Done():
|
|
||||||
default:
|
|
||||||
t.Errorf("<-child.Done() blocked, but shouldn't have")
|
|
||||||
}
|
|
||||||
if e := child.Err(); e != Canceled {
|
|
||||||
t.Errorf("child.Err() == %v want %v", e, Canceled)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parent should not be finished.
|
|
||||||
select {
|
|
||||||
case x := <-parent.Done():
|
|
||||||
t.Errorf("<-parent.Done() == %v want nothing (it should block)", x)
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
if e := parent.Err(); e != nil {
|
|
||||||
t.Errorf("parent.Err() == %v want nil", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDeadline(c Context, wait time.Duration, t *testing.T) {
|
|
||||||
select {
|
|
||||||
case <-time.After(wait):
|
|
||||||
t.Fatalf("context should have timed out")
|
|
||||||
case <-c.Done():
|
|
||||||
}
|
|
||||||
if e := c.Err(); e != DeadlineExceeded {
|
|
||||||
t.Errorf("c.Err() == %v want %v", e, DeadlineExceeded)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeadline(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
const timeUnit = 500 * time.Millisecond
|
|
||||||
c, _ := WithDeadline(Background(), time.Now().Add(1*timeUnit))
|
|
||||||
if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
|
|
||||||
t.Errorf("c.String() = %q want prefix %q", got, prefix)
|
|
||||||
}
|
|
||||||
testDeadline(c, 2*timeUnit, t)
|
|
||||||
|
|
||||||
c, _ = WithDeadline(Background(), time.Now().Add(1*timeUnit))
|
|
||||||
o := otherContext{c}
|
|
||||||
testDeadline(o, 2*timeUnit, t)
|
|
||||||
|
|
||||||
c, _ = WithDeadline(Background(), time.Now().Add(1*timeUnit))
|
|
||||||
o = otherContext{c}
|
|
||||||
c, _ = WithDeadline(o, time.Now().Add(3*timeUnit))
|
|
||||||
testDeadline(c, 2*timeUnit, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimeout(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
const timeUnit = 500 * time.Millisecond
|
|
||||||
c, _ := WithTimeout(Background(), 1*timeUnit)
|
|
||||||
if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
|
|
||||||
t.Errorf("c.String() = %q want prefix %q", got, prefix)
|
|
||||||
}
|
|
||||||
testDeadline(c, 2*timeUnit, t)
|
|
||||||
|
|
||||||
c, _ = WithTimeout(Background(), 1*timeUnit)
|
|
||||||
o := otherContext{c}
|
|
||||||
testDeadline(o, 2*timeUnit, t)
|
|
||||||
|
|
||||||
c, _ = WithTimeout(Background(), 1*timeUnit)
|
|
||||||
o = otherContext{c}
|
|
||||||
c, _ = WithTimeout(o, 3*timeUnit)
|
|
||||||
testDeadline(c, 2*timeUnit, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCanceledTimeout(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
const timeUnit = 500 * time.Millisecond
|
|
||||||
c, _ := WithTimeout(Background(), 2*timeUnit)
|
|
||||||
o := otherContext{c}
|
|
||||||
c, cancel := WithTimeout(o, 4*timeUnit)
|
|
||||||
cancel()
|
|
||||||
time.Sleep(1 * timeUnit) // let cancelation propagate
|
|
||||||
select {
|
|
||||||
case <-c.Done():
|
|
||||||
default:
|
|
||||||
t.Errorf("<-c.Done() blocked, but shouldn't have")
|
|
||||||
}
|
|
||||||
if e := c.Err(); e != Canceled {
|
|
||||||
t.Errorf("c.Err() == %v want %v", e, Canceled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type key1 int
|
|
||||||
type key2 int
|
|
||||||
|
|
||||||
var k1 = key1(1)
|
|
||||||
var k2 = key2(1) // same int as k1, different type
|
|
||||||
var k3 = key2(3) // same type as k2, different int
|
|
||||||
|
|
||||||
func TestValues(t *testing.T) {
|
|
||||||
check := func(c Context, nm, v1, v2, v3 string) {
|
|
||||||
if v, ok := c.Value(k1).(string); ok == (len(v1) == 0) || v != v1 {
|
|
||||||
t.Errorf(`%s.Value(k1).(string) = %q, %t want %q, %t`, nm, v, ok, v1, len(v1) != 0)
|
|
||||||
}
|
|
||||||
if v, ok := c.Value(k2).(string); ok == (len(v2) == 0) || v != v2 {
|
|
||||||
t.Errorf(`%s.Value(k2).(string) = %q, %t want %q, %t`, nm, v, ok, v2, len(v2) != 0)
|
|
||||||
}
|
|
||||||
if v, ok := c.Value(k3).(string); ok == (len(v3) == 0) || v != v3 {
|
|
||||||
t.Errorf(`%s.Value(k3).(string) = %q, %t want %q, %t`, nm, v, ok, v3, len(v3) != 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c0 := Background()
|
|
||||||
check(c0, "c0", "", "", "")
|
|
||||||
|
|
||||||
c1 := WithValue(Background(), k1, "c1k1")
|
|
||||||
check(c1, "c1", "c1k1", "", "")
|
|
||||||
|
|
||||||
if got, want := fmt.Sprint(c1), `context.Background.WithValue(1, "c1k1")`; got != want {
|
|
||||||
t.Errorf("c.String() = %q want %q", got, want)
|
|
||||||
}
|
|
||||||
|
|
||||||
c2 := WithValue(c1, k2, "c2k2")
|
|
||||||
check(c2, "c2", "c1k1", "c2k2", "")
|
|
||||||
|
|
||||||
c3 := WithValue(c2, k3, "c3k3")
|
|
||||||
check(c3, "c2", "c1k1", "c2k2", "c3k3")
|
|
||||||
|
|
||||||
c4 := WithValue(c3, k1, nil)
|
|
||||||
check(c4, "c4", "", "c2k2", "c3k3")
|
|
||||||
|
|
||||||
o0 := otherContext{Background()}
|
|
||||||
check(o0, "o0", "", "", "")
|
|
||||||
|
|
||||||
o1 := otherContext{WithValue(Background(), k1, "c1k1")}
|
|
||||||
check(o1, "o1", "c1k1", "", "")
|
|
||||||
|
|
||||||
o2 := WithValue(o1, k2, "o2k2")
|
|
||||||
check(o2, "o2", "c1k1", "o2k2", "")
|
|
||||||
|
|
||||||
o3 := otherContext{c4}
|
|
||||||
check(o3, "o3", "", "c2k2", "c3k3")
|
|
||||||
|
|
||||||
o4 := WithValue(o3, k3, nil)
|
|
||||||
check(o4, "o4", "", "c2k2", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAllocs(t *testing.T) {
|
|
||||||
bg := Background()
|
|
||||||
for _, test := range []struct {
|
|
||||||
desc string
|
|
||||||
f func()
|
|
||||||
limit float64
|
|
||||||
gccgoLimit float64
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
desc: "Background()",
|
|
||||||
f: func() { Background() },
|
|
||||||
limit: 0,
|
|
||||||
gccgoLimit: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: fmt.Sprintf("WithValue(bg, %v, nil)", k1),
|
|
||||||
f: func() {
|
|
||||||
c := WithValue(bg, k1, nil)
|
|
||||||
c.Value(k1)
|
|
||||||
},
|
|
||||||
limit: 3,
|
|
||||||
gccgoLimit: 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "WithTimeout(bg, 15*time.Millisecond)",
|
|
||||||
f: func() {
|
|
||||||
c, _ := WithTimeout(bg, 15*time.Millisecond)
|
|
||||||
<-c.Done()
|
|
||||||
},
|
|
||||||
limit: 8,
|
|
||||||
gccgoLimit: 16,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "WithCancel(bg)",
|
|
||||||
f: func() {
|
|
||||||
c, cancel := WithCancel(bg)
|
|
||||||
cancel()
|
|
||||||
<-c.Done()
|
|
||||||
},
|
|
||||||
limit: 5,
|
|
||||||
gccgoLimit: 8,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "WithTimeout(bg, 100*time.Millisecond)",
|
|
||||||
f: func() {
|
|
||||||
c, cancel := WithTimeout(bg, 100*time.Millisecond)
|
|
||||||
cancel()
|
|
||||||
<-c.Done()
|
|
||||||
},
|
|
||||||
limit: 8,
|
|
||||||
gccgoLimit: 25,
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
limit := test.limit
|
|
||||||
if runtime.Compiler == "gccgo" {
|
|
||||||
// gccgo does not yet do escape analysis.
|
|
||||||
// TODO(iant): Remove this when gccgo does do escape analysis.
|
|
||||||
limit = test.gccgoLimit
|
|
||||||
}
|
|
||||||
if n := testing.AllocsPerRun(100, test.f); n > limit {
|
|
||||||
t.Errorf("%s allocs = %f want %d", test.desc, n, int(limit))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSimultaneousCancels(t *testing.T) {
|
|
||||||
root, cancel := WithCancel(Background())
|
|
||||||
m := map[Context]CancelFunc{root: cancel}
|
|
||||||
q := []Context{root}
|
|
||||||
// Create a tree of contexts.
|
|
||||||
for len(q) != 0 && len(m) < 100 {
|
|
||||||
parent := q[0]
|
|
||||||
q = q[1:]
|
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
ctx, cancel := WithCancel(parent)
|
|
||||||
m[ctx] = cancel
|
|
||||||
q = append(q, ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Start all the cancels in a random order.
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(len(m))
|
|
||||||
for _, cancel := range m {
|
|
||||||
go func(cancel CancelFunc) {
|
|
||||||
cancel()
|
|
||||||
wg.Done()
|
|
||||||
}(cancel)
|
|
||||||
}
|
|
||||||
// Wait on all the contexts in a random order.
|
|
||||||
for ctx := range m {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
case <-time.After(1 * time.Second):
|
|
||||||
buf := make([]byte, 10<<10)
|
|
||||||
n := runtime.Stack(buf, true)
|
|
||||||
t.Fatalf("timed out waiting for <-ctx.Done(); stacks:\n%s", buf[:n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Wait for all the cancel functions to return.
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
wg.Wait()
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
case <-time.After(1 * time.Second):
|
|
||||||
buf := make([]byte, 10<<10)
|
|
||||||
n := runtime.Stack(buf, true)
|
|
||||||
t.Fatalf("timed out waiting for cancel functions; stacks:\n%s", buf[:n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInterlockedCancels(t *testing.T) {
|
|
||||||
parent, cancelParent := WithCancel(Background())
|
|
||||||
child, cancelChild := WithCancel(parent)
|
|
||||||
go func() {
|
|
||||||
parent.Done()
|
|
||||||
cancelChild()
|
|
||||||
}()
|
|
||||||
cancelParent()
|
|
||||||
select {
|
|
||||||
case <-child.Done():
|
|
||||||
case <-time.After(1 * time.Second):
|
|
||||||
buf := make([]byte, 10<<10)
|
|
||||||
n := runtime.Stack(buf, true)
|
|
||||||
t.Fatalf("timed out waiting for child.Done(); stacks:\n%s", buf[:n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLayersCancel(t *testing.T) {
|
|
||||||
testLayers(t, time.Now().UnixNano(), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLayersTimeout(t *testing.T) {
|
|
||||||
testLayers(t, time.Now().UnixNano(), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testLayers(t *testing.T, seed int64, testTimeout bool) {
|
|
||||||
rand.Seed(seed)
|
|
||||||
errorf := func(format string, a ...interface{}) {
|
|
||||||
t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...)
|
|
||||||
}
|
|
||||||
const (
|
|
||||||
timeout = 200 * time.Millisecond
|
|
||||||
minLayers = 30
|
|
||||||
)
|
|
||||||
type value int
|
|
||||||
var (
|
|
||||||
vals []*value
|
|
||||||
cancels []CancelFunc
|
|
||||||
numTimers int
|
|
||||||
ctx = Background()
|
|
||||||
)
|
|
||||||
for i := 0; i < minLayers || numTimers == 0 || len(cancels) == 0 || len(vals) == 0; i++ {
|
|
||||||
switch rand.Intn(3) {
|
|
||||||
case 0:
|
|
||||||
v := new(value)
|
|
||||||
ctx = WithValue(ctx, v, v)
|
|
||||||
vals = append(vals, v)
|
|
||||||
case 1:
|
|
||||||
var cancel CancelFunc
|
|
||||||
ctx, cancel = WithCancel(ctx)
|
|
||||||
cancels = append(cancels, cancel)
|
|
||||||
case 2:
|
|
||||||
var cancel CancelFunc
|
|
||||||
ctx, cancel = WithTimeout(ctx, timeout)
|
|
||||||
cancels = append(cancels, cancel)
|
|
||||||
numTimers++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkValues := func(when string) {
|
|
||||||
for _, key := range vals {
|
|
||||||
if val := ctx.Value(key).(*value); key != val {
|
|
||||||
errorf("%s: ctx.Value(%p) = %p want %p", when, key, val, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
errorf("ctx should not be canceled yet")
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
if s, prefix := fmt.Sprint(ctx), "context.Background."; !strings.HasPrefix(s, prefix) {
|
|
||||||
t.Errorf("ctx.String() = %q want prefix %q", s, prefix)
|
|
||||||
}
|
|
||||||
t.Log(ctx)
|
|
||||||
checkValues("before cancel")
|
|
||||||
if testTimeout {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
case <-time.After(timeout + 100*time.Millisecond):
|
|
||||||
errorf("ctx should have timed out")
|
|
||||||
}
|
|
||||||
checkValues("after timeout")
|
|
||||||
} else {
|
|
||||||
cancel := cancels[rand.Intn(len(cancels))]
|
|
||||||
cancel()
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
default:
|
|
||||||
errorf("ctx should be canceled")
|
|
||||||
}
|
|
||||||
checkValues("after cancel")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCancelRemoves(t *testing.T) {
|
|
||||||
checkChildren := func(when string, ctx Context, want int) {
|
|
||||||
if got := len(ctx.(*cancelCtx).children); got != want {
|
|
||||||
t.Errorf("%s: context has %d children, want %d", when, got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, _ := WithCancel(Background())
|
|
||||||
checkChildren("after creation", ctx, 0)
|
|
||||||
_, cancel := WithCancel(ctx)
|
|
||||||
checkChildren("with WithCancel child ", ctx, 1)
|
|
||||||
cancel()
|
|
||||||
checkChildren("after cancelling WithCancel child", ctx, 0)
|
|
||||||
|
|
||||||
ctx, _ = WithCancel(Background())
|
|
||||||
checkChildren("after creation", ctx, 0)
|
|
||||||
_, cancel = WithTimeout(ctx, 60*time.Minute)
|
|
||||||
checkChildren("with WithTimeout child ", ctx, 1)
|
|
||||||
cancel()
|
|
||||||
checkChildren("after cancelling WithTimeout child", ctx, 0)
|
|
||||||
}
|
|
|
@ -1,117 +0,0 @@
|
||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// +build !plan9
|
|
||||||
|
|
||||||
package ctxhttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGo17Context(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
io.WriteString(w, "ok")
|
|
||||||
}))
|
|
||||||
defer ts.Close()
|
|
||||||
ctx := context.Background()
|
|
||||||
resp, err := Get(ctx, http.DefaultClient, ts.URL)
|
|
||||||
if resp == nil || err != nil {
|
|
||||||
t.Fatalf("error received from client: %v %v", err, resp)
|
|
||||||
}
|
|
||||||
resp.Body.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
requestDuration = 100 * time.Millisecond
|
|
||||||
requestBody = "ok"
|
|
||||||
)
|
|
||||||
|
|
||||||
func okHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
time.Sleep(requestDuration)
|
|
||||||
io.WriteString(w, requestBody)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNoTimeout(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(okHandler))
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
res, err := Get(ctx, nil, ts.URL)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
slurp, err := ioutil.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(slurp) != requestBody {
|
|
||||||
t.Errorf("body = %q; want %q", slurp, requestBody)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCancelBeforeHeaders(t *testing.T) {
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
|
|
||||||
blockServer := make(chan struct{})
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
cancel()
|
|
||||||
<-blockServer
|
|
||||||
io.WriteString(w, requestBody)
|
|
||||||
}))
|
|
||||||
defer ts.Close()
|
|
||||||
defer close(blockServer)
|
|
||||||
|
|
||||||
res, err := Get(ctx, nil, ts.URL)
|
|
||||||
if err == nil {
|
|
||||||
res.Body.Close()
|
|
||||||
t.Fatal("Get returned unexpected nil error")
|
|
||||||
}
|
|
||||||
if err != context.Canceled {
|
|
||||||
t.Errorf("err = %v; want %v", err, context.Canceled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCancelAfterHangingRequest(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.(http.Flusher).Flush()
|
|
||||||
<-w.(http.CloseNotifier).CloseNotify()
|
|
||||||
}))
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
resp, err := Get(ctx, nil, ts.URL)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error in Get: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel befer reading the body.
|
|
||||||
// Reading Request.Body should fail, since the request was
|
|
||||||
// canceled before anything was written.
|
|
||||||
cancel()
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
b, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if len(b) != 0 || err == nil {
|
|
||||||
t.Errorf(`Read got (%q, %v); want ("", error)`, b, err)
|
|
||||||
}
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-time.After(1 * time.Second):
|
|
||||||
t.Errorf("Test timed out")
|
|
||||||
case <-done:
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
// Copyright 2014 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 context_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This example passes a context with a timeout to tell a blocking function that
|
|
||||||
// it should abandon its work after the timeout elapses.
|
|
||||||
func ExampleWithTimeout() {
|
|
||||||
// Pass a context with a timeout to tell a blocking function that it
|
|
||||||
// should abandon its work after the timeout elapses.
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-time.After(1 * time.Second):
|
|
||||||
fmt.Println("overslept")
|
|
||||||
case <-ctx.Done():
|
|
||||||
fmt.Println(ctx.Err()) // prints "context deadline exceeded"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// context deadline exceeded
|
|
||||||
}
|
|
|
@ -1,210 +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 dict implements the Dictionary Server Protocol
|
|
||||||
// as defined in RFC 2229.
|
|
||||||
package dict // import "golang.org/x/net/dict"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/textproto"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Client represents a client connection to a dictionary server.
|
|
||||||
type Client struct {
|
|
||||||
text *textproto.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dial returns a new client connected to a dictionary server at
|
|
||||||
// addr on the given network.
|
|
||||||
func Dial(network, addr string) (*Client, error) {
|
|
||||||
text, err := textproto.Dial(network, addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
_, _, err = text.ReadCodeLine(220)
|
|
||||||
if err != nil {
|
|
||||||
text.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Client{text: text}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the connection to the dictionary server.
|
|
||||||
func (c *Client) Close() error {
|
|
||||||
return c.text.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Dict represents a dictionary available on the server.
|
|
||||||
type Dict struct {
|
|
||||||
Name string // short name of dictionary
|
|
||||||
Desc string // long description
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dicts returns a list of the dictionaries available on the server.
|
|
||||||
func (c *Client) Dicts() ([]Dict, error) {
|
|
||||||
id, err := c.text.Cmd("SHOW DB")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
c.text.StartResponse(id)
|
|
||||||
defer c.text.EndResponse(id)
|
|
||||||
|
|
||||||
_, _, err = c.text.ReadCodeLine(110)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
lines, err := c.text.ReadDotLines()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
_, _, err = c.text.ReadCodeLine(250)
|
|
||||||
|
|
||||||
dicts := make([]Dict, len(lines))
|
|
||||||
for i := range dicts {
|
|
||||||
d := &dicts[i]
|
|
||||||
a, _ := fields(lines[i])
|
|
||||||
if len(a) < 2 {
|
|
||||||
return nil, textproto.ProtocolError("invalid dictionary: " + lines[i])
|
|
||||||
}
|
|
||||||
d.Name = a[0]
|
|
||||||
d.Desc = a[1]
|
|
||||||
}
|
|
||||||
return dicts, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Defn represents a definition.
|
|
||||||
type Defn struct {
|
|
||||||
Dict Dict // Dict where definition was found
|
|
||||||
Word string // Word being defined
|
|
||||||
Text []byte // Definition text, typically multiple lines
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define requests the definition of the given word.
|
|
||||||
// The argument dict names the dictionary to use,
|
|
||||||
// the Name field of a Dict returned by Dicts.
|
|
||||||
//
|
|
||||||
// The special dictionary name "*" means to look in all the
|
|
||||||
// server's dictionaries.
|
|
||||||
// The special dictionary name "!" means to look in all the
|
|
||||||
// server's dictionaries in turn, stopping after finding the word
|
|
||||||
// in one of them.
|
|
||||||
func (c *Client) Define(dict, word string) ([]*Defn, error) {
|
|
||||||
id, err := c.text.Cmd("DEFINE %s %q", dict, word)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
c.text.StartResponse(id)
|
|
||||||
defer c.text.EndResponse(id)
|
|
||||||
|
|
||||||
_, line, err := c.text.ReadCodeLine(150)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
a, _ := fields(line)
|
|
||||||
if len(a) < 1 {
|
|
||||||
return nil, textproto.ProtocolError("malformed response: " + line)
|
|
||||||
}
|
|
||||||
n, err := strconv.Atoi(a[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil, textproto.ProtocolError("invalid definition count: " + a[0])
|
|
||||||
}
|
|
||||||
def := make([]*Defn, n)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
_, line, err = c.text.ReadCodeLine(151)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
a, _ := fields(line)
|
|
||||||
if len(a) < 3 {
|
|
||||||
// skip it, to keep protocol in sync
|
|
||||||
i--
|
|
||||||
n--
|
|
||||||
def = def[0:n]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
d := &Defn{Word: a[0], Dict: Dict{a[1], a[2]}}
|
|
||||||
d.Text, err = c.text.ReadDotBytes()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
def[i] = d
|
|
||||||
}
|
|
||||||
_, _, err = c.text.ReadCodeLine(250)
|
|
||||||
return def, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fields returns the fields in s.
|
|
||||||
// Fields are space separated unquoted words
|
|
||||||
// or quoted with single or double quote.
|
|
||||||
func fields(s string) ([]string, error) {
|
|
||||||
var v []string
|
|
||||||
i := 0
|
|
||||||
for {
|
|
||||||
for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if i >= len(s) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if s[i] == '"' || s[i] == '\'' {
|
|
||||||
q := s[i]
|
|
||||||
// quoted string
|
|
||||||
var j int
|
|
||||||
for j = i + 1; ; j++ {
|
|
||||||
if j >= len(s) {
|
|
||||||
return nil, textproto.ProtocolError("malformed quoted string")
|
|
||||||
}
|
|
||||||
if s[j] == '\\' {
|
|
||||||
j++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if s[j] == q {
|
|
||||||
j++
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v = append(v, unquote(s[i+1:j-1]))
|
|
||||||
i = j
|
|
||||||
} else {
|
|
||||||
// atom
|
|
||||||
var j int
|
|
||||||
for j = i; j < len(s); j++ {
|
|
||||||
if s[j] == ' ' || s[j] == '\t' || s[j] == '\\' || s[j] == '"' || s[j] == '\'' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v = append(v, s[i:j])
|
|
||||||
i = j
|
|
||||||
}
|
|
||||||
if i < len(s) {
|
|
||||||
c := s[i]
|
|
||||||
if c != ' ' && c != '\t' {
|
|
||||||
return nil, textproto.ProtocolError("quotes not on word boundaries")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unquote(s string) string {
|
|
||||||
if strings.Index(s, "\\") < 0 {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
b := []byte(s)
|
|
||||||
w := 0
|
|
||||||
for r := 0; r < len(b); r++ {
|
|
||||||
c := b[r]
|
|
||||||
if c == '\\' {
|
|
||||||
r++
|
|
||||||
c = b[r]
|
|
||||||
}
|
|
||||||
b[w] = c
|
|
||||||
w++
|
|
||||||
}
|
|
||||||
return string(b[0:w])
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
// Copyright 2017 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 dnsmessage_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/net/dns/dnsmessage"
|
|
||||||
)
|
|
||||||
|
|
||||||
func mustNewName(name string) dnsmessage.Name {
|
|
||||||
n, err := dnsmessage.NewName(name)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleParser() {
|
|
||||||
msg := dnsmessage.Message{
|
|
||||||
Header: dnsmessage.Header{Response: true, Authoritative: true},
|
|
||||||
Questions: []dnsmessage.Question{
|
|
||||||
{
|
|
||||||
Name: mustNewName("foo.bar.example.com."),
|
|
||||||
Type: dnsmessage.TypeA,
|
|
||||||
Class: dnsmessage.ClassINET,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: mustNewName("bar.example.com."),
|
|
||||||
Type: dnsmessage.TypeA,
|
|
||||||
Class: dnsmessage.ClassINET,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Answers: []dnsmessage.Resource{
|
|
||||||
{
|
|
||||||
Header: dnsmessage.ResourceHeader{
|
|
||||||
Name: mustNewName("foo.bar.example.com."),
|
|
||||||
Type: dnsmessage.TypeA,
|
|
||||||
Class: dnsmessage.ClassINET,
|
|
||||||
},
|
|
||||||
Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 1}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Header: dnsmessage.ResourceHeader{
|
|
||||||
Name: mustNewName("bar.example.com."),
|
|
||||||
Type: dnsmessage.TypeA,
|
|
||||||
Class: dnsmessage.ClassINET,
|
|
||||||
},
|
|
||||||
Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 2}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
buf, err := msg.Pack()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wantName := "bar.example.com."
|
|
||||||
|
|
||||||
var p dnsmessage.Parser
|
|
||||||
if _, err := p.Start(buf); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
q, err := p.Question()
|
|
||||||
if err == dnsmessage.ErrSectionDone {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if q.Name.String() != wantName {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Found question for name", wantName)
|
|
||||||
if err := p.SkipAllQuestions(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
var gotIPs []net.IP
|
|
||||||
for {
|
|
||||||
h, err := p.AnswerHeader()
|
|
||||||
if err == dnsmessage.ErrSectionDone {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h.Type != dnsmessage.TypeA && h.Type != dnsmessage.TypeAAAA) || h.Class != dnsmessage.ClassINET {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.EqualFold(h.Name.String(), wantName) {
|
|
||||||
if err := p.SkipAnswer(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch h.Type {
|
|
||||||
case dnsmessage.TypeA:
|
|
||||||
r, err := p.AResource()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
gotIPs = append(gotIPs, r.A[:])
|
|
||||||
case dnsmessage.TypeAAAA:
|
|
||||||
r, err := p.AAAAResource()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
gotIPs = append(gotIPs, r.AAAA[:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Found A/AAAA records for name %s: %v\n", wantName, gotIPs)
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// Found question for name bar.example.com.
|
|
||||||
// Found A/AAAA records for name bar.example.com.: [127.0.0.2]
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,109 +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 atom
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestKnown(t *testing.T) {
|
|
||||||
for _, s := range testAtomList {
|
|
||||||
if atom := Lookup([]byte(s)); atom.String() != s {
|
|
||||||
t.Errorf("Lookup(%q) = %#x (%q)", s, uint32(atom), atom.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHits(t *testing.T) {
|
|
||||||
for _, a := range table {
|
|
||||||
if a == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
got := Lookup([]byte(a.String()))
|
|
||||||
if got != a {
|
|
||||||
t.Errorf("Lookup(%q) = %#x, want %#x", a.String(), uint32(got), uint32(a))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMisses(t *testing.T) {
|
|
||||||
testCases := []string{
|
|
||||||
"",
|
|
||||||
"\x00",
|
|
||||||
"\xff",
|
|
||||||
"A",
|
|
||||||
"DIV",
|
|
||||||
"Div",
|
|
||||||
"dIV",
|
|
||||||
"aa",
|
|
||||||
"a\x00",
|
|
||||||
"ab",
|
|
||||||
"abb",
|
|
||||||
"abbr0",
|
|
||||||
"abbr ",
|
|
||||||
" abbr",
|
|
||||||
" a",
|
|
||||||
"acceptcharset",
|
|
||||||
"acceptCharset",
|
|
||||||
"accept_charset",
|
|
||||||
"h0",
|
|
||||||
"h1h2",
|
|
||||||
"h7",
|
|
||||||
"onClick",
|
|
||||||
"λ",
|
|
||||||
// The following string has the same hash (0xa1d7fab7) as "onmouseover".
|
|
||||||
"\x00\x00\x00\x00\x00\x50\x18\xae\x38\xd0\xb7",
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
got := Lookup([]byte(tc))
|
|
||||||
if got != 0 {
|
|
||||||
t.Errorf("Lookup(%q): got %d, want 0", tc, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForeignObject(t *testing.T) {
|
|
||||||
const (
|
|
||||||
afo = Foreignobject
|
|
||||||
afO = ForeignObject
|
|
||||||
sfo = "foreignobject"
|
|
||||||
sfO = "foreignObject"
|
|
||||||
)
|
|
||||||
if got := Lookup([]byte(sfo)); got != afo {
|
|
||||||
t.Errorf("Lookup(%q): got %#v, want %#v", sfo, got, afo)
|
|
||||||
}
|
|
||||||
if got := Lookup([]byte(sfO)); got != afO {
|
|
||||||
t.Errorf("Lookup(%q): got %#v, want %#v", sfO, got, afO)
|
|
||||||
}
|
|
||||||
if got := afo.String(); got != sfo {
|
|
||||||
t.Errorf("Atom(%#v).String(): got %q, want %q", afo, got, sfo)
|
|
||||||
}
|
|
||||||
if got := afO.String(); got != sfO {
|
|
||||||
t.Errorf("Atom(%#v).String(): got %q, want %q", afO, got, sfO)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLookup(b *testing.B) {
|
|
||||||
sortedTable := make([]string, 0, len(table))
|
|
||||||
for _, a := range table {
|
|
||||||
if a != 0 {
|
|
||||||
sortedTable = append(sortedTable, a.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.Strings(sortedTable)
|
|
||||||
|
|
||||||
x := make([][]byte, 1000)
|
|
||||||
for i := range x {
|
|
||||||
x[i] = []byte(sortedTable[i%len(sortedTable)])
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
for _, s := range x {
|
|
||||||
Lookup(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,376 +0,0 @@
|
||||||
// Code generated by go generate gen.go; DO NOT EDIT.
|
|
||||||
|
|
||||||
//go:generate go run gen.go -test
|
|
||||||
|
|
||||||
package atom
|
|
||||||
|
|
||||||
var testAtomList = []string{
|
|
||||||
"a",
|
|
||||||
"abbr",
|
|
||||||
"accept",
|
|
||||||
"accept-charset",
|
|
||||||
"accesskey",
|
|
||||||
"acronym",
|
|
||||||
"action",
|
|
||||||
"address",
|
|
||||||
"align",
|
|
||||||
"allowfullscreen",
|
|
||||||
"allowpaymentrequest",
|
|
||||||
"allowusermedia",
|
|
||||||
"alt",
|
|
||||||
"annotation",
|
|
||||||
"annotation-xml",
|
|
||||||
"applet",
|
|
||||||
"area",
|
|
||||||
"article",
|
|
||||||
"as",
|
|
||||||
"aside",
|
|
||||||
"async",
|
|
||||||
"audio",
|
|
||||||
"autocomplete",
|
|
||||||
"autofocus",
|
|
||||||
"autoplay",
|
|
||||||
"b",
|
|
||||||
"base",
|
|
||||||
"basefont",
|
|
||||||
"bdi",
|
|
||||||
"bdo",
|
|
||||||
"bgsound",
|
|
||||||
"big",
|
|
||||||
"blink",
|
|
||||||
"blockquote",
|
|
||||||
"body",
|
|
||||||
"br",
|
|
||||||
"button",
|
|
||||||
"canvas",
|
|
||||||
"caption",
|
|
||||||
"center",
|
|
||||||
"challenge",
|
|
||||||
"charset",
|
|
||||||
"checked",
|
|
||||||
"cite",
|
|
||||||
"class",
|
|
||||||
"code",
|
|
||||||
"col",
|
|
||||||
"colgroup",
|
|
||||||
"color",
|
|
||||||
"cols",
|
|
||||||
"colspan",
|
|
||||||
"command",
|
|
||||||
"content",
|
|
||||||
"contenteditable",
|
|
||||||
"contextmenu",
|
|
||||||
"controls",
|
|
||||||
"coords",
|
|
||||||
"crossorigin",
|
|
||||||
"data",
|
|
||||||
"datalist",
|
|
||||||
"datetime",
|
|
||||||
"dd",
|
|
||||||
"default",
|
|
||||||
"defer",
|
|
||||||
"del",
|
|
||||||
"desc",
|
|
||||||
"details",
|
|
||||||
"dfn",
|
|
||||||
"dialog",
|
|
||||||
"dir",
|
|
||||||
"dirname",
|
|
||||||
"disabled",
|
|
||||||
"div",
|
|
||||||
"dl",
|
|
||||||
"download",
|
|
||||||
"draggable",
|
|
||||||
"dropzone",
|
|
||||||
"dt",
|
|
||||||
"em",
|
|
||||||
"embed",
|
|
||||||
"enctype",
|
|
||||||
"face",
|
|
||||||
"fieldset",
|
|
||||||
"figcaption",
|
|
||||||
"figure",
|
|
||||||
"font",
|
|
||||||
"footer",
|
|
||||||
"for",
|
|
||||||
"foreignObject",
|
|
||||||
"foreignobject",
|
|
||||||
"form",
|
|
||||||
"formaction",
|
|
||||||
"formenctype",
|
|
||||||
"formmethod",
|
|
||||||
"formnovalidate",
|
|
||||||
"formtarget",
|
|
||||||
"frame",
|
|
||||||
"frameset",
|
|
||||||
"h1",
|
|
||||||
"h2",
|
|
||||||
"h3",
|
|
||||||
"h4",
|
|
||||||
"h5",
|
|
||||||
"h6",
|
|
||||||
"head",
|
|
||||||
"header",
|
|
||||||
"headers",
|
|
||||||
"height",
|
|
||||||
"hgroup",
|
|
||||||
"hidden",
|
|
||||||
"high",
|
|
||||||
"hr",
|
|
||||||
"href",
|
|
||||||
"hreflang",
|
|
||||||
"html",
|
|
||||||
"http-equiv",
|
|
||||||
"i",
|
|
||||||
"icon",
|
|
||||||
"id",
|
|
||||||
"iframe",
|
|
||||||
"image",
|
|
||||||
"img",
|
|
||||||
"input",
|
|
||||||
"inputmode",
|
|
||||||
"ins",
|
|
||||||
"integrity",
|
|
||||||
"is",
|
|
||||||
"isindex",
|
|
||||||
"ismap",
|
|
||||||
"itemid",
|
|
||||||
"itemprop",
|
|
||||||
"itemref",
|
|
||||||
"itemscope",
|
|
||||||
"itemtype",
|
|
||||||
"kbd",
|
|
||||||
"keygen",
|
|
||||||
"keytype",
|
|
||||||
"kind",
|
|
||||||
"label",
|
|
||||||
"lang",
|
|
||||||
"legend",
|
|
||||||
"li",
|
|
||||||
"link",
|
|
||||||
"list",
|
|
||||||
"listing",
|
|
||||||
"loop",
|
|
||||||
"low",
|
|
||||||
"main",
|
|
||||||
"malignmark",
|
|
||||||
"manifest",
|
|
||||||
"map",
|
|
||||||
"mark",
|
|
||||||
"marquee",
|
|
||||||
"math",
|
|
||||||
"max",
|
|
||||||
"maxlength",
|
|
||||||
"media",
|
|
||||||
"mediagroup",
|
|
||||||
"menu",
|
|
||||||
"menuitem",
|
|
||||||
"meta",
|
|
||||||
"meter",
|
|
||||||
"method",
|
|
||||||
"mglyph",
|
|
||||||
"mi",
|
|
||||||
"min",
|
|
||||||
"minlength",
|
|
||||||
"mn",
|
|
||||||
"mo",
|
|
||||||
"ms",
|
|
||||||
"mtext",
|
|
||||||
"multiple",
|
|
||||||
"muted",
|
|
||||||
"name",
|
|
||||||
"nav",
|
|
||||||
"nobr",
|
|
||||||
"noembed",
|
|
||||||
"noframes",
|
|
||||||
"nomodule",
|
|
||||||
"nonce",
|
|
||||||
"noscript",
|
|
||||||
"novalidate",
|
|
||||||
"object",
|
|
||||||
"ol",
|
|
||||||
"onabort",
|
|
||||||
"onafterprint",
|
|
||||||
"onautocomplete",
|
|
||||||
"onautocompleteerror",
|
|
||||||
"onauxclick",
|
|
||||||
"onbeforeprint",
|
|
||||||
"onbeforeunload",
|
|
||||||
"onblur",
|
|
||||||
"oncancel",
|
|
||||||
"oncanplay",
|
|
||||||
"oncanplaythrough",
|
|
||||||
"onchange",
|
|
||||||
"onclick",
|
|
||||||
"onclose",
|
|
||||||
"oncontextmenu",
|
|
||||||
"oncopy",
|
|
||||||
"oncuechange",
|
|
||||||
"oncut",
|
|
||||||
"ondblclick",
|
|
||||||
"ondrag",
|
|
||||||
"ondragend",
|
|
||||||
"ondragenter",
|
|
||||||
"ondragexit",
|
|
||||||
"ondragleave",
|
|
||||||
"ondragover",
|
|
||||||
"ondragstart",
|
|
||||||
"ondrop",
|
|
||||||
"ondurationchange",
|
|
||||||
"onemptied",
|
|
||||||
"onended",
|
|
||||||
"onerror",
|
|
||||||
"onfocus",
|
|
||||||
"onhashchange",
|
|
||||||
"oninput",
|
|
||||||
"oninvalid",
|
|
||||||
"onkeydown",
|
|
||||||
"onkeypress",
|
|
||||||
"onkeyup",
|
|
||||||
"onlanguagechange",
|
|
||||||
"onload",
|
|
||||||
"onloadeddata",
|
|
||||||
"onloadedmetadata",
|
|
||||||
"onloadend",
|
|
||||||
"onloadstart",
|
|
||||||
"onmessage",
|
|
||||||
"onmessageerror",
|
|
||||||
"onmousedown",
|
|
||||||
"onmouseenter",
|
|
||||||
"onmouseleave",
|
|
||||||
"onmousemove",
|
|
||||||
"onmouseout",
|
|
||||||
"onmouseover",
|
|
||||||
"onmouseup",
|
|
||||||
"onmousewheel",
|
|
||||||
"onoffline",
|
|
||||||
"ononline",
|
|
||||||
"onpagehide",
|
|
||||||
"onpageshow",
|
|
||||||
"onpaste",
|
|
||||||
"onpause",
|
|
||||||
"onplay",
|
|
||||||
"onplaying",
|
|
||||||
"onpopstate",
|
|
||||||
"onprogress",
|
|
||||||
"onratechange",
|
|
||||||
"onrejectionhandled",
|
|
||||||
"onreset",
|
|
||||||
"onresize",
|
|
||||||
"onscroll",
|
|
||||||
"onsecuritypolicyviolation",
|
|
||||||
"onseeked",
|
|
||||||
"onseeking",
|
|
||||||
"onselect",
|
|
||||||
"onshow",
|
|
||||||
"onsort",
|
|
||||||
"onstalled",
|
|
||||||
"onstorage",
|
|
||||||
"onsubmit",
|
|
||||||
"onsuspend",
|
|
||||||
"ontimeupdate",
|
|
||||||
"ontoggle",
|
|
||||||
"onunhandledrejection",
|
|
||||||
"onunload",
|
|
||||||
"onvolumechange",
|
|
||||||
"onwaiting",
|
|
||||||
"onwheel",
|
|
||||||
"open",
|
|
||||||
"optgroup",
|
|
||||||
"optimum",
|
|
||||||
"option",
|
|
||||||
"output",
|
|
||||||
"p",
|
|
||||||
"param",
|
|
||||||
"pattern",
|
|
||||||
"picture",
|
|
||||||
"ping",
|
|
||||||
"placeholder",
|
|
||||||
"plaintext",
|
|
||||||
"playsinline",
|
|
||||||
"poster",
|
|
||||||
"pre",
|
|
||||||
"preload",
|
|
||||||
"progress",
|
|
||||||
"prompt",
|
|
||||||
"public",
|
|
||||||
"q",
|
|
||||||
"radiogroup",
|
|
||||||
"rb",
|
|
||||||
"readonly",
|
|
||||||
"referrerpolicy",
|
|
||||||
"rel",
|
|
||||||
"required",
|
|
||||||
"reversed",
|
|
||||||
"rows",
|
|
||||||
"rowspan",
|
|
||||||
"rp",
|
|
||||||
"rt",
|
|
||||||
"rtc",
|
|
||||||
"ruby",
|
|
||||||
"s",
|
|
||||||
"samp",
|
|
||||||
"sandbox",
|
|
||||||
"scope",
|
|
||||||
"scoped",
|
|
||||||
"script",
|
|
||||||
"seamless",
|
|
||||||
"section",
|
|
||||||
"select",
|
|
||||||
"selected",
|
|
||||||
"shape",
|
|
||||||
"size",
|
|
||||||
"sizes",
|
|
||||||
"slot",
|
|
||||||
"small",
|
|
||||||
"sortable",
|
|
||||||
"sorted",
|
|
||||||
"source",
|
|
||||||
"spacer",
|
|
||||||
"span",
|
|
||||||
"spellcheck",
|
|
||||||
"src",
|
|
||||||
"srcdoc",
|
|
||||||
"srclang",
|
|
||||||
"srcset",
|
|
||||||
"start",
|
|
||||||
"step",
|
|
||||||
"strike",
|
|
||||||
"strong",
|
|
||||||
"style",
|
|
||||||
"sub",
|
|
||||||
"summary",
|
|
||||||
"sup",
|
|
||||||
"svg",
|
|
||||||
"system",
|
|
||||||
"tabindex",
|
|
||||||
"table",
|
|
||||||
"target",
|
|
||||||
"tbody",
|
|
||||||
"td",
|
|
||||||
"template",
|
|
||||||
"textarea",
|
|
||||||
"tfoot",
|
|
||||||
"th",
|
|
||||||
"thead",
|
|
||||||
"time",
|
|
||||||
"title",
|
|
||||||
"tr",
|
|
||||||
"track",
|
|
||||||
"translate",
|
|
||||||
"tt",
|
|
||||||
"type",
|
|
||||||
"typemustmatch",
|
|
||||||
"u",
|
|
||||||
"ul",
|
|
||||||
"updateviacache",
|
|
||||||
"usemap",
|
|
||||||
"value",
|
|
||||||
"var",
|
|
||||||
"video",
|
|
||||||
"wbr",
|
|
||||||
"width",
|
|
||||||
"workertype",
|
|
||||||
"wrap",
|
|
||||||
"xmp",
|
|
||||||
}
|
|
|
@ -1,257 +0,0 @@
|
||||||
// Copyright 2013 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 charset provides common text encodings for HTML documents.
|
|
||||||
//
|
|
||||||
// The mapping from encoding labels to encodings is defined at
|
|
||||||
// https://encoding.spec.whatwg.org/.
|
|
||||||
package charset // import "golang.org/x/net/html/charset"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"mime"
|
|
||||||
"strings"
|
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"golang.org/x/net/html"
|
|
||||||
"golang.org/x/text/encoding"
|
|
||||||
"golang.org/x/text/encoding/charmap"
|
|
||||||
"golang.org/x/text/encoding/htmlindex"
|
|
||||||
"golang.org/x/text/transform"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Lookup returns the encoding with the specified label, and its canonical
|
|
||||||
// name. It returns nil and the empty string if label is not one of the
|
|
||||||
// standard encodings for HTML. Matching is case-insensitive and ignores
|
|
||||||
// leading and trailing whitespace. Encoders will use HTML escape sequences for
|
|
||||||
// runes that are not supported by the character set.
|
|
||||||
func Lookup(label string) (e encoding.Encoding, name string) {
|
|
||||||
e, err := htmlindex.Get(label)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ""
|
|
||||||
}
|
|
||||||
name, _ = htmlindex.Name(e)
|
|
||||||
return &htmlEncoding{e}, name
|
|
||||||
}
|
|
||||||
|
|
||||||
type htmlEncoding struct{ encoding.Encoding }
|
|
||||||
|
|
||||||
func (h *htmlEncoding) NewEncoder() *encoding.Encoder {
|
|
||||||
// HTML requires a non-terminating legacy encoder. We use HTML escapes to
|
|
||||||
// substitute unsupported code points.
|
|
||||||
return encoding.HTMLEscapeUnsupported(h.Encoding.NewEncoder())
|
|
||||||
}
|
|
||||||
|
|
||||||
// DetermineEncoding determines the encoding of an HTML document by examining
|
|
||||||
// up to the first 1024 bytes of content and the declared Content-Type.
|
|
||||||
//
|
|
||||||
// See http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#determining-the-character-encoding
|
|
||||||
func DetermineEncoding(content []byte, contentType string) (e encoding.Encoding, name string, certain bool) {
|
|
||||||
if len(content) > 1024 {
|
|
||||||
content = content[:1024]
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, b := range boms {
|
|
||||||
if bytes.HasPrefix(content, b.bom) {
|
|
||||||
e, name = Lookup(b.enc)
|
|
||||||
return e, name, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, params, err := mime.ParseMediaType(contentType); err == nil {
|
|
||||||
if cs, ok := params["charset"]; ok {
|
|
||||||
if e, name = Lookup(cs); e != nil {
|
|
||||||
return e, name, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(content) > 0 {
|
|
||||||
e, name = prescan(content)
|
|
||||||
if e != nil {
|
|
||||||
return e, name, false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to detect UTF-8.
|
|
||||||
// First eliminate any partial rune at the end.
|
|
||||||
for i := len(content) - 1; i >= 0 && i > len(content)-4; i-- {
|
|
||||||
b := content[i]
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if utf8.RuneStart(b) {
|
|
||||||
content = content[:i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hasHighBit := false
|
|
||||||
for _, c := range content {
|
|
||||||
if c >= 0x80 {
|
|
||||||
hasHighBit = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if hasHighBit && utf8.Valid(content) {
|
|
||||||
return encoding.Nop, "utf-8", false
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: change default depending on user's locale?
|
|
||||||
return charmap.Windows1252, "windows-1252", false
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewReader returns an io.Reader that converts the content of r to UTF-8.
|
|
||||||
// It calls DetermineEncoding to find out what r's encoding is.
|
|
||||||
func NewReader(r io.Reader, contentType string) (io.Reader, error) {
|
|
||||||
preview := make([]byte, 1024)
|
|
||||||
n, err := io.ReadFull(r, preview)
|
|
||||||
switch {
|
|
||||||
case err == io.ErrUnexpectedEOF:
|
|
||||||
preview = preview[:n]
|
|
||||||
r = bytes.NewReader(preview)
|
|
||||||
case err != nil:
|
|
||||||
return nil, err
|
|
||||||
default:
|
|
||||||
r = io.MultiReader(bytes.NewReader(preview), r)
|
|
||||||
}
|
|
||||||
|
|
||||||
if e, _, _ := DetermineEncoding(preview, contentType); e != encoding.Nop {
|
|
||||||
r = transform.NewReader(r, e.NewDecoder())
|
|
||||||
}
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewReaderLabel returns a reader that converts from the specified charset to
|
|
||||||
// UTF-8. It uses Lookup to find the encoding that corresponds to label, and
|
|
||||||
// returns an error if Lookup returns nil. It is suitable for use as
|
|
||||||
// encoding/xml.Decoder's CharsetReader function.
|
|
||||||
func NewReaderLabel(label string, input io.Reader) (io.Reader, error) {
|
|
||||||
e, _ := Lookup(label)
|
|
||||||
if e == nil {
|
|
||||||
return nil, fmt.Errorf("unsupported charset: %q", label)
|
|
||||||
}
|
|
||||||
return transform.NewReader(input, e.NewDecoder()), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func prescan(content []byte) (e encoding.Encoding, name string) {
|
|
||||||
z := html.NewTokenizer(bytes.NewReader(content))
|
|
||||||
for {
|
|
||||||
switch z.Next() {
|
|
||||||
case html.ErrorToken:
|
|
||||||
return nil, ""
|
|
||||||
|
|
||||||
case html.StartTagToken, html.SelfClosingTagToken:
|
|
||||||
tagName, hasAttr := z.TagName()
|
|
||||||
if !bytes.Equal(tagName, []byte("meta")) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
attrList := make(map[string]bool)
|
|
||||||
gotPragma := false
|
|
||||||
|
|
||||||
const (
|
|
||||||
dontKnow = iota
|
|
||||||
doNeedPragma
|
|
||||||
doNotNeedPragma
|
|
||||||
)
|
|
||||||
needPragma := dontKnow
|
|
||||||
|
|
||||||
name = ""
|
|
||||||
e = nil
|
|
||||||
for hasAttr {
|
|
||||||
var key, val []byte
|
|
||||||
key, val, hasAttr = z.TagAttr()
|
|
||||||
ks := string(key)
|
|
||||||
if attrList[ks] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
attrList[ks] = true
|
|
||||||
for i, c := range val {
|
|
||||||
if 'A' <= c && c <= 'Z' {
|
|
||||||
val[i] = c + 0x20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ks {
|
|
||||||
case "http-equiv":
|
|
||||||
if bytes.Equal(val, []byte("content-type")) {
|
|
||||||
gotPragma = true
|
|
||||||
}
|
|
||||||
|
|
||||||
case "content":
|
|
||||||
if e == nil {
|
|
||||||
name = fromMetaElement(string(val))
|
|
||||||
if name != "" {
|
|
||||||
e, name = Lookup(name)
|
|
||||||
if e != nil {
|
|
||||||
needPragma = doNeedPragma
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "charset":
|
|
||||||
e, name = Lookup(string(val))
|
|
||||||
needPragma = doNotNeedPragma
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if needPragma == dontKnow || needPragma == doNeedPragma && !gotPragma {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(name, "utf-16") {
|
|
||||||
name = "utf-8"
|
|
||||||
e = encoding.Nop
|
|
||||||
}
|
|
||||||
|
|
||||||
if e != nil {
|
|
||||||
return e, name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromMetaElement(s string) string {
|
|
||||||
for s != "" {
|
|
||||||
csLoc := strings.Index(s, "charset")
|
|
||||||
if csLoc == -1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
s = s[csLoc+len("charset"):]
|
|
||||||
s = strings.TrimLeft(s, " \t\n\f\r")
|
|
||||||
if !strings.HasPrefix(s, "=") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s = s[1:]
|
|
||||||
s = strings.TrimLeft(s, " \t\n\f\r")
|
|
||||||
if s == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if q := s[0]; q == '"' || q == '\'' {
|
|
||||||
s = s[1:]
|
|
||||||
closeQuote := strings.IndexRune(s, rune(q))
|
|
||||||
if closeQuote == -1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return s[:closeQuote]
|
|
||||||
}
|
|
||||||
|
|
||||||
end := strings.IndexAny(s, "; \t\n\f\r")
|
|
||||||
if end == -1 {
|
|
||||||
end = len(s)
|
|
||||||
}
|
|
||||||
return s[:end]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
var boms = []struct {
|
|
||||||
bom []byte
|
|
||||||
enc string
|
|
||||||
}{
|
|
||||||
{[]byte{0xfe, 0xff}, "utf-16be"},
|
|
||||||
{[]byte{0xff, 0xfe}, "utf-16le"},
|
|
||||||
{[]byte{0xef, 0xbb, 0xbf}, "utf-8"},
|
|
||||||
}
|
|
|
@ -1,237 +0,0 @@
|
||||||
// Copyright 2013 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 charset
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/xml"
|
|
||||||
"io/ioutil"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/text/transform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func transformString(t transform.Transformer, s string) (string, error) {
|
|
||||||
r := transform.NewReader(strings.NewReader(s), t)
|
|
||||||
b, err := ioutil.ReadAll(r)
|
|
||||||
return string(b), err
|
|
||||||
}
|
|
||||||
|
|
||||||
type testCase struct {
|
|
||||||
utf8, other, otherEncoding string
|
|
||||||
}
|
|
||||||
|
|
||||||
// testCases for encoding and decoding.
|
|
||||||
var testCases = []testCase{
|
|
||||||
{"Résumé", "Résumé", "utf8"},
|
|
||||||
{"Résumé", "R\xe9sum\xe9", "latin1"},
|
|
||||||
{"これは漢字です。", "S0\x8c0o0\"oW[g0Y0\x020", "UTF-16LE"},
|
|
||||||
{"これは漢字です。", "0S0\x8c0oo\"[W0g0Y0\x02", "UTF-16BE"},
|
|
||||||
{"Hello, world", "Hello, world", "ASCII"},
|
|
||||||
{"Gdańsk", "Gda\xf1sk", "ISO-8859-2"},
|
|
||||||
{"Ââ Čč Đđ Ŋŋ Õõ Šš Žž Åå Ää", "\xc2\xe2 \xc8\xe8 \xa9\xb9 \xaf\xbf \xd5\xf5 \xaa\xba \xac\xbc \xc5\xe5 \xc4\xe4", "ISO-8859-10"},
|
|
||||||
{"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "ISO-8859-11"},
|
|
||||||
{"latviešu", "latvie\xf0u", "ISO-8859-13"},
|
|
||||||
{"Seònaid", "Se\xf2naid", "ISO-8859-14"},
|
|
||||||
{"€1 is cheap", "\xa41 is cheap", "ISO-8859-15"},
|
|
||||||
{"românește", "rom\xe2ne\xbate", "ISO-8859-16"},
|
|
||||||
{"nutraĵo", "nutra\xbco", "ISO-8859-3"},
|
|
||||||
{"Kalâdlit", "Kal\xe2dlit", "ISO-8859-4"},
|
|
||||||
{"русский", "\xe0\xe3\xe1\xe1\xda\xd8\xd9", "ISO-8859-5"},
|
|
||||||
{"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "ISO-8859-7"},
|
|
||||||
{"Kağan", "Ka\xf0an", "ISO-8859-9"},
|
|
||||||
{"Résumé", "R\x8esum\x8e", "macintosh"},
|
|
||||||
{"Gdańsk", "Gda\xf1sk", "windows-1250"},
|
|
||||||
{"русский", "\xf0\xf3\xf1\xf1\xea\xe8\xe9", "windows-1251"},
|
|
||||||
{"Résumé", "R\xe9sum\xe9", "windows-1252"},
|
|
||||||
{"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "windows-1253"},
|
|
||||||
{"Kağan", "Ka\xf0an", "windows-1254"},
|
|
||||||
{"עִבְרִית", "\xf2\xc4\xe1\xc0\xf8\xc4\xe9\xfa", "windows-1255"},
|
|
||||||
{"العربية", "\xc7\xe1\xda\xd1\xc8\xed\xc9", "windows-1256"},
|
|
||||||
{"latviešu", "latvie\xf0u", "windows-1257"},
|
|
||||||
{"Việt", "Vi\xea\xf2t", "windows-1258"},
|
|
||||||
{"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "windows-874"},
|
|
||||||
{"русский", "\xd2\xd5\xd3\xd3\xcb\xc9\xca", "KOI8-R"},
|
|
||||||
{"українська", "\xd5\xcb\xd2\xc1\xa7\xce\xd3\xd8\xcb\xc1", "KOI8-U"},
|
|
||||||
{"Hello 常用國字標準字體表", "Hello \xb1`\xa5\u03b0\xea\xa6r\xbc\u0437\u01e6r\xc5\xe9\xaa\xed", "big5"},
|
|
||||||
{"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gbk"},
|
|
||||||
{"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gb18030"},
|
|
||||||
{"עִבְרִית", "\x81\x30\xfb\x30\x81\x30\xf6\x34\x81\x30\xf9\x33\x81\x30\xf6\x30\x81\x30\xfb\x36\x81\x30\xf6\x34\x81\x30\xfa\x31\x81\x30\xfb\x38", "gb18030"},
|
|
||||||
{"㧯", "\x82\x31\x89\x38", "gb18030"},
|
|
||||||
{"これは漢字です。", "\x82\xb1\x82\xea\x82\xcd\x8a\xbf\x8e\x9a\x82\xc5\x82\xb7\x81B", "SJIS"},
|
|
||||||
{"Hello, 世界!", "Hello, \x90\xa2\x8aE!", "SJIS"},
|
|
||||||
{"イウエオカ", "\xb2\xb3\xb4\xb5\xb6", "SJIS"},
|
|
||||||
{"これは漢字です。", "\xa4\xb3\xa4\xec\xa4\u03f4\xc1\xbb\xfa\xa4\u01e4\xb9\xa1\xa3", "EUC-JP"},
|
|
||||||
{"Hello, 世界!", "Hello, \x1b$B@$3&\x1b(B!", "ISO-2022-JP"},
|
|
||||||
{"다음과 같은 조건을 따라야 합니다: 저작자표시", "\xb4\xd9\xc0\xbd\xb0\xfa \xb0\xb0\xc0\xba \xc1\xb6\xb0\xc7\xc0\xbb \xb5\xfb\xb6\xf3\xbe\xdf \xc7մϴ\xd9: \xc0\xfa\xc0\xdb\xc0\xdaǥ\xbd\xc3", "EUC-KR"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecode(t *testing.T) {
|
|
||||||
testCases := append(testCases, []testCase{
|
|
||||||
// Replace multi-byte maximum subpart of ill-formed subsequence with
|
|
||||||
// single replacement character (WhatWG requirement).
|
|
||||||
{"Rés\ufffdumé", "Rés\xe1\x80umé", "utf8"},
|
|
||||||
}...)
|
|
||||||
for _, tc := range testCases {
|
|
||||||
e, _ := Lookup(tc.otherEncoding)
|
|
||||||
if e == nil {
|
|
||||||
t.Errorf("%s: not found", tc.otherEncoding)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s, err := transformString(e.NewDecoder(), tc.other)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: decode %q: %v", tc.otherEncoding, tc.other, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if s != tc.utf8 {
|
|
||||||
t.Errorf("%s: got %q, want %q", tc.otherEncoding, s, tc.utf8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEncode(t *testing.T) {
|
|
||||||
testCases := append(testCases, []testCase{
|
|
||||||
// Use Go-style replacement.
|
|
||||||
{"Rés\xe1\x80umé", "Rés\ufffd\ufffdumé", "utf8"},
|
|
||||||
// U+0144 LATIN SMALL LETTER N WITH ACUTE not supported by encoding.
|
|
||||||
{"Gdańsk", "Gdańsk", "ISO-8859-11"},
|
|
||||||
{"\ufffd", "�", "ISO-8859-11"},
|
|
||||||
{"a\xe1\x80b", "a��b", "ISO-8859-11"},
|
|
||||||
}...)
|
|
||||||
for _, tc := range testCases {
|
|
||||||
e, _ := Lookup(tc.otherEncoding)
|
|
||||||
if e == nil {
|
|
||||||
t.Errorf("%s: not found", tc.otherEncoding)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s, err := transformString(e.NewEncoder(), tc.utf8)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: encode %q: %s", tc.otherEncoding, tc.utf8, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if s != tc.other {
|
|
||||||
t.Errorf("%s: got %q, want %q", tc.otherEncoding, s, tc.other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sniffTestCases = []struct {
|
|
||||||
filename, declared, want string
|
|
||||||
}{
|
|
||||||
{"HTTP-charset.html", "text/html; charset=iso-8859-15", "iso-8859-15"},
|
|
||||||
{"UTF-16LE-BOM.html", "", "utf-16le"},
|
|
||||||
{"UTF-16BE-BOM.html", "", "utf-16be"},
|
|
||||||
{"meta-content-attribute.html", "text/html", "iso-8859-15"},
|
|
||||||
{"meta-charset-attribute.html", "text/html", "iso-8859-15"},
|
|
||||||
{"No-encoding-declaration.html", "text/html", "utf-8"},
|
|
||||||
{"HTTP-vs-UTF-8-BOM.html", "text/html; charset=iso-8859-15", "utf-8"},
|
|
||||||
{"HTTP-vs-meta-content.html", "text/html; charset=iso-8859-15", "iso-8859-15"},
|
|
||||||
{"HTTP-vs-meta-charset.html", "text/html; charset=iso-8859-15", "iso-8859-15"},
|
|
||||||
{"UTF-8-BOM-vs-meta-content.html", "text/html", "utf-8"},
|
|
||||||
{"UTF-8-BOM-vs-meta-charset.html", "text/html", "utf-8"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSniff(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl": // platforms that don't permit direct file system access
|
|
||||||
t.Skipf("not supported on %q", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range sniffTestCases {
|
|
||||||
content, err := ioutil.ReadFile("testdata/" + tc.filename)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: error reading file: %v", tc.filename, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
_, name, _ := DetermineEncoding(content, tc.declared)
|
|
||||||
if name != tc.want {
|
|
||||||
t.Errorf("%s: got %q, want %q", tc.filename, name, tc.want)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReader(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl": // platforms that don't permit direct file system access
|
|
||||||
t.Skipf("not supported on %q", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range sniffTestCases {
|
|
||||||
content, err := ioutil.ReadFile("testdata/" + tc.filename)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: error reading file: %v", tc.filename, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := NewReader(bytes.NewReader(content), tc.declared)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: error creating reader: %v", tc.filename, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: error reading from charset.NewReader: %v", tc.filename, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
e, _ := Lookup(tc.want)
|
|
||||||
want, err := ioutil.ReadAll(transform.NewReader(bytes.NewReader(content), e.NewDecoder()))
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: error decoding with hard-coded charset name: %v", tc.filename, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(got, want) {
|
|
||||||
t.Errorf("%s: got %q, want %q", tc.filename, got, want)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var metaTestCases = []struct {
|
|
||||||
meta, want string
|
|
||||||
}{
|
|
||||||
{"", ""},
|
|
||||||
{"text/html", ""},
|
|
||||||
{"text/html; charset utf-8", ""},
|
|
||||||
{"text/html; charset=latin-2", "latin-2"},
|
|
||||||
{"text/html; charset; charset = utf-8", "utf-8"},
|
|
||||||
{`charset="big5"`, "big5"},
|
|
||||||
{"charset='shift_jis'", "shift_jis"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFromMeta(t *testing.T) {
|
|
||||||
for _, tc := range metaTestCases {
|
|
||||||
got := fromMetaElement(tc.meta)
|
|
||||||
if got != tc.want {
|
|
||||||
t.Errorf("%q: got %q, want %q", tc.meta, got, tc.want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestXML(t *testing.T) {
|
|
||||||
const s = "<?xml version=\"1.0\" encoding=\"windows-1252\"?><a><Word>r\xe9sum\xe9</Word></a>"
|
|
||||||
|
|
||||||
d := xml.NewDecoder(strings.NewReader(s))
|
|
||||||
d.CharsetReader = NewReaderLabel
|
|
||||||
|
|
||||||
var a struct {
|
|
||||||
Word string
|
|
||||||
}
|
|
||||||
err := d.Decode(&a)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Decode: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
want := "résumé"
|
|
||||||
if a.Word != want {
|
|
||||||
t.Errorf("got %q, want %q", a.Word, want)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<title>HTTP charset</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="The character encoding of a page can be set using the HTTP header charset declaration.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>HTTP charset</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">The character encoding of a page can be set using the HTTP header charset declaration.</p>
|
|
||||||
<div class="notes"><p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ÜÀÚ</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p><p>The only character encoding declaration for this HTML file is in the HTTP header, which sets the encoding to ISO 8859-15.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-003">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-001<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#basics" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-001" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
|
|
||||||
<li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<title>HTTP vs UTF-8 BOM</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="A character encoding set in the HTTP header has lower precedence than the UTF-8 signature.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-utf8.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>HTTP vs UTF-8 BOM</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">A character encoding set in the HTTP header has lower precedence than the UTF-8 signature.</p>
|
|
||||||
<div class="notes"><p><p>The HTTP header attempts to set the character encoding to ISO 8859-15. The page starts with a UTF-8 signature.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ýäè</code>. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.</p><p>If the test is unsuccessful, the characters  should appear at the top of the page. These represent the bytes that make up the UTF-8 signature when encountered in the ISO 8859-15 encoding.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-022">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-034<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-034" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
|
|
||||||
<li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="iso-8859-1" > <title>HTTP vs meta charset</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="The HTTP header has a higher precedence than an encoding declaration in a meta charset attribute.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }.test div { width: 90px; }
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>HTTP vs meta charset</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">The HTTP header has a higher precedence than an encoding declaration in a meta charset attribute.</p>
|
|
||||||
<div class="notes"><p><p>The HTTP header attempts to set the character encoding to ISO 8859-15. The page contains an encoding declaration in a meta charset attribute that attempts to set the character encoding to ISO 8859-1.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ÜÀÚ</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-037">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-018<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-018" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
|
|
||||||
<li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" > <title>HTTP vs meta content</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="The HTTP header has a higher precedence than an encoding declaration in a meta content attribute.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }.test div { width: 90px; }
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>HTTP vs meta content</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">The HTTP header has a higher precedence than an encoding declaration in a meta content attribute.</p>
|
|
||||||
<div class="notes"><p><p>The HTTP header attempts to set the character encoding to ISO 8859-15. The page contains an encoding declaration in a meta content attribute that attempts to set the character encoding to ISO 8859-1.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ÜÀÚ</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-018">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-016<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-016" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
|
|
||||||
<li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<title>No encoding declaration</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="A page with no encoding information in HTTP, BOM, XML declaration or meta element will be treated as UTF-8.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-utf8.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>No encoding declaration</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">A page with no encoding information in HTTP, BOM, XML declaration or meta element will be treated as UTF-8.</p>
|
|
||||||
<div class="notes"><p><p>The test on this page contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ýäè</code>. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-034">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-015<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#basics" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-015" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
These test cases come from
|
|
||||||
http://www.w3.org/International/tests/repository/html5/the-input-byte-stream/results-basics
|
|
||||||
|
|
||||||
Distributed under both the W3C Test Suite License
|
|
||||||
(http://www.w3.org/Consortium/Legal/2008/04-testsuite-license)
|
|
||||||
and the W3C 3-clause BSD License
|
|
||||||
(http://www.w3.org/Consortium/Legal/2008/03-bsd-license).
|
|
||||||
To contribute to a W3C Test Suite, see the policies and contribution
|
|
||||||
forms (http://www.w3.org/2004/10/27-testcases).
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,49 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="iso-8859-15"> <title>UTF-8 BOM vs meta charset</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta charset attribute declares a different encoding.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }.test div { width: 90px; }
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-utf8.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>UTF-8 BOM vs meta charset</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta charset attribute declares a different encoding.</p>
|
|
||||||
<div class="notes"><p><p>The page contains an encoding declaration in a meta charset attribute that attempts to set the character encoding to ISO 8859-15, but the file starts with a UTF-8 signature.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ýäè</code>. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-024">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-038<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-038" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
|
|
||||||
<li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-15"> <title>UTF-8 BOM vs meta content</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta content attribute declares a different encoding.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-utf8.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>UTF-8 BOM vs meta content</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta content attribute declares a different encoding.</p>
|
|
||||||
<div class="notes"><p><p>The page contains an encoding declaration in a meta content attribute that attempts to set the character encoding to ISO 8859-15, but the file starts with a UTF-8 signature.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ýäè</code>. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-038">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-037<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-037" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
|
|
||||||
<li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta charset="iso-8859-15"> <title>meta charset attribute</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="The character encoding of the page can be set by a meta element with charset attribute.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>meta charset attribute</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">The character encoding of the page can be set by a meta element with charset attribute.</p>
|
|
||||||
<div class="notes"><p><p>The only character encoding declaration for this HTML file is in the charset attribute of the meta element, which declares the encoding to be ISO 8859-15.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ÜÀÚ</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-015">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-009<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#basics" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-009" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
|
|
||||||
<li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" >
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-15"> <title>meta content attribute</title>
|
|
||||||
<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
|
|
||||||
<link rel="stylesheet" type="text/css" href="./generatedtests.css">
|
|
||||||
<script src="http://w3c-test.org/resources/testharness.js"></script>
|
|
||||||
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
|
|
||||||
<meta name='flags' content='http'>
|
|
||||||
<meta name="assert" content="The character encoding of the page can be set by a meta element with http-equiv and content attributes.">
|
|
||||||
<style type='text/css'>
|
|
||||||
.test div { width: 50px; }</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p class='title'>meta content attribute</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='test'><div id='box' class='ýäè'> </div></div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class='description'>
|
|
||||||
<p class="assertion" title="Assertion">The character encoding of the page can be set by a meta element with http-equiv and content attributes.</p>
|
|
||||||
<div class="notes"><p><p>The only character encoding declaration for this HTML file is in the content attribute of the meta element, which declares the encoding to be ISO 8859-15.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.ÜÀÚ</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-009">Next test</a></div><div class="doctype">HTML5</div>
|
|
||||||
<p class="jump">the-input-byte-stream-007<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#basics" target="_blank">Result summary & related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-007" target="_blank">Detailed results for this test</a><br/> <a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
|
|
||||||
<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
|
|
||||||
<li>The test is read from a server that supports HTTP.</li></ul></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_equals(document.getElementById('box').offsetWidth, 100);
|
|
||||||
}, " ");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
|
@ -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,97 +0,0 @@
|
||||||
// Copyright 2013 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"
|
|
||||||
|
|
||||||
type unescapeTest struct {
|
|
||||||
// A short description of the test case.
|
|
||||||
desc string
|
|
||||||
// The HTML text.
|
|
||||||
html string
|
|
||||||
// The unescaped text.
|
|
||||||
unescaped string
|
|
||||||
}
|
|
||||||
|
|
||||||
var unescapeTests = []unescapeTest{
|
|
||||||
// Handle no entities.
|
|
||||||
{
|
|
||||||
"copy",
|
|
||||||
"A\ttext\nstring",
|
|
||||||
"A\ttext\nstring",
|
|
||||||
},
|
|
||||||
// Handle simple named entities.
|
|
||||||
{
|
|
||||||
"simple",
|
|
||||||
"& > <",
|
|
||||||
"& > <",
|
|
||||||
},
|
|
||||||
// Handle hitting the end of the string.
|
|
||||||
{
|
|
||||||
"stringEnd",
|
|
||||||
"& &",
|
|
||||||
"& &",
|
|
||||||
},
|
|
||||||
// Handle entities with two codepoints.
|
|
||||||
{
|
|
||||||
"multiCodepoint",
|
|
||||||
"text ⋛︀ blah",
|
|
||||||
"text \u22db\ufe00 blah",
|
|
||||||
},
|
|
||||||
// Handle decimal numeric entities.
|
|
||||||
{
|
|
||||||
"decimalEntity",
|
|
||||||
"Delta = Δ ",
|
|
||||||
"Delta = Δ ",
|
|
||||||
},
|
|
||||||
// Handle hexadecimal numeric entities.
|
|
||||||
{
|
|
||||||
"hexadecimalEntity",
|
|
||||||
"Lambda = λ = λ ",
|
|
||||||
"Lambda = λ = λ ",
|
|
||||||
},
|
|
||||||
// Handle numeric early termination.
|
|
||||||
{
|
|
||||||
"numericEnds",
|
|
||||||
"&# &#x €43 © = ©f = ©",
|
|
||||||
"&# &#x €43 © = ©f = ©",
|
|
||||||
},
|
|
||||||
// Handle numeric ISO-8859-1 entity replacements.
|
|
||||||
{
|
|
||||||
"numericReplacements",
|
|
||||||
"Footnote‡",
|
|
||||||
"Footnote‡",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnescape(t *testing.T) {
|
|
||||||
for _, tt := range unescapeTests {
|
|
||||||
unescaped := UnescapeString(tt.html)
|
|
||||||
if unescaped != tt.unescaped {
|
|
||||||
t.Errorf("TestUnescape %s: want %q, got %q", tt.desc, tt.unescaped, unescaped)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnescapeEscape(t *testing.T) {
|
|
||||||
ss := []string{
|
|
||||||
``,
|
|
||||||
`abc def`,
|
|
||||||
`a & b`,
|
|
||||||
`a&b`,
|
|
||||||
`a & b`,
|
|
||||||
`"`,
|
|
||||||
`"`,
|
|
||||||
`"<&>"`,
|
|
||||||
`"<&>"`,
|
|
||||||
`3&5==1 && 0<1, "0<1", a+acute=á`,
|
|
||||||
`The special characters are: <, >, &, ' and "`,
|
|
||||||
}
|
|
||||||
for _, s := range ss {
|
|
||||||
if got := UnescapeString(EscapeString(s)); got != s {
|
|
||||||
t.Errorf("got %q want %q", got, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +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.
|
|
||||||
|
|
||||||
// This example demonstrates parsing HTML data and walking the resulting tree.
|
|
||||||
package html_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/net/html"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleParse() {
|
|
||||||
s := `<p>Links:</p><ul><li><a href="foo">Foo</a><li><a href="/bar/baz">BarBaz</a></ul>`
|
|
||||||
doc, err := html.Parse(strings.NewReader(s))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
var f func(*html.Node)
|
|
||||||
f = func(n *html.Node) {
|
|
||||||
if n.Type == html.ElementNode && n.Data == "a" {
|
|
||||||
for _, a := range n.Attr {
|
|
||||||
if a.Key == "href" {
|
|
||||||
fmt.Println(a.Val)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
f(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f(doc)
|
|
||||||
// Output:
|
|
||||||
// foo
|
|
||||||
// /bar/baz
|
|
||||||
}
|
|
|
@ -1,146 +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 (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// checkTreeConsistency checks that a node and its descendants are all
|
|
||||||
// consistent in their parent/child/sibling relationships.
|
|
||||||
func checkTreeConsistency(n *Node) error {
|
|
||||||
return checkTreeConsistency1(n, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkTreeConsistency1(n *Node, depth int) error {
|
|
||||||
if depth == 1e4 {
|
|
||||||
return fmt.Errorf("html: tree looks like it contains a cycle")
|
|
||||||
}
|
|
||||||
if err := checkNodeConsistency(n); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
if err := checkTreeConsistency1(c, depth+1); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkNodeConsistency checks that a node's parent/child/sibling relationships
|
|
||||||
// are consistent.
|
|
||||||
func checkNodeConsistency(n *Node) error {
|
|
||||||
if n == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
nParent := 0
|
|
||||||
for p := n.Parent; p != nil; p = p.Parent {
|
|
||||||
nParent++
|
|
||||||
if nParent == 1e4 {
|
|
||||||
return fmt.Errorf("html: parent list looks like an infinite loop")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nForward := 0
|
|
||||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
nForward++
|
|
||||||
if nForward == 1e6 {
|
|
||||||
return fmt.Errorf("html: forward list of children looks like an infinite loop")
|
|
||||||
}
|
|
||||||
if c.Parent != n {
|
|
||||||
return fmt.Errorf("html: inconsistent child/parent relationship")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nBackward := 0
|
|
||||||
for c := n.LastChild; c != nil; c = c.PrevSibling {
|
|
||||||
nBackward++
|
|
||||||
if nBackward == 1e6 {
|
|
||||||
return fmt.Errorf("html: backward list of children looks like an infinite loop")
|
|
||||||
}
|
|
||||||
if c.Parent != n {
|
|
||||||
return fmt.Errorf("html: inconsistent child/parent relationship")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Parent != nil {
|
|
||||||
if n.Parent == n {
|
|
||||||
return fmt.Errorf("html: inconsistent parent relationship")
|
|
||||||
}
|
|
||||||
if n.Parent == n.FirstChild {
|
|
||||||
return fmt.Errorf("html: inconsistent parent/first relationship")
|
|
||||||
}
|
|
||||||
if n.Parent == n.LastChild {
|
|
||||||
return fmt.Errorf("html: inconsistent parent/last relationship")
|
|
||||||
}
|
|
||||||
if n.Parent == n.PrevSibling {
|
|
||||||
return fmt.Errorf("html: inconsistent parent/prev relationship")
|
|
||||||
}
|
|
||||||
if n.Parent == n.NextSibling {
|
|
||||||
return fmt.Errorf("html: inconsistent parent/next relationship")
|
|
||||||
}
|
|
||||||
|
|
||||||
parentHasNAsAChild := false
|
|
||||||
for c := n.Parent.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
if c == n {
|
|
||||||
parentHasNAsAChild = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !parentHasNAsAChild {
|
|
||||||
return fmt.Errorf("html: inconsistent parent/child relationship")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.PrevSibling != nil && n.PrevSibling.NextSibling != n {
|
|
||||||
return fmt.Errorf("html: inconsistent prev/next relationship")
|
|
||||||
}
|
|
||||||
if n.NextSibling != nil && n.NextSibling.PrevSibling != n {
|
|
||||||
return fmt.Errorf("html: inconsistent next/prev relationship")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.FirstChild == nil) != (n.LastChild == nil) {
|
|
||||||
return fmt.Errorf("html: inconsistent first/last relationship")
|
|
||||||
}
|
|
||||||
if n.FirstChild != nil && n.FirstChild == n.LastChild {
|
|
||||||
// We have a sole child.
|
|
||||||
if n.FirstChild.PrevSibling != nil || n.FirstChild.NextSibling != nil {
|
|
||||||
return fmt.Errorf("html: inconsistent sole child's sibling relationship")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
seen := map[*Node]bool{}
|
|
||||||
|
|
||||||
var last *Node
|
|
||||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
if seen[c] {
|
|
||||||
return fmt.Errorf("html: inconsistent repeated child")
|
|
||||||
}
|
|
||||||
seen[c] = true
|
|
||||||
last = c
|
|
||||||
}
|
|
||||||
if last != n.LastChild {
|
|
||||||
return fmt.Errorf("html: inconsistent last relationship")
|
|
||||||
}
|
|
||||||
|
|
||||||
var first *Node
|
|
||||||
for c := n.LastChild; c != nil; c = c.PrevSibling {
|
|
||||||
if !seen[c] {
|
|
||||||
return fmt.Errorf("html: inconsistent missing child")
|
|
||||||
}
|
|
||||||
delete(seen, c)
|
|
||||||
first = c
|
|
||||||
}
|
|
||||||
if first != n.FirstChild {
|
|
||||||
return fmt.Errorf("html: inconsistent first relationship")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(seen) != 0 {
|
|
||||||
return fmt.Errorf("html: inconsistent forwards/backwards child list")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,404 +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"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/html/atom"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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.TrimSuffix(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)
|
|
||||||
}
|
|
||||||
inQuote := false
|
|
||||||
for {
|
|
||||||
line, err = r.ReadSlice('\n')
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
return "", "", "", err
|
|
||||||
}
|
|
||||||
trimmed := bytes.Trim(line, "| \n")
|
|
||||||
if len(trimmed) > 0 {
|
|
||||||
if line[0] == '|' && trimmed[0] == '"' {
|
|
||||||
inQuote = true
|
|
||||||
}
|
|
||||||
if trimmed[len(trimmed)-1] == '"' && !(line[0] == '|' && len(trimmed) == 1) {
|
|
||||||
inQuote = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(line) == 0 || len(line) == 1 && line[0] == '\n' && !inQuote {
|
|
||||||
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, " ")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type sortedAttributes []Attribute
|
|
||||||
|
|
||||||
func (a sortedAttributes) Len() int {
|
|
||||||
return len(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a sortedAttributes) Less(i, j int) bool {
|
|
||||||
if a[i].Namespace != a[j].Namespace {
|
|
||||||
return a[i].Namespace < a[j].Namespace
|
|
||||||
}
|
|
||||||
return a[i].Key < a[j].Key
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a sortedAttributes) Swap(i, j int) {
|
|
||||||
a[i], a[j] = a[j], a[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func dumpLevel(w io.Writer, n *Node, level int) error {
|
|
||||||
dumpIndent(w, level)
|
|
||||||
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 := sortedAttributes(n.Attr)
|
|
||||||
sort.Sort(attr)
|
|
||||||
for _, a := range attr {
|
|
||||||
io.WriteString(w, "\n")
|
|
||||||
dumpIndent(w, level)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if n.Namespace == "" && n.DataAtom == atom.Template {
|
|
||||||
io.WriteString(w, "\n")
|
|
||||||
dumpIndent(w, level)
|
|
||||||
level++
|
|
||||||
io.WriteString(w, "content")
|
|
||||||
}
|
|
||||||
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 := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
if err := dumpLevel(w, c, level); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dump(n *Node) (string, error) {
|
|
||||||
if n == nil || n.FirstChild == nil {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
var b bytes.Buffer
|
|
||||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
if err := dumpLevel(&b, c, 0); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var testDataDirs = []string{"testdata/webkit/", "testdata/go/"}
|
|
||||||
|
|
||||||
func TestParser(t *testing.T) {
|
|
||||||
for _, testDataDir := range testDataDirs {
|
|
||||||
testFiles, err := filepath.Glob(testDataDir + "*.dat")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for _, tf := range testFiles {
|
|
||||||
f, err := os.Open(tf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
r := bufio.NewReader(f)
|
|
||||||
|
|
||||||
for i := 0; ; i++ {
|
|
||||||
text, want, context, err := readParseTest(r)
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = testParseCase(text, want, context)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s test #%d %q, %s", tf, i, text, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// testParseCase tests one test case from the test files. If the test does not
|
|
||||||
// pass, it returns an error that explains the failure.
|
|
||||||
// text is the HTML to be parsed, want is a dump of the correct parse tree,
|
|
||||||
// and context is the name of the context node, if any.
|
|
||||||
func testParseCase(text, want, context string) (err error) {
|
|
||||||
defer func() {
|
|
||||||
if x := recover(); x != nil {
|
|
||||||
switch e := x.(type) {
|
|
||||||
case error:
|
|
||||||
err = e
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("%v", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var doc *Node
|
|
||||||
if context == "" {
|
|
||||||
doc, err = Parse(strings.NewReader(text))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
contextNode := &Node{
|
|
||||||
Type: ElementNode,
|
|
||||||
DataAtom: atom.Lookup([]byte(context)),
|
|
||||||
Data: context,
|
|
||||||
}
|
|
||||||
nodes, err := ParseFragment(strings.NewReader(text), contextNode)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
doc = &Node{
|
|
||||||
Type: DocumentNode,
|
|
||||||
}
|
|
||||||
for _, n := range nodes {
|
|
||||||
doc.AppendChild(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := checkTreeConsistency(doc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := dump(doc)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Compare the parsed tree to the #document section.
|
|
||||||
if got != want {
|
|
||||||
return fmt.Errorf("got vs want:\n----\n%s----\n%s----", got, want)
|
|
||||||
}
|
|
||||||
|
|
||||||
if renderTestBlacklist[text] || context != "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
got1, err := dump(doc1)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if got != got1 {
|
|
||||||
return fmt.Errorf("got vs got1:\n----\n%s----\n%s----", got, got1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
// The same thing with a <p>:
|
|
||||||
`<p><table></p>`: 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,
|
|
||||||
`<template><a><table><a>`: true,
|
|
||||||
// A similar reparenting situation involving <nobr>:
|
|
||||||
`<!DOCTYPE html><body><b><nobr>1<table><nobr></b><i><nobr>2<nobr></i>3`: 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,
|
|
||||||
`<!doctype html><table><plaintext></plaintext>`: true,
|
|
||||||
`<!doctype html><table><tbody><plaintext></plaintext>`: true,
|
|
||||||
`<!doctype html><table><tbody><tr><plaintext></plaintext>`: true,
|
|
||||||
// A form inside a table inside a form doesn't work either.
|
|
||||||
`<!doctype html><form><table></form><form></table></form>`: true,
|
|
||||||
// A script that ends at EOF may escape its own closing tag when rendered.
|
|
||||||
`<!doctype html><script><!--<script `: true,
|
|
||||||
`<!doctype html><script><!--<script <`: true,
|
|
||||||
`<!doctype html><script><!--<script <a`: true,
|
|
||||||
`<!doctype html><script><!--<script </`: true,
|
|
||||||
`<!doctype html><script><!--<script </s`: true,
|
|
||||||
`<!doctype html><script><!--<script </script`: true,
|
|
||||||
`<!doctype html><script><!--<script </scripta`: true,
|
|
||||||
`<!doctype html><script><!--<script -`: true,
|
|
||||||
`<!doctype html><script><!--<script -a`: true,
|
|
||||||
`<!doctype html><script><!--<script -<`: true,
|
|
||||||
`<!doctype html><script><!--<script --`: true,
|
|
||||||
`<!doctype html><script><!--<script --a`: true,
|
|
||||||
`<!doctype html><script><!--<script --<`: true,
|
|
||||||
`<script><!--<script `: true,
|
|
||||||
`<script><!--<script <a`: true,
|
|
||||||
`<script><!--<script </script`: true,
|
|
||||||
`<script><!--<script </scripta`: true,
|
|
||||||
`<script><!--<script -`: true,
|
|
||||||
`<script><!--<script -a`: true,
|
|
||||||
`<script><!--<script --`: true,
|
|
||||||
`<script><!--<script --a`: true,
|
|
||||||
`<script><!--<script <`: true,
|
|
||||||
`<script><!--<script </`: true,
|
|
||||||
`<script><!--<script </s`: true,
|
|
||||||
// Reconstructing the active formatting elements results in a <plaintext>
|
|
||||||
// element that contains an <a> element.
|
|
||||||
`<!doctype html><p><a><plaintext>b`: true,
|
|
||||||
`<table><math><select><mi><select></table>`: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNodeConsistency(t *testing.T) {
|
|
||||||
// inconsistentNode is a Node whose DataAtom and Data do not agree.
|
|
||||||
inconsistentNode := &Node{
|
|
||||||
Type: ElementNode,
|
|
||||||
DataAtom: atom.Frameset,
|
|
||||||
Data: "table",
|
|
||||||
}
|
|
||||||
_, err := ParseFragment(strings.NewReader("<p>hello</p>"), inconsistentNode)
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("got nil error, want non-nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseFragmentWithNilContext(t *testing.T) {
|
|
||||||
// This shouldn't panic.
|
|
||||||
ParseFragment(strings.NewReader("<p>hello</p>"), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkParser(b *testing.B) {
|
|
||||||
buf, err := ioutil.ReadFile("testdata/go1.html")
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("could not read testdata/go1.html: %v", err)
|
|
||||||
}
|
|
||||||
b.SetBytes(int64(len(buf)))
|
|
||||||
runtime.GC()
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Parse(bytes.NewBuffer(buf))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,156 +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) {
|
|
||||||
nodes := [...]*Node{
|
|
||||||
0: {
|
|
||||||
Type: ElementNode,
|
|
||||||
Data: "html",
|
|
||||||
},
|
|
||||||
1: {
|
|
||||||
Type: ElementNode,
|
|
||||||
Data: "head",
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
Type: ElementNode,
|
|
||||||
Data: "body",
|
|
||||||
},
|
|
||||||
3: {
|
|
||||||
Type: TextNode,
|
|
||||||
Data: "0<1",
|
|
||||||
},
|
|
||||||
4: {
|
|
||||||
Type: ElementNode,
|
|
||||||
Data: "p",
|
|
||||||
Attr: []Attribute{
|
|
||||||
{
|
|
||||||
Key: "id",
|
|
||||||
Val: "A",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Key: "foo",
|
|
||||||
Val: `abc"def`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
5: {
|
|
||||||
Type: TextNode,
|
|
||||||
Data: "2",
|
|
||||||
},
|
|
||||||
6: {
|
|
||||||
Type: ElementNode,
|
|
||||||
Data: "b",
|
|
||||||
Attr: []Attribute{
|
|
||||||
{
|
|
||||||
Key: "empty",
|
|
||||||
Val: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
7: {
|
|
||||||
Type: TextNode,
|
|
||||||
Data: "3",
|
|
||||||
},
|
|
||||||
8: {
|
|
||||||
Type: ElementNode,
|
|
||||||
Data: "i",
|
|
||||||
Attr: []Attribute{
|
|
||||||
{
|
|
||||||
Key: "backslash",
|
|
||||||
Val: `\`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
9: {
|
|
||||||
Type: TextNode,
|
|
||||||
Data: "&4",
|
|
||||||
},
|
|
||||||
10: {
|
|
||||||
Type: TextNode,
|
|
||||||
Data: "5",
|
|
||||||
},
|
|
||||||
11: {
|
|
||||||
Type: ElementNode,
|
|
||||||
Data: "blockquote",
|
|
||||||
},
|
|
||||||
12: {
|
|
||||||
Type: ElementNode,
|
|
||||||
Data: "br",
|
|
||||||
},
|
|
||||||
13: {
|
|
||||||
Type: TextNode,
|
|
||||||
Data: "6",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a tree out of those nodes, based on a textual representation.
|
|
||||||
// Only the ".\t"s are significant. The trailing HTML-like text is
|
|
||||||
// just commentary. The "0:" prefixes are for easy cross-reference with
|
|
||||||
// the nodes array.
|
|
||||||
treeAsText := [...]string{
|
|
||||||
0: `<html>`,
|
|
||||||
1: `. <head>`,
|
|
||||||
2: `. <body>`,
|
|
||||||
3: `. . "0<1"`,
|
|
||||||
4: `. . <p id="A" foo="abc"def">`,
|
|
||||||
5: `. . . "2"`,
|
|
||||||
6: `. . . <b empty="">`,
|
|
||||||
7: `. . . . "3"`,
|
|
||||||
8: `. . . <i backslash="\">`,
|
|
||||||
9: `. . . . "&4"`,
|
|
||||||
10: `. . "5"`,
|
|
||||||
11: `. . <blockquote>`,
|
|
||||||
12: `. . <br>`,
|
|
||||||
13: `. . "6"`,
|
|
||||||
}
|
|
||||||
if len(nodes) != len(treeAsText) {
|
|
||||||
t.Fatal("len(nodes) != len(treeAsText)")
|
|
||||||
}
|
|
||||||
var stack [8]*Node
|
|
||||||
for i, line := range treeAsText {
|
|
||||||
level := 0
|
|
||||||
for line[0] == '.' {
|
|
||||||
// Strip a leading ".\t".
|
|
||||||
line = line[2:]
|
|
||||||
level++
|
|
||||||
}
|
|
||||||
n := nodes[i]
|
|
||||||
if level == 0 {
|
|
||||||
if stack[0] != nil {
|
|
||||||
t.Fatal("multiple root nodes")
|
|
||||||
}
|
|
||||||
stack[0] = n
|
|
||||||
} else {
|
|
||||||
stack[level-1].AppendChild(n)
|
|
||||||
stack[level] = n
|
|
||||||
for i := level + 1; i < len(stack); i++ {
|
|
||||||
stack[i] = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// At each stage of tree construction, we check all nodes for consistency.
|
|
||||||
for j, m := range nodes {
|
|
||||||
if err := checkNodeConsistency(m); err != nil {
|
|
||||||
t.Fatalf("i=%d, j=%d: %v", i, j, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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, nodes[0]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if got := b.String(); got != want {
|
|
||||||
t.Errorf("got vs want:\n%s\n%s\n", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
#data
|
|
||||||
<table><math><select><mi><select></table>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math select>
|
|
||||||
| <math mi>
|
|
||||||
| <select>
|
|
||||||
| <table>
|
|
|
@ -1,62 +0,0 @@
|
||||||
#data
|
|
||||||
<body><template><yt-icon-button></yt-icon-button><form><paper-input></paper-input></form><style></style></template>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <template>
|
|
||||||
| content
|
|
||||||
| <yt-icon-button>
|
|
||||||
| <form>
|
|
||||||
| <paper-input>
|
|
||||||
| <style>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<template><tBody><isindex/action=0>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <template>
|
|
||||||
| content
|
|
||||||
| <tbody>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><template><mo><template>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math template>
|
|
||||||
| <math mo>
|
|
||||||
| <template>
|
|
||||||
| content
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><template><desc><t><svg></template>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg template>
|
|
||||||
| <svg desc>
|
|
||||||
| <t>
|
|
||||||
| <svg svg>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><template><mn><b></template>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math template>
|
|
||||||
| <math mn>
|
|
||||||
| <b>
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
|
||||||
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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"
|
|
|
@ -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>
|
|
|
@ -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"
|
|
|
@ -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"
|
|
|
@ -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>
|
|
|
@ -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"
|
|
|
@ -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>
|
|
BIN
vendor/golang.org/x/net/html/testdata/webkit/pending-spec-changes-plain-text-unsafe.dat
generated
vendored
BIN
vendor/golang.org/x/net/html/testdata/webkit/pending-spec-changes-plain-text-unsafe.dat
generated
vendored
Binary file not shown.
|
@ -1,52 +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"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><td><svg><desc><td></desc><circle>
|
|
||||||
#errors
|
|
||||||
7: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
|
|
||||||
30: A table cell was implicitly closed, but there were open elements.
|
|
||||||
26: Unclosed element “desc”.
|
|
||||||
20: Unclosed element “svg”.
|
|
||||||
37: Stray end tag “desc”.
|
|
||||||
45: End of file seen and there were open elements.
|
|
||||||
45: Unclosed element “circle”.
|
|
||||||
7: Unclosed element “table”.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg desc>
|
|
||||||
| <td>
|
|
||||||
| <circle>
|
|
Binary file not shown.
|
@ -1,298 +0,0 @@
|
||||||
#data
|
|
||||||
<html><ruby>a<rb>b<rb></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rb>
|
|
||||||
| "b"
|
|
||||||
| <rb>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rb>b<rt></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rb>
|
|
||||||
| "b"
|
|
||||||
| <rt>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rb>b<rtc></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rb>
|
|
||||||
| "b"
|
|
||||||
| <rtc>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rb>b<rp></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rb>
|
|
||||||
| "b"
|
|
||||||
| <rp>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rb>b<span></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rb>
|
|
||||||
| "b"
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rt>b<rb></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rt>
|
|
||||||
| "b"
|
|
||||||
| <rb>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rt>b<rt></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rt>
|
|
||||||
| "b"
|
|
||||||
| <rt>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rt>b<rtc></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rt>
|
|
||||||
| "b"
|
|
||||||
| <rtc>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rt>b<rp></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rt>
|
|
||||||
| "b"
|
|
||||||
| <rp>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rt>b<span></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rt>
|
|
||||||
| "b"
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rtc>b<rb></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rtc>
|
|
||||||
| "b"
|
|
||||||
| <rb>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rtc>b<rt>c<rt>d</ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rtc>
|
|
||||||
| "b"
|
|
||||||
| <rt>
|
|
||||||
| "c"
|
|
||||||
| <rt>
|
|
||||||
| "d"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rtc>b<rtc></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rtc>
|
|
||||||
| "b"
|
|
||||||
| <rtc>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rtc>b<rp></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rtc>
|
|
||||||
| "b"
|
|
||||||
| <rp>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rtc>b<span></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rtc>
|
|
||||||
| "b"
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rp>b<rb></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rp>
|
|
||||||
| "b"
|
|
||||||
| <rb>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rp>b<rt></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rp>
|
|
||||||
| "b"
|
|
||||||
| <rt>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rp>b<rtc></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rp>
|
|
||||||
| "b"
|
|
||||||
| <rtc>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rp>b<rp></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rp>
|
|
||||||
| "b"
|
|
||||||
| <rp>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby>a<rp>b<span></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rp>
|
|
||||||
| "b"
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><ruby><rtc><ruby>a<rb>b<rt></ruby></ruby></html>
|
|
||||||
#errors
|
|
||||||
(1,6): expected-doctype-but-got-start-tag
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| <rtc>
|
|
||||||
| <ruby>
|
|
||||||
| "a"
|
|
||||||
| <rb>
|
|
||||||
| "b"
|
|
||||||
| <rt>
|
|
|
@ -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"
|
|
|
@ -1,212 +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>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><td><svg><desc><td>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg desc>
|
|
||||||
| <td>
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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"
|
|
|
@ -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"
|
|
|
@ -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>
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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"
|
|
|
@ -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>
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,763 +0,0 @@
|
||||||
#data
|
|
||||||
<!DOCTYPE html>Test
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "Test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<textarea>test</div>test
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 24 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <textarea>
|
|
||||||
| "test</div>test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><td>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 11 Unexpected table cell start tag (td) in the table body phase.
|
|
||||||
Line: 1 Col: 11 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><td>test</tbody></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 11 Unexpected table cell start tag (td) in the table body phase.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| "test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frame>test
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (frame). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 7 Unexpected start tag frame. Ignored.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><frameset>test
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 29 Unepxected characters in the frameset phase. Characters ignored.
|
|
||||||
Line: 1 Col: 29 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><frameset><!DOCTYPE html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 40 Unexpected DOCTYPE. Ignored.
|
|
||||||
Line: 1 Col: 40 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><font><p><b>test</font>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 38 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm.
|
|
||||||
Line: 1 Col: 38 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <font>
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| <b>
|
|
||||||
| "test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><dt><div><dd>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 28 Missing end tag (div, dt).
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <dt>
|
|
||||||
| <div>
|
|
||||||
| <dd>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<script></x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 11 Unexpected end of file. Expected end tag (script).
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <script>
|
|
||||||
| "</x"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><plaintext><td>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 18 Unexpected start tag (plaintext) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 22 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <plaintext>
|
|
||||||
| "<td>"
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<plaintext></plaintext>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 11 Unexpected start tag (plaintext). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 23 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <plaintext>
|
|
||||||
| "</plaintext>"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><table><tr>TEST
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 30 Unexpected non-space characters in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 30 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "TEST"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body t1=1><body t2=2><body t3=3 t4=4>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 37 Unexpected start tag (body).
|
|
||||||
Line: 1 Col: 53 Unexpected start tag (body).
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| t1="1"
|
|
||||||
| t2="2"
|
|
||||||
| t3="3"
|
|
||||||
| t4="4"
|
|
||||||
|
|
||||||
#data
|
|
||||||
</b test
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected end of file in attribute name.
|
|
||||||
Line: 1 Col: 8 End tag contains unexpected attributes.
|
|
||||||
Line: 1 Col: 8 Unexpected end tag (b). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 8 Unexpected end tag (b) after the (implied) root element.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html></b test<b &=&>X
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 32 Named entity didn't end with ';'.
|
|
||||||
Line: 1 Col: 33 End tag contains unexpected attributes.
|
|
||||||
Line: 1 Col: 33 Unexpected end tag (b) after the (implied) root element.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctypehtml><scrIPt type=text/x-foobar;baz>X</SCRipt
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
|
|
||||||
Line: 1 Col: 54 Unexpected end of file in the tag name.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <script>
|
|
||||||
| type="text/x-foobar;baz"
|
|
||||||
| "X</SCRipt"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
&
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "&"
|
|
||||||
|
|
||||||
#data
|
|
||||||
&#
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 1 Numeric entity expected. Got end of file instead.
|
|
||||||
Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "&#"
|
|
||||||
|
|
||||||
#data
|
|
||||||
&#X
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 3 Numeric entity expected but none found.
|
|
||||||
Line: 1 Col: 3 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "&#X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
&#x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 3 Numeric entity expected but none found.
|
|
||||||
Line: 1 Col: 3 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "&#x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
-
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 4 Numeric entity didn't end with ';'.
|
|
||||||
Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "-"
|
|
||||||
|
|
||||||
#data
|
|
||||||
&x-test
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 1 Named entity expected. Got none.
|
|
||||||
Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "&x-test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctypehtml><p><li>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <li>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctypehtml><p><dt>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <dt>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctypehtml><p><dd>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <dd>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctypehtml><p><form>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
|
|
||||||
Line: 1 Col: 23 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <form>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><p></P>X
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
&
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 4 Named entity didn't end with ';'.
|
|
||||||
Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "&"
|
|
||||||
|
|
||||||
#data
|
|
||||||
&AMp;
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 1 Named entity expected. Got none.
|
|
||||||
Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "&AMp;"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><thisISasillyTESTelementNameToMakeSureCrazyTagNamesArePARSEDcorrectLY>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 110 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>X</body>X
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 24 Unexpected non-space characters in the after body phase.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "XX"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><!-- X
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 21 Unexpected end of file in comment.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <!-- X -->
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><table><caption>test TEST</caption><td>test
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 54 Unexpected table cell start tag (td) in the table body phase.
|
|
||||||
Line: 1 Col: 58 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
| "test TEST"
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| "test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><select><option><optgroup>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 41 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| <option>
|
|
||||||
| <optgroup>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><select><optgroup><option></optgroup><option><select><option>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 68 Unexpected select start tag in the select phase treated as select end tag.
|
|
||||||
Line: 1 Col: 76 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| <optgroup>
|
|
||||||
| <option>
|
|
||||||
| <option>
|
|
||||||
| <option>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><select><optgroup><option><optgroup>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 51 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| <optgroup>
|
|
||||||
| <option>
|
|
||||||
| <optgroup>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><datalist><option>foo</datalist>bar
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <datalist>
|
|
||||||
| <option>
|
|
||||||
| "foo"
|
|
||||||
| "bar"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><font><input><input></font>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <font>
|
|
||||||
| <input>
|
|
||||||
| <input>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><!-- XXX - XXX -->
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <!-- XXX - XXX -->
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><!-- XXX - XXX
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 29 Unexpected end of file in comment (-)
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <!-- XXX - XXX -->
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><!-- XXX - XXX - XXX -->
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <!-- XXX - XXX - XXX -->
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<isindex test=x name=x>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 23 Unexpected start tag (isindex). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 23 Unexpected start tag isindex. Don't use it!
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <form>
|
|
||||||
| <hr>
|
|
||||||
| <label>
|
|
||||||
| "This is a searchable index. Enter search keywords: "
|
|
||||||
| <input>
|
|
||||||
| name="isindex"
|
|
||||||
| test="x"
|
|
||||||
| <hr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
test
|
|
||||||
test
|
|
||||||
#errors
|
|
||||||
Line: 2 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "test
|
|
||||||
test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><title>test</body></title>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <title>
|
|
||||||
| "test</body>"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><title>X</title><meta name=z><link rel=foo><style>
|
|
||||||
x { content:"</style" } </style>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <title>
|
|
||||||
| "X"
|
|
||||||
| <meta>
|
|
||||||
| name="z"
|
|
||||||
| <link>
|
|
||||||
| rel="foo"
|
|
||||||
| <style>
|
|
||||||
| "
|
|
||||||
x { content:"</style" } "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><select><optgroup></optgroup></select>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| <optgroup>
|
|
||||||
|
|
||||||
#data
|
|
||||||
|
|
||||||
|
|
||||||
#errors
|
|
||||||
Line: 2 Col: 1 Unexpected End of file. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html> <html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><script>
|
|
||||||
</script> <title>x</title> </head>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <script>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| " "
|
|
||||||
| <title>
|
|
||||||
| "x"
|
|
||||||
| " "
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><body><html id=x>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 38 html needs to be the first start tag.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| id="x"
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>X</body><html id="x">
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 36 Unexpected start tag token (html) in the after body phase.
|
|
||||||
Line: 1 Col: 36 html needs to be the first start tag.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| id="x"
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><head><html id=x>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 32 html needs to be the first start tag.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| id="x"
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>X</html>X
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 24 Unexpected non-space characters in the after body phase.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "XX"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>X</html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "X "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>X</html><p>X
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 26 Unexpected start tag (p).
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "X"
|
|
||||||
| <p>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>X<p/x/y/z>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 19 Expected a > after the /.
|
|
||||||
Line: 1 Col: 21 Solidus (/) incorrectly placed in tag.
|
|
||||||
Line: 1 Col: 23 Solidus (/) incorrectly placed in tag.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "X"
|
|
||||||
| <p>
|
|
||||||
| x=""
|
|
||||||
| y=""
|
|
||||||
| z=""
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><!--x--
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 22 Unexpected end of file in comment (--).
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <!-- x -->
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><table><tr><td></p></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 34 Unexpected end tag (p). Ignored.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <p>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE <!DOCTYPE HTML>><!--<!--x-->-->
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 20 Expected space or '>'. Got ''
|
|
||||||
Line: 1 Col: 25 Erroneous DOCTYPE.
|
|
||||||
Line: 1 Col: 35 Unexpected character in comment found.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE <!doctype>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| ">"
|
|
||||||
| <!-- <!--x -->
|
|
||||||
| "-->"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><div><form></form><div></div></div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| <form>
|
|
||||||
| <div>
|
|
|
@ -1,455 +0,0 @@
|
||||||
#data
|
|
||||||
<!doctype html><p><button><button>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <button>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><address>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <address>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><blockquote>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <blockquote>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><menu>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <menu>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><p>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <p>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><ul>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <ul>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><h1>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <h1>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><h6>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <h6>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><listing>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <listing>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><pre>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <pre>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><form>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <form>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><li>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <li>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><dd>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <dd>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><dt>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <dt>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><plaintext>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <plaintext>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><table>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><hr>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <hr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button><xmp>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <xmp>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><button></p>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <button>
|
|
||||||
| <p>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><address><button></address>a
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <address>
|
|
||||||
| <button>
|
|
||||||
| "a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><address><button></address>a
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <address>
|
|
||||||
| <button>
|
|
||||||
| "a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p><table></p>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <p>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><svg>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><figcaption>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <figcaption>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><summary>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <summary>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><form><table><form>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <form>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><form><form>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <form>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><form></table><form>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <form>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><svg><foreignObject><p>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg foreignObject>
|
|
||||||
| <p>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><svg><title>abc
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg title>
|
|
||||||
| "abc"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<option><span><option>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <option>
|
|
||||||
| <span>
|
|
||||||
| <option>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<option><option>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <option>
|
|
||||||
| <option>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><annotation-xml><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math annotation-xml>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><annotation-xml encoding="application/svg+xml"><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math annotation-xml>
|
|
||||||
| encoding="application/svg+xml"
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><annotation-xml encoding="application/xhtml+xml"><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math annotation-xml>
|
|
||||||
| encoding="application/xhtml+xml"
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><annotation-xml encoding="aPPlication/xhtmL+xMl"><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math annotation-xml>
|
|
||||||
| encoding="aPPlication/xhtmL+xMl"
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><annotation-xml encoding="text/html"><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math annotation-xml>
|
|
||||||
| encoding="text/html"
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><annotation-xml encoding="Text/htmL"><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math annotation-xml>
|
|
||||||
| encoding="Text/htmL"
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><annotation-xml encoding=" text/html "><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math annotation-xml>
|
|
||||||
| encoding=" text/html "
|
|
||||||
| <div>
|
|
|
@ -1,221 +0,0 @@
|
||||||
#data
|
|
||||||
<svg><![CDATA[foo]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><![CDATA[foo]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| "foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div><![CDATA[foo]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| <!-- [CDATA[foo]] -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[foo
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[foo
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[]] >]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "]] >"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[]] >]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "]] >"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[]]
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "]]"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[]
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "]"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[]>a
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "]>a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><foreignObject><div><![CDATA[foo]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg foreignObject>
|
|
||||||
| <div>
|
|
||||||
| <!-- [CDATA[foo]] -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[<svg>]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "<svg>"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[</svg>a]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "</svg>a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[<svg>a
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "<svg>a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[</svg>a
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "</svg>a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[<svg>]]><path>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "<svg>"
|
|
||||||
| <svg path>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[<svg>]]></path>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "<svg>"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[<svg>]]><!--path-->
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "<svg>"
|
|
||||||
| <!-- path -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[<svg>]]>path
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "<svg>path"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><![CDATA[<!--svg-->]]>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| "<!--svg-->"
|
|
|
@ -1,157 +0,0 @@
|
||||||
#data
|
|
||||||
<a><b><big><em><strong><div>X</a>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| <b>
|
|
||||||
| <big>
|
|
||||||
| <em>
|
|
||||||
| <strong>
|
|
||||||
| <big>
|
|
||||||
| <em>
|
|
||||||
| <strong>
|
|
||||||
| <div>
|
|
||||||
| <a>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8>A</a>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| <b>
|
|
||||||
| <b>
|
|
||||||
| <div>
|
|
||||||
| id="1"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="2"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="3"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="4"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="5"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="6"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="7"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="8"
|
|
||||||
| <a>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8><div id=9>A</a>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| <b>
|
|
||||||
| <b>
|
|
||||||
| <div>
|
|
||||||
| id="1"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="2"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="3"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="4"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="5"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="6"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="7"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="8"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="9"
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><b><div id=1><div id=2><div id=3><div id=4><div id=5><div id=6><div id=7><div id=8><div id=9><div id=10>A</a>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| <b>
|
|
||||||
| <b>
|
|
||||||
| <div>
|
|
||||||
| id="1"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="2"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="3"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="4"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="5"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="6"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="7"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="8"
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| id="9"
|
|
||||||
| <div>
|
|
||||||
| id="10"
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<cite><b><cite><i><cite><i><cite><i><div>X</b>TEST
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected start tag (cite). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 46 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
|
|
||||||
Line: 1 Col: 50 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <cite>
|
|
||||||
| <b>
|
|
||||||
| <cite>
|
|
||||||
| <i>
|
|
||||||
| <cite>
|
|
||||||
| <i>
|
|
||||||
| <cite>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <div>
|
|
||||||
| <b>
|
|
||||||
| "X"
|
|
||||||
| "TEST"
|
|
|
@ -1,155 +0,0 @@
|
||||||
#data
|
|
||||||
<p><font size=4><font color=red><font size=4><font size=4><font size=4><font size=4><font size=4><font color=red><p>X
|
|
||||||
#errors
|
|
||||||
3: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
|
|
||||||
116: Unclosed elements.
|
|
||||||
117: End of file seen and there were open elements.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p><font size=4><font size=4><font size=4><font size=4><p>X
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p><font size=4><font size=4><font size=4><font size="5"><font size=4><p>X
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="5"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="5"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p><font size=4 id=a><font size=4 id=b><font size=4><font size=4><p>X
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| id="a"
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| id="b"
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| id="a"
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| id="b"
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| <font>
|
|
||||||
| size="4"
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p><b id=a><b id=a><b id=a><b><object><b id=a><b id=a>X</object><p>Y
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <b>
|
|
||||||
| id="a"
|
|
||||||
| <b>
|
|
||||||
| id="a"
|
|
||||||
| <b>
|
|
||||||
| id="a"
|
|
||||||
| <b>
|
|
||||||
| <object>
|
|
||||||
| <b>
|
|
||||||
| id="a"
|
|
||||||
| <b>
|
|
||||||
| id="a"
|
|
||||||
| "X"
|
|
||||||
| <p>
|
|
||||||
| <b>
|
|
||||||
| id="a"
|
|
||||||
| <b>
|
|
||||||
| id="a"
|
|
||||||
| <b>
|
|
||||||
| id="a"
|
|
||||||
| <b>
|
|
||||||
| "Y"
|
|
|
@ -1,79 +0,0 @@
|
||||||
#data
|
|
||||||
<!DOCTYPE html>≂̸
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "≂̸"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>≂̸A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "≂̸A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>  
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| " "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>  A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| " A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>⊂⃒
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "⊂⃒"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>⊂⃒A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "⊂⃒A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>𝔾
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "𝔾"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html>𝔾A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "𝔾A"
|
|
|
@ -1,219 +0,0 @@
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><foo>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <foo>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><area>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <area>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><base>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <base>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><basefont>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <basefont>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><bgsound>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <bgsound>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><br>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <br>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><col>A
|
|
||||||
#errors
|
|
||||||
26: Stray start tag “col”.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><command>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <command>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><embed>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <embed>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><frame>A
|
|
||||||
#errors
|
|
||||||
26: Stray start tag “frame”.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><hr>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <hr>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><img>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <img>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><input>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <input>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><keygen>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <keygen>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><link>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <link>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><meta>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <meta>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><param>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <param>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><source>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <source>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><track>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <track>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><wbr>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <wbr>
|
|
||||||
| "A"
|
|
|
@ -1,313 +0,0 @@
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><a href='#1'><nobr>1<nobr></a><br><a href='#2'><nobr>2<nobr></a><br><a href='#3'><nobr>3<nobr></a>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| href="#1"
|
|
||||||
| <nobr>
|
|
||||||
| "1"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <br>
|
|
||||||
| <a>
|
|
||||||
| href="#2"
|
|
||||||
| <a>
|
|
||||||
| href="#2"
|
|
||||||
| <nobr>
|
|
||||||
| "2"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <br>
|
|
||||||
| <a>
|
|
||||||
| href="#3"
|
|
||||||
| <a>
|
|
||||||
| href="#3"
|
|
||||||
| <nobr>
|
|
||||||
| "3"
|
|
||||||
| <nobr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><b><nobr>1<nobr></b><i><nobr>2<nobr></i>3
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "1"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <nobr>
|
|
||||||
| "2"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| "3"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><b><nobr>1<table><nobr></b><i><nobr>2<nobr></i>3
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "1"
|
|
||||||
| <nobr>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <nobr>
|
|
||||||
| "2"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| "3"
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><b><nobr>1<table><tr><td><nobr></b><i><nobr>2<nobr></i>3
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "1"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <nobr>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <nobr>
|
|
||||||
| "2"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| "3"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><b><nobr>1<div><nobr></b><i><nobr>2<nobr></i>3
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "1"
|
|
||||||
| <div>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <nobr>
|
|
||||||
| "2"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| "3"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><b><nobr>1<nobr></b><div><i><nobr>2<nobr></i>3
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "1"
|
|
||||||
| <nobr>
|
|
||||||
| <div>
|
|
||||||
| <nobr>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <nobr>
|
|
||||||
| "2"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| "3"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><b><nobr>1<nobr><ins></b><i><nobr>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "1"
|
|
||||||
| <nobr>
|
|
||||||
| <ins>
|
|
||||||
| <nobr>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <nobr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><b><nobr>1<ins><nobr></b><i>2
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "1"
|
|
||||||
| <ins>
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <i>
|
|
||||||
| "2"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><b>1<nobr></b><i><nobr>2</i>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| "1"
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| <nobr>
|
|
||||||
| "2"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p><code x</code></p>
|
|
||||||
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <code>
|
|
||||||
| code=""
|
|
||||||
| x<=""
|
|
||||||
| <code>
|
|
||||||
| code=""
|
|
||||||
| x<=""
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><svg><foreignObject><p><i></p>a
|
|
||||||
#errors
|
|
||||||
45: End tag “p” seen, but there were open elements.
|
|
||||||
41: Unclosed element “i”.
|
|
||||||
46: End of file seen and there were open elements.
|
|
||||||
35: Unclosed element “foreignObject”.
|
|
||||||
20: Unclosed element “svg”.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg foreignObject>
|
|
||||||
| <p>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| "a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><table><tr><td><svg><foreignObject><p><i></p>a
|
|
||||||
#errors
|
|
||||||
56: End tag “p” seen, but there were open elements.
|
|
||||||
52: Unclosed element “i”.
|
|
||||||
57: End of file seen and there were open elements.
|
|
||||||
46: Unclosed element “foreignObject”.
|
|
||||||
31: Unclosed element “svg”.
|
|
||||||
22: Unclosed element “table”.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg foreignObject>
|
|
||||||
| <p>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| "a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><math><mtext><p><i></p>a
|
|
||||||
#errors
|
|
||||||
38: End tag “p” seen, but there were open elements.
|
|
||||||
34: Unclosed element “i”.
|
|
||||||
39: End of file in a foreign namespace context.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mtext>
|
|
||||||
| <p>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| "a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><table><tr><td><math><mtext><p><i></p>a
|
|
||||||
#errors
|
|
||||||
53: End tag “p” seen, but there were open elements.
|
|
||||||
49: Unclosed element “i”.
|
|
||||||
54: End of file in a foreign namespace context.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <math math>
|
|
||||||
| <math mtext>
|
|
||||||
| <p>
|
|
||||||
| <i>
|
|
||||||
| <i>
|
|
||||||
| "a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><div><!/div>a
|
|
||||||
#errors
|
|
||||||
29: Bogus comment.
|
|
||||||
34: End of file seen and there were open elements.
|
|
||||||
26: Unclosed element “div”.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| <!-- /div -->
|
|
||||||
| "a"
|
|
|
@ -1,305 +0,0 @@
|
||||||
#data
|
|
||||||
<head></head><style></style>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 20 Unexpected start tag (style) that can be in head. Moved.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <style>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<head></head><script></script>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 21 Unexpected start tag (script) that can be in head. Moved.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <script>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<head></head><!-- --><style></style><!-- --><script></script>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 28 Unexpected start tag (style) that can be in head. Moved.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <style>
|
|
||||||
| <script>
|
|
||||||
| <!-- -->
|
|
||||||
| <!-- -->
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<head></head><!-- -->x<style></style><!-- --><script></script>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <!-- -->
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
| <style>
|
|
||||||
| <!-- -->
|
|
||||||
| <script>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><pre>
|
|
||||||
</pre></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <pre>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><pre>
|
|
||||||
foo</pre></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <pre>
|
|
||||||
| "foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><pre>
|
|
||||||
|
|
||||||
foo</pre></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <pre>
|
|
||||||
| "
|
|
||||||
foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><pre>
|
|
||||||
foo
|
|
||||||
</pre></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <pre>
|
|
||||||
| "foo
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><pre>x</pre><span>
|
|
||||||
</span></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <pre>
|
|
||||||
| "x"
|
|
||||||
| <span>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><pre>x
|
|
||||||
y</pre></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <pre>
|
|
||||||
| "x
|
|
||||||
y"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><pre>x<div>
|
|
||||||
y</pre></body></html>
|
|
||||||
#errors
|
|
||||||
Line: 2 Col: 7 End tag (pre) seen too early. Expected other end tag.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <pre>
|
|
||||||
| "x"
|
|
||||||
| <div>
|
|
||||||
| "
|
|
||||||
y"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><pre>

A</pre>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <pre>
|
|
||||||
| "
|
|
||||||
A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><HTML><META><HEAD></HEAD></HTML>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 33 Unexpected start tag head in existing head. Ignored.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <meta>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><HTML><HEAD><head></HEAD></HTML>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 33 Unexpected start tag head in existing head. Ignored.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<textarea>foo<span>bar</span><i>baz
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 35 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <textarea>
|
|
||||||
| "foo<span>bar</span><i>baz"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<title>foo<span>bar</em><i>baz
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 30 Unexpected end of file. Expected end tag (title).
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| "foo<span>bar</em><i>baz"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><textarea>
|
|
||||||
</textarea>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <textarea>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><textarea>
|
|
||||||
foo</textarea>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <textarea>
|
|
||||||
| "foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><textarea>
|
|
||||||
|
|
||||||
foo</textarea>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <textarea>
|
|
||||||
| "
|
|
||||||
foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><html><head></head><body><ul><li><div><p><li></ul></body></html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 60 Missing end tag (div, li).
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ul>
|
|
||||||
| <li>
|
|
||||||
| <div>
|
|
||||||
| <p>
|
|
||||||
| <li>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><nobr><nobr><nobr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 27 Unexpected start tag (nobr) implies end tag (nobr).
|
|
||||||
Line: 1 Col: 33 Unexpected start tag (nobr) implies end tag (nobr).
|
|
||||||
Line: 1 Col: 33 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><nobr><nobr></nobr><nobr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 27 Unexpected start tag (nobr) implies end tag (nobr).
|
|
||||||
Line: 1 Col: 40 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
| <nobr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><html><body><p><table></table></body></html>
|
|
||||||
#errors
|
|
||||||
Not known
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p><table></table>
|
|
||||||
#errors
|
|
||||||
Not known
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <table>
|
|
|
@ -1,59 +0,0 @@
|
||||||
#data
|
|
||||||
direct div content
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
div
|
|
||||||
#document
|
|
||||||
| "direct div content"
|
|
||||||
|
|
||||||
#data
|
|
||||||
direct textarea content
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
textarea
|
|
||||||
#document
|
|
||||||
| "direct textarea content"
|
|
||||||
|
|
||||||
#data
|
|
||||||
textarea content with <em>pseudo</em> <foo>markup
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
textarea
|
|
||||||
#document
|
|
||||||
| "textarea content with <em>pseudo</em> <foo>markup"
|
|
||||||
|
|
||||||
#data
|
|
||||||
this is CDATA inside a <style> element
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
style
|
|
||||||
#document
|
|
||||||
| "this is CDATA inside a <style> element"
|
|
||||||
|
|
||||||
#data
|
|
||||||
</plaintext>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
plaintext
|
|
||||||
#document
|
|
||||||
| "</plaintext>"
|
|
||||||
|
|
||||||
#data
|
|
||||||
setting html's innerHTML
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 24 Unexpected EOF in inner html mode.
|
|
||||||
#document-fragment
|
|
||||||
html
|
|
||||||
#document
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "setting html's innerHTML"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<title>setting head's innerHTML</title>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
head
|
|
||||||
#document
|
|
||||||
| <title>
|
|
||||||
| "setting head's innerHTML"
|
|
|
@ -1,191 +0,0 @@
|
||||||
#data
|
|
||||||
<style> <!-- </style>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 22 Unexpected end of file. Expected end tag (style).
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <style>
|
|
||||||
| " <!-- "
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<style> <!-- </style> --> </style>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <style>
|
|
||||||
| " <!-- "
|
|
||||||
| " "
|
|
||||||
| <body>
|
|
||||||
| "--> x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<style> <!--> </style>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <style>
|
|
||||||
| " <!--> "
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<style> <!---> </style>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <style>
|
|
||||||
| " <!---> "
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<iframe> <!---> </iframe>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <iframe>
|
|
||||||
| " <!---> "
|
|
||||||
| "x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<iframe> <!--- </iframe>->x</iframe> --> </iframe>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <iframe>
|
|
||||||
| " <!--- "
|
|
||||||
| "->x --> x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<script> <!-- </script> --> </script>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <script>
|
|
||||||
| " <!-- "
|
|
||||||
| " "
|
|
||||||
| <body>
|
|
||||||
| "--> x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<title> <!-- </title> --> </title>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| " <!-- "
|
|
||||||
| " "
|
|
||||||
| <body>
|
|
||||||
| "--> x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<textarea> <!--- </textarea>->x</textarea> --> </textarea>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <textarea>
|
|
||||||
| " <!--- "
|
|
||||||
| "->x --> x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<style> <!</-- </style>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <style>
|
|
||||||
| " <!</-- "
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p><xmp></xmp>
|
|
||||||
#errors
|
|
||||||
XXX: Unknown
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <xmp>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<xmp> <!-- > --> </xmp>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 5 Unexpected start tag (xmp). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <xmp>
|
|
||||||
| " <!-- > --> "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<title>&</title>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| "&"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<title><!--&--></title>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| "<!--&-->"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<title><!--</title>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 19 Unexpected end of file. Expected end tag (title).
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| "<!--"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<noscript><!--</noscript>--></noscript>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <noscript>
|
|
||||||
| "<!--"
|
|
||||||
| <body>
|
|
||||||
| "-->"
|
|
|
@ -1,663 +0,0 @@
|
||||||
#data
|
|
||||||
<!doctype html></head> <head>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 29 Unexpected start tag head. Ignored.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| " "
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><form><div></form><div>
|
|
||||||
#errors
|
|
||||||
33: End tag "form" seen but there were unclosed elements.
|
|
||||||
38: End of file seen and there were open elements.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <form>
|
|
||||||
| <div>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><title>&</title>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| "&"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><title><!--&--></title>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| "<!--&-->"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 9 No space after literal string 'DOCTYPE'.
|
|
||||||
Line: 1 Col: 10 Unexpected > character. Expected DOCTYPE name.
|
|
||||||
Line: 1 Col: 10 Erroneous DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE >
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!---x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected end of file in comment.
|
|
||||||
Line: 1 Col: 6 Unexpected End of file. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <!-- -x -->
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<body>
|
|
||||||
<div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected start tag (body).
|
|
||||||
Line: 2 Col: 5 Expected closing tag. Unexpected end of file.
|
|
||||||
#document-fragment
|
|
||||||
div
|
|
||||||
#document
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset></frameset>
|
|
||||||
foo
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
|
|
||||||
Line: 2 Col: 3 Unexpected non-space characters in the after frameset phase. Ignored.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset></frameset>
|
|
||||||
<noframes>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
|
|
||||||
Line: 2 Col: 10 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <noframes>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset></frameset>
|
|
||||||
<div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
|
|
||||||
Line: 2 Col: 5 Unexpected start tag (div) in the after frameset phase. Ignored.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset></frameset>
|
|
||||||
</html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset></frameset>
|
|
||||||
</div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
|
|
||||||
Line: 2 Col: 6 Unexpected end tag (div) in the after frameset phase. Ignored.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<form><form>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected start tag (form). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 12 Unexpected start tag (form).
|
|
||||||
Line: 1 Col: 12 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <form>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<button><button>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected start tag (button). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 16 Unexpected start tag (button) implies end tag (button).
|
|
||||||
Line: 1 Col: 16 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <button>
|
|
||||||
| <button>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><td></th>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 20 Unexpected end tag (th). Ignored.
|
|
||||||
Line: 1 Col: 20 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><caption><td>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 20 Unexpected end tag (td). Ignored.
|
|
||||||
Line: 1 Col: 20 Unexpected table cell start tag (td) in the table body phase.
|
|
||||||
Line: 1 Col: 20 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><caption><div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 21 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</caption><div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected end tag (caption). Ignored.
|
|
||||||
Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><caption><div></caption>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 31 Unexpected end tag (caption). Missing end tag (div).
|
|
||||||
Line: 1 Col: 31 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><caption></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 24 Unexpected end table tag in caption. Generates implied end caption.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table><div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected end table tag in caption. Generates implied end caption.
|
|
||||||
Line: 1 Col: 8 Unexpected end tag (caption). Ignored.
|
|
||||||
Line: 1 Col: 13 Expected closing tag. Unexpected end of file.
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><caption></body></col></colgroup></html></tbody></td></tfoot></th></thead></tr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 23 Unexpected end tag (body). Ignored.
|
|
||||||
Line: 1 Col: 29 Unexpected end tag (col). Ignored.
|
|
||||||
Line: 1 Col: 40 Unexpected end tag (colgroup). Ignored.
|
|
||||||
Line: 1 Col: 47 Unexpected end tag (html). Ignored.
|
|
||||||
Line: 1 Col: 55 Unexpected end tag (tbody). Ignored.
|
|
||||||
Line: 1 Col: 60 Unexpected end tag (td). Ignored.
|
|
||||||
Line: 1 Col: 68 Unexpected end tag (tfoot). Ignored.
|
|
||||||
Line: 1 Col: 73 Unexpected end tag (th). Ignored.
|
|
||||||
Line: 1 Col: 81 Unexpected end tag (thead). Ignored.
|
|
||||||
Line: 1 Col: 86 Unexpected end tag (tr). Ignored.
|
|
||||||
Line: 1 Col: 86 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><caption><div></div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 27 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><td></body></caption></col></colgroup></html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 22 Unexpected end tag (body). Ignored.
|
|
||||||
Line: 1 Col: 32 Unexpected end tag (caption). Ignored.
|
|
||||||
Line: 1 Col: 38 Unexpected end tag (col). Ignored.
|
|
||||||
Line: 1 Col: 49 Unexpected end tag (colgroup). Ignored.
|
|
||||||
Line: 1 Col: 56 Unexpected end tag (html). Ignored.
|
|
||||||
Line: 1 Col: 56 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table></tbody></tfoot></thead></tr><div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected end tag (table). Ignored.
|
|
||||||
Line: 1 Col: 16 Unexpected end tag (tbody). Ignored.
|
|
||||||
Line: 1 Col: 24 Unexpected end tag (tfoot). Ignored.
|
|
||||||
Line: 1 Col: 32 Unexpected end tag (thead). Ignored.
|
|
||||||
Line: 1 Col: 37 Unexpected end tag (tr). Ignored.
|
|
||||||
Line: 1 Col: 42 Expected closing tag. Unexpected end of file.
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><colgroup>foo
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 20 Unexpected non-space characters in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 20 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "foo"
|
|
||||||
| <table>
|
|
||||||
| <colgroup>
|
|
||||||
|
|
||||||
#data
|
|
||||||
foo<col>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 3 Unexpected end tag (colgroup). Ignored.
|
|
||||||
#document-fragment
|
|
||||||
colgroup
|
|
||||||
#document
|
|
||||||
| <col>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><colgroup></col>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 23 This element (col) has no end tag.
|
|
||||||
Line: 1 Col: 23 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <colgroup>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset><div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 15 Unexpected start tag token (div) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</frameset><frame>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 11 Unexpected end tag token (frameset) in the frameset phase (innerHTML).
|
|
||||||
#document-fragment
|
|
||||||
frameset
|
|
||||||
#document
|
|
||||||
| <frame>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset></div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 16 Unexpected end tag token (div) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 16 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</body><div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected end tag (body). Ignored.
|
|
||||||
Line: 1 Col: 12 Expected closing tag. Unexpected end of file.
|
|
||||||
#document-fragment
|
|
||||||
body
|
|
||||||
#document
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 16 Unexpected start tag (div) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 16 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</tr><td>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 5 Unexpected end tag (tr). Ignored.
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</tbody></tfoot></thead><td>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected end tag (tbody). Ignored.
|
|
||||||
Line: 1 Col: 16 Unexpected end tag (tfoot). Ignored.
|
|
||||||
Line: 1 Col: 24 Unexpected end tag (thead). Ignored.
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><div><td>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 16 Unexpected start tag (div) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 20 Unexpected implied end tag (div) in the table row phase.
|
|
||||||
Line: 1 Col: 20 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<caption><col><colgroup><tbody><tfoot><thead><tr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 9 Unexpected start tag (caption).
|
|
||||||
Line: 1 Col: 14 Unexpected start tag (col).
|
|
||||||
Line: 1 Col: 24 Unexpected start tag (colgroup).
|
|
||||||
Line: 1 Col: 31 Unexpected start tag (tbody).
|
|
||||||
Line: 1 Col: 38 Unexpected start tag (tfoot).
|
|
||||||
Line: 1 Col: 45 Unexpected start tag (thead).
|
|
||||||
Line: 1 Col: 49 Unexpected end of file. Expected table content.
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tbody></thead>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 22 Unexpected end tag (thead) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 22 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table><tr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected end tag (table). Ignored.
|
|
||||||
Line: 1 Col: 12 Unexpected end of file. Expected table content.
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tbody></body></caption></col></colgroup></html></td></th></tr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 21 Unexpected end tag (body) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 31 Unexpected end tag (caption) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 37 Unexpected end tag (col) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 48 Unexpected end tag (colgroup) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 55 Unexpected end tag (html) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 60 Unexpected end tag (td) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 65 Unexpected end tag (th) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 70 Unexpected end tag (tr) in the table body phase. Ignored.
|
|
||||||
Line: 1 Col: 70 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tbody></div>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 20 Unexpected end tag (div) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 20 End tag (div) seen too early. Expected other end tag.
|
|
||||||
Line: 1 Col: 20 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 14 Unexpected start tag (table) implies end tag (table).
|
|
||||||
Line: 1 Col: 14 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table></body></caption></col></colgroup></html></tbody></td></tfoot></th></thead></tr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 14 Unexpected end tag (body). Ignored.
|
|
||||||
Line: 1 Col: 24 Unexpected end tag (caption). Ignored.
|
|
||||||
Line: 1 Col: 30 Unexpected end tag (col). Ignored.
|
|
||||||
Line: 1 Col: 41 Unexpected end tag (colgroup). Ignored.
|
|
||||||
Line: 1 Col: 48 Unexpected end tag (html). Ignored.
|
|
||||||
Line: 1 Col: 56 Unexpected end tag (tbody). Ignored.
|
|
||||||
Line: 1 Col: 61 Unexpected end tag (td). Ignored.
|
|
||||||
Line: 1 Col: 69 Unexpected end tag (tfoot). Ignored.
|
|
||||||
Line: 1 Col: 74 Unexpected end tag (th). Ignored.
|
|
||||||
Line: 1 Col: 82 Unexpected end tag (thead). Ignored.
|
|
||||||
Line: 1 Col: 87 Unexpected end tag (tr). Ignored.
|
|
||||||
Line: 1 Col: 87 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table><tr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 8 Unexpected end tag (table). Ignored.
|
|
||||||
Line: 1 Col: 12 Unexpected end of file. Expected table content.
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<body></body></html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 20 Unexpected html end tag in inner html mode.
|
|
||||||
Line: 1 Col: 20 Unexpected EOF in inner html mode.
|
|
||||||
#document-fragment
|
|
||||||
html
|
|
||||||
#document
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><frameset></frameset></html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
| " "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"><html></html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 50 Erroneous DOCTYPE.
|
|
||||||
Line: 1 Col: 63 Unexpected end tag (html) after the (implied) root element.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html "-//W3C//DTD HTML 4.01//EN" "">
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<param><frameset></frameset>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (param). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 17 Unexpected start tag (frameset).
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<source><frameset></frameset>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (source). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 17 Unexpected start tag (frameset).
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<track><frameset></frameset>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (track). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 17 Unexpected start tag (frameset).
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</html><frameset></frameset>
|
|
||||||
#errors
|
|
||||||
7: End tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
|
|
||||||
17: Stray “frameset” start tag.
|
|
||||||
17: “frameset” start tag seen.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</body><frameset></frameset>
|
|
||||||
#errors
|
|
||||||
7: End tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
|
|
||||||
17: Stray “frameset” start tag.
|
|
||||||
17: “frameset” start tag seen.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
|
@ -1,390 +0,0 @@
|
||||||
#data
|
|
||||||
<!doctype html><body><title>X</title>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <title>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><title>X</title></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 29 Unexpected start tag (title) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 38 Unexpected end tag (title) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <title>
|
|
||||||
| "X"
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><head></head><title>X</title>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 35 Unexpected start tag (title) that can be in head. Moved.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| "X"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html></head><title>X</title>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 29 Unexpected start tag (title) that can be in head. Moved.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <title>
|
|
||||||
| "X"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><meta></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 28 Unexpected start tag (meta) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <meta>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table>X<tr><td><table> <meta></table></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 23 Unexpected non-space characters in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 45 Unexpected start tag (meta) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "X"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <meta>
|
|
||||||
| <table>
|
|
||||||
| " "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><html> <head>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html> <head>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><style> <tr>x </style> </table>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <style>
|
|
||||||
| " <tr>x "
|
|
||||||
| " "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><TBODY><script> <tr>x </script> </table>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <script>
|
|
||||||
| " <tr>x "
|
|
||||||
| " "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><p><applet><p>X</p></applet>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <applet>
|
|
||||||
| <p>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><listing>
|
|
||||||
X</listing>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <listing>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><select><input>X
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 30 Unexpected input start tag in the select phase.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| <input>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><select><select>X
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 31 Unexpected select start tag in the select phase treated as select end tag.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><input type=hidDEN></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 41 Unexpected input with type hidden in table context.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <input>
|
|
||||||
| type="hidDEN"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table>X<input type=hidDEN></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 23 Unexpected non-space characters in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "X"
|
|
||||||
| <table>
|
|
||||||
| <input>
|
|
||||||
| type="hidDEN"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table> <input type=hidDEN></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 43 Unexpected input with type hidden in table context.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| " "
|
|
||||||
| <input>
|
|
||||||
| type="hidDEN"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table> <input type='hidDEN'></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 45 Unexpected input with type hidden in table context.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| " "
|
|
||||||
| <input>
|
|
||||||
| type="hidDEN"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><input type=" hidden"><input type=hidDEN></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 44 Unexpected start tag (input) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <input>
|
|
||||||
| type=" hidden"
|
|
||||||
| <table>
|
|
||||||
| <input>
|
|
||||||
| type="hidDEN"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><table><select>X<tr>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 30 Unexpected start tag (select) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 35 Unexpected table element start tag (trs) in the select in table phase.
|
|
||||||
Line: 1 Col: 35 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| "X"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><select>X</select>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE hTmL><html></html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 28 Unexpected end tag (html) after the (implied) root element.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE HTML><html></html>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 28 Unexpected end tag (html) after the (implied) root element.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<body>X</body></body>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 21 Unexpected end tag token (body) in the after body phase.
|
|
||||||
Line: 1 Col: 21 Unexpected EOF in inner html mode.
|
|
||||||
#document-fragment
|
|
||||||
html
|
|
||||||
#document
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "X"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div><p>a</x> b
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 13 Unexpected end tag (x). Ignored.
|
|
||||||
Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| <p>
|
|
||||||
| "a b"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><td><code></code> </table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <code>
|
|
||||||
| " "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><b><tr><td>aaa</td></tr>bbb</table>ccc
|
|
||||||
#errors
|
|
||||||
XXX: Fix me
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <b>
|
|
||||||
| "bbb"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| "aaa"
|
|
||||||
| <b>
|
|
||||||
| "ccc"
|
|
||||||
|
|
||||||
#data
|
|
||||||
A<table><tr> B</tr> B</table>
|
|
||||||
#errors
|
|
||||||
XXX: Fix me
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "A B B"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
A<table><tr> B</tr> </em>C</table>
|
|
||||||
#errors
|
|
||||||
XXX: Fix me
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "A BC"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| " "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<select><keygen>
|
|
||||||
#errors
|
|
||||||
Not known
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| <keygen>
|
|
|
@ -1,148 +0,0 @@
|
||||||
#data
|
|
||||||
<div>
|
|
||||||
<div></div>
|
|
||||||
</span>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
|
|
||||||
Line: 3 Col: 7 Unexpected end tag (span). Ignored.
|
|
||||||
Line: 3 Col: 8 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <div>
|
|
||||||
| "
|
|
||||||
x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div>x<div></div>
|
|
||||||
</span>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
|
|
||||||
Line: 2 Col: 7 Unexpected end tag (span). Ignored.
|
|
||||||
Line: 2 Col: 8 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| "x"
|
|
||||||
| <div>
|
|
||||||
| "
|
|
||||||
x"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div>x<div></div>x</span>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 25 Unexpected end tag (span). Ignored.
|
|
||||||
Line: 1 Col: 26 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| "x"
|
|
||||||
| <div>
|
|
||||||
| "xx"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div>x<div></div>y</span>z
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 5 Unexpected start tag (div). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 25 Unexpected end tag (span). Ignored.
|
|
||||||
Line: 1 Col: 26 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| "x"
|
|
||||||
| <div>
|
|
||||||
| "yz"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><div>x<div></div>x</span>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 12 Unexpected start tag (div) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 18 Unexpected start tag (div) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 24 Unexpected end tag (div) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 32 Unexpected end tag (span) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 32 Unexpected end tag (span). Ignored.
|
|
||||||
Line: 1 Col: 33 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| "x"
|
|
||||||
| <div>
|
|
||||||
| "xx"
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
x<table>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 9 Unexpected non-space characters in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 9 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "xx"
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
x<table><table>x
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 15 Unexpected start tag (table) implies end tag (table).
|
|
||||||
Line: 1 Col: 16 Unexpected non-space characters in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 16 Unexpected end of file. Expected table content.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
| <table>
|
|
||||||
| "x"
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<b>a<div></div><div></b>y
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 3 Unexpected start tag (b). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 24 End tag (b) violates step 1, paragraph 3 of the adoption agency algorithm.
|
|
||||||
Line: 1 Col: 25 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| "a"
|
|
||||||
| <div>
|
|
||||||
| <div>
|
|
||||||
| <b>
|
|
||||||
| "y"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><div><p></a>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 3 Unexpected start tag (a). Expected DOCTYPE.
|
|
||||||
Line: 1 Col: 15 End tag (a) violates step 1, paragraph 3 of the adoption agency algorithm.
|
|
||||||
Line: 1 Col: 15 End tag (a) violates step 1, paragraph 3 of the adoption agency algorithm.
|
|
||||||
Line: 1 Col: 15 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| <a>
|
|
||||||
| <p>
|
|
||||||
| <a>
|
|
|
@ -1,457 +0,0 @@
|
||||||
#data
|
|
||||||
<!DOCTYPE html><math></math>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><math></math>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><math><mi>
|
|
||||||
#errors
|
|
||||||
25: End of file in a foreign namespace context.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><math><annotation-xml><svg><u>
|
|
||||||
#errors
|
|
||||||
45: HTML start tag “u” in a foreign namespace context.
|
|
||||||
45: End of file seen and there were open elements.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math annotation-xml>
|
|
||||||
| <svg svg>
|
|
||||||
| <u>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><select><math></math></select>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 35 Unexpected start tag token (math) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 42 Unexpected end tag (math) in the select phase. Ignored.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><select><option><math></math></option></select>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 43 Unexpected start tag token (math) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 50 Unexpected end tag (math) in the select phase. Ignored.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| <option>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><math></math></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 34 Unexpected start tag (math) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 41 Unexpected end tag (math) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><math><mi>foo</mi></math></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 34 Unexpected start tag (math) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 46 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 53 Unexpected end tag (math) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><math><mi>foo</mi><mi>bar</mi></math></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 34 Unexpected start tag (math) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 46 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 58 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 65 Unexpected end tag (math) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><tbody><math><mi>foo</mi><mi>bar</mi></math></tbody></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 41 Unexpected start tag (math) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 53 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 65 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 72 Unexpected end tag (math) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><tbody><tr><math><mi>foo</mi><mi>bar</mi></math></tr></tbody></table>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 45 Unexpected start tag (math) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 57 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 69 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 76 Unexpected end tag (math) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math></td></tr></tbody></table>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><tbody><tr><td><math><mi>foo</mi><mi>bar</mi></math><p>baz</td></tr></tbody></table>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <p>
|
|
||||||
| "baz"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi></math><p>baz</caption></table>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <p>
|
|
||||||
| "baz"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 70 HTML start tag "p" in a foreign namespace context.
|
|
||||||
Line: 1 Col: 81 Unexpected end table tag in caption. Generates implied end caption.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <p>
|
|
||||||
| "baz"
|
|
||||||
| <p>
|
|
||||||
| "quux"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi>baz</table><p>quux
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 78 Unexpected end table tag in caption. Generates implied end caption.
|
|
||||||
Line: 1 Col: 78 Unexpected end tag (caption). Missing end tag (math).
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <caption>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| "baz"
|
|
||||||
| <p>
|
|
||||||
| "quux"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><colgroup><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 44 Unexpected start tag (math) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 56 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 68 Unexpected end tag (mi) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 71 HTML start tag "p" in a foreign namespace context.
|
|
||||||
Line: 1 Col: 71 Unexpected start tag (p) in table context caused voodoo mode.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <p>
|
|
||||||
| "baz"
|
|
||||||
| <table>
|
|
||||||
| <colgroup>
|
|
||||||
| <p>
|
|
||||||
| "quux"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><tr><td><select><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 50 Unexpected start tag token (math) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 54 Unexpected start tag token (mi) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 62 Unexpected end tag (mi) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 66 Unexpected start tag token (mi) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 74 Unexpected end tag (mi) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 77 Unexpected start tag token (p) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 88 Unexpected table element end tag (tables) in the select in table phase.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <select>
|
|
||||||
| "foobarbaz"
|
|
||||||
| <p>
|
|
||||||
| "quux"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body><table><select><math><mi>foo</mi><mi>bar</mi><p>baz</table><p>quux
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 36 Unexpected start tag (select) in table context caused voodoo mode.
|
|
||||||
Line: 1 Col: 42 Unexpected start tag token (math) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 46 Unexpected start tag token (mi) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 54 Unexpected end tag (mi) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 58 Unexpected start tag token (mi) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 66 Unexpected end tag (mi) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 69 Unexpected start tag token (p) in the select phase. Ignored.
|
|
||||||
Line: 1 Col: 80 Unexpected table element end tag (tables) in the select in table phase.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| "foobarbaz"
|
|
||||||
| <table>
|
|
||||||
| <p>
|
|
||||||
| "quux"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body></body></html><math><mi>foo</mi><mi>bar</mi><p>baz
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 41 Unexpected start tag (math).
|
|
||||||
Line: 1 Col: 68 HTML start tag "p" in a foreign namespace context.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <p>
|
|
||||||
| "baz"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body></body><math><mi>foo</mi><mi>bar</mi><p>baz
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 34 Unexpected start tag token (math) in the after body phase.
|
|
||||||
Line: 1 Col: 61 HTML start tag "p" in a foreign namespace context.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| "foo"
|
|
||||||
| <math mi>
|
|
||||||
| "bar"
|
|
||||||
| <p>
|
|
||||||
| "baz"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><frameset><math><mi></mi><mi></mi><p><span>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 31 Unexpected start tag token (math) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 35 Unexpected start tag token (mi) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 40 Unexpected end tag token (mi) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 44 Unexpected start tag token (mi) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 49 Unexpected end tag token (mi) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 52 Unexpected start tag token (p) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 58 Unexpected start tag token (span) in the frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 58 Expected closing tag. Unexpected end of file.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><frameset></frameset><math><mi></mi><mi></mi><p><span>
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 42 Unexpected start tag (math) in the after frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 46 Unexpected start tag (mi) in the after frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 51 Unexpected end tag (mi) in the after frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 55 Unexpected start tag (mi) in the after frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 60 Unexpected end tag (mi) in the after frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 63 Unexpected start tag (p) in the after frameset phase. Ignored.
|
|
||||||
Line: 1 Col: 69 Unexpected start tag (span) in the after frameset phase. Ignored.
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body xlink:href=foo><math xlink:href=foo></math>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| xlink:href="foo"
|
|
||||||
| <math math>
|
|
||||||
| xlink href="foo"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo></mi></math>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| xlink:href="foo"
|
|
||||||
| xml:lang="en"
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| xlink href="foo"
|
|
||||||
| xml lang="en"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo /></math>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| xlink:href="foo"
|
|
||||||
| xml:lang="en"
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| xlink href="foo"
|
|
||||||
| xml lang="en"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!DOCTYPE html><body xlink:href=foo xml:lang=en><math><mi xml:lang=en xlink:href=foo />bar</math>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| xlink:href="foo"
|
|
||||||
| xml:lang="en"
|
|
||||||
| <math math>
|
|
||||||
| <math mi>
|
|
||||||
| xlink href="foo"
|
|
||||||
| xml lang="en"
|
|
||||||
| "bar"
|
|
|
@ -1,741 +0,0 @@
|
||||||
#data
|
|
||||||
<body><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
body
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><body>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
body
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><body>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
div
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<body><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
html
|
|
||||||
#document
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
body
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><frameset>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
body
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><frameset>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
div
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<frameset><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
html
|
|
||||||
#document
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><caption>a
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <caption>
|
|
||||||
| "a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><colgroup><col>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <colgroup>
|
|
||||||
| <col>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><tbody><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><tfoot><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tfoot>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><thead><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <thead>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><th>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <th>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table></table><tbody>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span></table>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</caption><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span></caption><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><caption><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><col><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><colgroup><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><html><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><tbody><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><td><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><tfoot><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><thead><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><th><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span><tr><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<span></table><span>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
caption
|
|
||||||
#document
|
|
||||||
| <span>
|
|
||||||
| <span>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</colgroup><col>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
colgroup
|
|
||||||
#document
|
|
||||||
| <col>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><col>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
colgroup
|
|
||||||
#document
|
|
||||||
| <col>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<caption><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<col><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<colgroup><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<tbody><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<tfoot><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<thead><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<td><table><tbody><a><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tbody
|
|
||||||
#document
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <a>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</tr><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<td><table><a><tr></tr><tr>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
| <a>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<caption><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<col><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<colgroup><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<tbody><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<tfoot><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<thead><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<tr><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<td><table></table><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
| <table>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<td><table></table><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
tr
|
|
||||||
#document
|
|
||||||
| <td>
|
|
||||||
| <table>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<caption><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<col><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<colgroup><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<tbody><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<tfoot><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<th><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<thead><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<tr><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</table><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</tbody><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</td><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</tfoot><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</thead><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</th><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</tr><a>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><td><td>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
td
|
|
||||||
#document
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</select><option>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
select
|
|
||||||
#document
|
|
||||||
| <option>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<input><option>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
select
|
|
||||||
#document
|
|
||||||
| <option>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<keygen><option>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
select
|
|
||||||
#document
|
|
||||||
| <option>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<textarea><option>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
select
|
|
||||||
#document
|
|
||||||
| <option>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</html><!--abc-->
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
html
|
|
||||||
#document
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <!-- abc -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
</frameset><frame>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
frameset
|
|
||||||
#document
|
|
||||||
| <frame>
|
|
||||||
|
|
||||||
#data
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
html
|
|
||||||
#document
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
|
@ -1,261 +0,0 @@
|
||||||
#data
|
|
||||||
<b><p>Bold </b> Not bold</p>
|
|
||||||
Also not bold.
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <b>
|
|
||||||
| <p>
|
|
||||||
| <b>
|
|
||||||
| "Bold "
|
|
||||||
| " Not bold"
|
|
||||||
| "
|
|
||||||
Also not bold."
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html>
|
|
||||||
<font color=red><i>Italic and Red<p>Italic and Red </font> Just italic.</p> Italic only.</i> Plain
|
|
||||||
<p>I should not be red. <font color=red>Red. <i>Italic and red.</p>
|
|
||||||
<p>Italic and red. </i> Red.</font> I should not be red.</p>
|
|
||||||
<b>Bold <i>Bold and italic</b> Only Italic </i> Plain
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| <i>
|
|
||||||
| "Italic and Red"
|
|
||||||
| <i>
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| "Italic and Red "
|
|
||||||
| " Just italic."
|
|
||||||
| " Italic only."
|
|
||||||
| " Plain
|
|
||||||
"
|
|
||||||
| <p>
|
|
||||||
| "I should not be red. "
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| "Red. "
|
|
||||||
| <i>
|
|
||||||
| "Italic and red."
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| <i>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| color="red"
|
|
||||||
| <i>
|
|
||||||
| "Italic and red. "
|
|
||||||
| " Red."
|
|
||||||
| " I should not be red."
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <b>
|
|
||||||
| "Bold "
|
|
||||||
| <i>
|
|
||||||
| "Bold and italic"
|
|
||||||
| <i>
|
|
||||||
| " Only Italic "
|
|
||||||
| " Plain"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body>
|
|
||||||
<p><font size="7">First paragraph.</p>
|
|
||||||
<p>Second paragraph.</p></font>
|
|
||||||
<b><p><i>Bold and Italic</b> Italic</p>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| size="7"
|
|
||||||
| "First paragraph."
|
|
||||||
| <font>
|
|
||||||
| size="7"
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <p>
|
|
||||||
| "Second paragraph."
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <b>
|
|
||||||
| <p>
|
|
||||||
| <b>
|
|
||||||
| <i>
|
|
||||||
| "Bold and Italic"
|
|
||||||
| <i>
|
|
||||||
| " Italic"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html>
|
|
||||||
<dl>
|
|
||||||
<dt><b>Boo
|
|
||||||
<dd>Goo?
|
|
||||||
</dl>
|
|
||||||
</html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <dl>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <dt>
|
|
||||||
| <b>
|
|
||||||
| "Boo
|
|
||||||
"
|
|
||||||
| <dd>
|
|
||||||
| <b>
|
|
||||||
| "Goo?
|
|
||||||
"
|
|
||||||
| <b>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body>
|
|
||||||
<label><a><div>Hello<div>World</div></a></label>
|
|
||||||
</body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <label>
|
|
||||||
| <a>
|
|
||||||
| <div>
|
|
||||||
| <a>
|
|
||||||
| "Hello"
|
|
||||||
| <div>
|
|
||||||
| "World"
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><center> <font>a</center> <img> <tr><td> </td> </tr> </table>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <center>
|
|
||||||
| " "
|
|
||||||
| <font>
|
|
||||||
| "a"
|
|
||||||
| <font>
|
|
||||||
| <img>
|
|
||||||
| " "
|
|
||||||
| <table>
|
|
||||||
| " "
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| " "
|
|
||||||
| " "
|
|
||||||
| " "
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><p><a><p>You should see this text.
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| <a>
|
|
||||||
| <p>
|
|
||||||
| <a>
|
|
||||||
| "You should see this text."
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<CENTER><CENTER><TD></TD></TR><TR>
|
|
||||||
<FONT>
|
|
||||||
<TABLE><tr></tr></TABLE>
|
|
||||||
</P>
|
|
||||||
<a></font><font></a>
|
|
||||||
This page contains an insanely badly-nested tag sequence.
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <center>
|
|
||||||
| <center>
|
|
||||||
| <font>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <table>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <td>
|
|
||||||
| <tr>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <font>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <p>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <a>
|
|
||||||
| <a>
|
|
||||||
| <font>
|
|
||||||
| <font>
|
|
||||||
| "
|
|
||||||
This page contains an insanely badly-nested tag sequence."
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
<b><nobr><div>This text is in a div inside a nobr</nobr>More text that should not be in the nobr, i.e., the
|
|
||||||
nobr should have closed the div inside it implicitly. </b><pre>A pre tag outside everything else.</pre>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| <div>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "This text is in a div inside a nobr"
|
|
||||||
| "More text that should not be in the nobr, i.e., the
|
|
||||||
nobr should have closed the div inside it implicitly. "
|
|
||||||
| <pre>
|
|
||||||
| "A pre tag outside everything else."
|
|
||||||
| "
|
|
||||||
|
|
||||||
"
|
|
|
@ -1,610 +0,0 @@
|
||||||
#data
|
|
||||||
Test
|
|
||||||
#errors
|
|
||||||
Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE.
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "Test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div></div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div>Test</div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| "Test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<di
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div>Hello</div>
|
|
||||||
<script>
|
|
||||||
console.log("PASS");
|
|
||||||
</script>
|
|
||||||
<div>Bye</div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| "Hello"
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <script>
|
|
||||||
| "
|
|
||||||
console.log("PASS");
|
|
||||||
"
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <div>
|
|
||||||
| "Bye"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div foo="bar">Hello</div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| foo="bar"
|
|
||||||
| "Hello"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div>Hello</div>
|
|
||||||
<script>
|
|
||||||
console.log("FOO<span>BAR</span>BAZ");
|
|
||||||
</script>
|
|
||||||
<div>Bye</div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| "Hello"
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <script>
|
|
||||||
| "
|
|
||||||
console.log("FOO<span>BAR</span>BAZ");
|
|
||||||
"
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <div>
|
|
||||||
| "Bye"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<foo bar="baz"></foo><potato quack="duck"></potato>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <foo>
|
|
||||||
| bar="baz"
|
|
||||||
| <potato>
|
|
||||||
| quack="duck"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<foo bar="baz"><potato quack="duck"></potato></foo>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <foo>
|
|
||||||
| bar="baz"
|
|
||||||
| <potato>
|
|
||||||
| quack="duck"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<foo></foo bar="baz"><potato></potato quack="duck">
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <foo>
|
|
||||||
| <potato>
|
|
||||||
|
|
||||||
#data
|
|
||||||
</ tttt>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!-- tttt -->
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div FOO ><img><img></div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| foo=""
|
|
||||||
| <img>
|
|
||||||
| <img>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p>Test</p<p>Test2</p>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| "TestTest2"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<rdar://problem/6869687>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <rdar:>
|
|
||||||
| 6869687=""
|
|
||||||
| problem=""
|
|
||||||
|
|
||||||
#data
|
|
||||||
<A>test< /A>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| "test< /A>"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "<"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<body foo='bar'><body foo='baz' yo='mama'>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| foo="bar"
|
|
||||||
| yo="mama"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<body></br foo="bar"></body>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <br>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<bdy><br foo="bar"></body>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <bdy>
|
|
||||||
| <br>
|
|
||||||
| foo="bar"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<body></body></br foo="bar">
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <br>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<bdy></body><br foo="bar">
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <bdy>
|
|
||||||
| <br>
|
|
||||||
| foo="bar"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body></body></html><!-- Hi there -->
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <!-- Hi there -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body></body></html>x<!-- Hi there -->
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
| <!-- Hi there -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body></body></html>x<!-- Hi there --></html><!-- Again -->
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
| <!-- Hi there -->
|
|
||||||
| <!-- Again -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body></body></html>x<!-- Hi there --></body></html><!-- Again -->
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "x"
|
|
||||||
| <!-- Hi there -->
|
|
||||||
| <!-- Again -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body><ruby><div><rp>xx</rp></div></ruby></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| <div>
|
|
||||||
| <rp>
|
|
||||||
| "xx"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body><ruby><div><rt>xx</rt></div></ruby></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ruby>
|
|
||||||
| <div>
|
|
||||||
| <rt>
|
|
||||||
| "xx"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><frameset><!--1--><noframes>A</noframes><!--2--></frameset><!--3--><noframes>B</noframes><!--4--></html><!--5--><noframes>C</noframes><!--6-->
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
| <!-- 1 -->
|
|
||||||
| <noframes>
|
|
||||||
| "A"
|
|
||||||
| <!-- 2 -->
|
|
||||||
| <!-- 3 -->
|
|
||||||
| <noframes>
|
|
||||||
| "B"
|
|
||||||
| <!-- 4 -->
|
|
||||||
| <noframes>
|
|
||||||
| "C"
|
|
||||||
| <!-- 5 -->
|
|
||||||
| <!-- 6 -->
|
|
||||||
|
|
||||||
#data
|
|
||||||
<select><option>A<select><option>B<select><option>C<select><option>D<select><option>E<select><option>F<select><option>G<select>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <select>
|
|
||||||
| <option>
|
|
||||||
| "A"
|
|
||||||
| <option>
|
|
||||||
| "B"
|
|
||||||
| <select>
|
|
||||||
| <option>
|
|
||||||
| "C"
|
|
||||||
| <option>
|
|
||||||
| "D"
|
|
||||||
| <select>
|
|
||||||
| <option>
|
|
||||||
| "E"
|
|
||||||
| <option>
|
|
||||||
| "F"
|
|
||||||
| <select>
|
|
||||||
| <option>
|
|
||||||
| "G"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<dd><dd><dt><dt><dd><li><li>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <dd>
|
|
||||||
| <dd>
|
|
||||||
| <dt>
|
|
||||||
| <dt>
|
|
||||||
| <dd>
|
|
||||||
| <li>
|
|
||||||
| <li>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div><b></div><div><nobr>a<nobr>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| <b>
|
|
||||||
| <div>
|
|
||||||
| <b>
|
|
||||||
| <nobr>
|
|
||||||
| "a"
|
|
||||||
| <nobr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<head></head>
|
|
||||||
<body></body>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| "
|
|
||||||
"
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<head></head> <style></style>ddd
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <style>
|
|
||||||
| " "
|
|
||||||
| <body>
|
|
||||||
| "ddd"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<kbd><table></kbd><col><select><tr>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <kbd>
|
|
||||||
| <select>
|
|
||||||
| <table>
|
|
||||||
| <colgroup>
|
|
||||||
| <col>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<kbd><table></kbd><col><select><tr></table><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <kbd>
|
|
||||||
| <select>
|
|
||||||
| <table>
|
|
||||||
| <colgroup>
|
|
||||||
| <col>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><li><style></style><title></title></a>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| <li>
|
|
||||||
| <a>
|
|
||||||
| <style>
|
|
||||||
| <title>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<font></p><p><meta><title></title></font>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <font>
|
|
||||||
| <p>
|
|
||||||
| <p>
|
|
||||||
| <font>
|
|
||||||
| <meta>
|
|
||||||
| <title>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<a><center><title></title><a>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <a>
|
|
||||||
| <center>
|
|
||||||
| <a>
|
|
||||||
| <title>
|
|
||||||
| <a>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><title><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg title>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><title><rect><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg title>
|
|
||||||
| <rect>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><title><svg><div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg title>
|
|
||||||
| <svg svg>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<img <="" FAIL>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <img>
|
|
||||||
| <=""
|
|
||||||
| fail=""
|
|
||||||
|
|
||||||
#data
|
|
||||||
<ul><li><div id='foo'/>A</li><li>B<div>C</div></li></ul>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <ul>
|
|
||||||
| <li>
|
|
||||||
| <div>
|
|
||||||
| id="foo"
|
|
||||||
| "A"
|
|
||||||
| <li>
|
|
||||||
| "B"
|
|
||||||
| <div>
|
|
||||||
| "C"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><em><desc></em>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <em>
|
|
||||||
| <desc>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><tr><td><svg><desc><td></desc><circle>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg desc>
|
|
||||||
| <td>
|
|
||||||
| <circle>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<svg><tfoot></mi><td>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <svg svg>
|
|
||||||
| <svg tfoot>
|
|
||||||
| <svg td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<math><mrow><mrow><mn>1</mn></mrow><mi>a</mi></mrow></math>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <math math>
|
|
||||||
| <math mrow>
|
|
||||||
| <math mrow>
|
|
||||||
| <math mn>
|
|
||||||
| "1"
|
|
||||||
| <math mi>
|
|
||||||
| "a"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><input type="hidden"><frameset>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <frameset>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<!doctype html><input type="button"><frameset>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <!DOCTYPE html>
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <input>
|
|
||||||
| type="button"
|
|
|
@ -1,159 +0,0 @@
|
||||||
#data
|
|
||||||
<foo bar=qux/>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <foo>
|
|
||||||
| bar="qux/"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<p id="status"><noscript><strong>A</strong></noscript><span>B</span></p>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <p>
|
|
||||||
| id="status"
|
|
||||||
| <noscript>
|
|
||||||
| "<strong>A</strong>"
|
|
||||||
| <span>
|
|
||||||
| "B"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<div><sarcasm><div></div></sarcasm></div>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <div>
|
|
||||||
| <sarcasm>
|
|
||||||
| <div>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<html><body><img src="" border="0" alt="><div>A</div></body></html>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><td></tbody>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| "A"
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><td></thead>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><td></tfoot>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <tbody>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><thead><td></tbody>A
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <table>
|
|
||||||
| <thead>
|
|
||||||
| <tr>
|
|
||||||
| <td>
|
|
||||||
| "A"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<legend>test</legend>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <legend>
|
|
||||||
| "test"
|
|
||||||
|
|
||||||
#data
|
|
||||||
<table><input>
|
|
||||||
#errors
|
|
||||||
#document
|
|
||||||
| <html>
|
|
||||||
| <head>
|
|
||||||
| <body>
|
|
||||||
| <input>
|
|
||||||
| <table>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<b><em><dcell><postfield><postfield><postfield><postfield><missing_glyph><missing_glyph><missing_glyph><missing_glyph><hkern><aside></b></em>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
div
|
|
||||||
#document
|
|
||||||
| <b>
|
|
||||||
| <em>
|
|
||||||
| <dcell>
|
|
||||||
| <postfield>
|
|
||||||
| <postfield>
|
|
||||||
| <postfield>
|
|
||||||
| <postfield>
|
|
||||||
| <missing_glyph>
|
|
||||||
| <missing_glyph>
|
|
||||||
| <missing_glyph>
|
|
||||||
| <missing_glyph>
|
|
||||||
| <hkern>
|
|
||||||
| <aside>
|
|
||||||
| <em>
|
|
||||||
| <b>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<isindex action="x">
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
table
|
|
||||||
#document
|
|
||||||
| <form>
|
|
||||||
| action="x"
|
|
||||||
| <hr>
|
|
||||||
| <label>
|
|
||||||
| "This is a searchable index. Enter search keywords: "
|
|
||||||
| <input>
|
|
||||||
| name="isindex"
|
|
||||||
| <hr>
|
|
||||||
|
|
||||||
#data
|
|
||||||
<option><XH<optgroup></optgroup>
|
|
||||||
#errors
|
|
||||||
#document-fragment
|
|
||||||
select
|
|
||||||
#document
|
|
||||||
| <option>
|
|
|
@ -1,748 +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"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
type tokenTest struct {
|
|
||||||
// A short description of the test case.
|
|
||||||
desc string
|
|
||||||
// The HTML to parse.
|
|
||||||
html string
|
|
||||||
// The string representations of the expected tokens, joined by '$'.
|
|
||||||
golden string
|
|
||||||
}
|
|
||||||
|
|
||||||
var tokenTests = []tokenTest{
|
|
||||||
{
|
|
||||||
"empty",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
// A single text node. The tokenizer should not break text nodes on whitespace,
|
|
||||||
// nor should it normalize whitespace within a text node.
|
|
||||||
{
|
|
||||||
"text",
|
|
||||||
"foo bar",
|
|
||||||
"foo bar",
|
|
||||||
},
|
|
||||||
// An entity.
|
|
||||||
{
|
|
||||||
"entity",
|
|
||||||
"one < two",
|
|
||||||
"one < two",
|
|
||||||
},
|
|
||||||
// A start, self-closing and end tag. The tokenizer does not care if the start
|
|
||||||
// and end tokens don't match; that is the job of the parser.
|
|
||||||
{
|
|
||||||
"tags",
|
|
||||||
"<a>b<c/>d</e>",
|
|
||||||
"<a>$b$<c/>$d$</e>",
|
|
||||||
},
|
|
||||||
// Angle brackets that aren't a tag.
|
|
||||||
{
|
|
||||||
"not a tag #0",
|
|
||||||
"<",
|
|
||||||
"<",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #1",
|
|
||||||
"</",
|
|
||||||
"</",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #2",
|
|
||||||
"</>",
|
|
||||||
"<!---->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #3",
|
|
||||||
"a</>b",
|
|
||||||
"a$<!---->$b",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #4",
|
|
||||||
"</ >",
|
|
||||||
"<!-- -->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #5",
|
|
||||||
"</.",
|
|
||||||
"<!--.-->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #6",
|
|
||||||
"</.>",
|
|
||||||
"<!--.-->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #7",
|
|
||||||
"a < b",
|
|
||||||
"a < b",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #8",
|
|
||||||
"<.>",
|
|
||||||
"<.>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #9",
|
|
||||||
"a<<<b>>>c",
|
|
||||||
"a<<$<b>$>>c",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #10",
|
|
||||||
"if x<0 and y < 0 then x*y>0",
|
|
||||||
"if x<0 and y < 0 then x*y>0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"not a tag #11",
|
|
||||||
"<<p>",
|
|
||||||
"<$<p>",
|
|
||||||
},
|
|
||||||
// EOF in a tag name.
|
|
||||||
{
|
|
||||||
"tag name eof #0",
|
|
||||||
"<a",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tag name eof #1",
|
|
||||||
"<a ",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tag name eof #2",
|
|
||||||
"a<b",
|
|
||||||
"a",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tag name eof #3",
|
|
||||||
"<a><b",
|
|
||||||
"<a>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tag name eof #4",
|
|
||||||
`<a x`,
|
|
||||||
``,
|
|
||||||
},
|
|
||||||
// Some malformed tags that are missing a '>'.
|
|
||||||
{
|
|
||||||
"malformed tag #0",
|
|
||||||
`<p</p>`,
|
|
||||||
`<p< p="">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #1",
|
|
||||||
`<p </p>`,
|
|
||||||
`<p <="" p="">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #2",
|
|
||||||
`<p id`,
|
|
||||||
``,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #3",
|
|
||||||
`<p id=`,
|
|
||||||
``,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #4",
|
|
||||||
`<p id=>`,
|
|
||||||
`<p id="">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #5",
|
|
||||||
`<p id=0`,
|
|
||||||
``,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #6",
|
|
||||||
`<p id=0</p>`,
|
|
||||||
`<p id="0</p">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #7",
|
|
||||||
`<p id="0</p>`,
|
|
||||||
``,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #8",
|
|
||||||
`<p id="0"</p>`,
|
|
||||||
`<p id="0" <="" p="">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"malformed tag #9",
|
|
||||||
`<p></p id`,
|
|
||||||
`<p>`,
|
|
||||||
},
|
|
||||||
// Raw text and RCDATA.
|
|
||||||
{
|
|
||||||
"basic raw text",
|
|
||||||
"<script><a></b></script>",
|
|
||||||
"<script>$<a></b>$</script>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"unfinished script end tag",
|
|
||||||
"<SCRIPT>a</SCR",
|
|
||||||
"<script>$a</SCR",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"broken script end tag",
|
|
||||||
"<SCRIPT>a</SCR ipt>",
|
|
||||||
"<script>$a</SCR ipt>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"EOF in script end tag",
|
|
||||||
"<SCRIPT>a</SCRipt",
|
|
||||||
"<script>$a</SCRipt",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"scriptx end tag",
|
|
||||||
"<SCRIPT>a</SCRiptx",
|
|
||||||
"<script>$a</SCRiptx",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"' ' completes script end tag",
|
|
||||||
"<SCRIPT>a</SCRipt ",
|
|
||||||
"<script>$a",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"'>' completes script end tag",
|
|
||||||
"<SCRIPT>a</SCRipt>",
|
|
||||||
"<script>$a$</script>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"self-closing script end tag",
|
|
||||||
"<SCRIPT>a</SCRipt/>",
|
|
||||||
"<script>$a$</script>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"nested script tag",
|
|
||||||
"<SCRIPT>a</SCRipt<script>",
|
|
||||||
"<script>$a</SCRipt<script>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"script end tag after unfinished",
|
|
||||||
"<SCRIPT>a</SCRipt</script>",
|
|
||||||
"<script>$a</SCRipt$</script>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"script/style mismatched tags",
|
|
||||||
"<script>a</style>",
|
|
||||||
"<script>$a</style>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"style element with entity",
|
|
||||||
"<style>'",
|
|
||||||
"<style>$&apos;",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"textarea with tag",
|
|
||||||
"<textarea><div></textarea>",
|
|
||||||
"<textarea>$<div>$</textarea>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title with tag and entity",
|
|
||||||
"<title><b>K&R C</b></title>",
|
|
||||||
"<title>$<b>K&R C</b>$</title>",
|
|
||||||
},
|
|
||||||
// DOCTYPE tests.
|
|
||||||
{
|
|
||||||
"Proper DOCTYPE",
|
|
||||||
"<!DOCTYPE html>",
|
|
||||||
"<!DOCTYPE html>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"DOCTYPE with no space",
|
|
||||||
"<!doctypehtml>",
|
|
||||||
"<!DOCTYPE html>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"DOCTYPE with two spaces",
|
|
||||||
"<!doctype html>",
|
|
||||||
"<!DOCTYPE html>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"looks like DOCTYPE but isn't",
|
|
||||||
"<!DOCUMENT html>",
|
|
||||||
"<!--DOCUMENT html-->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"DOCTYPE at EOF",
|
|
||||||
"<!DOCtype",
|
|
||||||
"<!DOCTYPE >",
|
|
||||||
},
|
|
||||||
// XML processing instructions.
|
|
||||||
{
|
|
||||||
"XML processing instruction",
|
|
||||||
"<?xml?>",
|
|
||||||
"<!--?xml?-->",
|
|
||||||
},
|
|
||||||
// Comments.
|
|
||||||
{
|
|
||||||
"comment0",
|
|
||||||
"abc<b><!-- skipme --></b>def",
|
|
||||||
"abc$<b>$<!-- skipme -->$</b>$def",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment1",
|
|
||||||
"a<!-->z",
|
|
||||||
"a$<!---->$z",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment2",
|
|
||||||
"a<!--->z",
|
|
||||||
"a$<!---->$z",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment3",
|
|
||||||
"a<!--x>-->z",
|
|
||||||
"a$<!--x>-->$z",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment4",
|
|
||||||
"a<!--x->-->z",
|
|
||||||
"a$<!--x->-->$z",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment5",
|
|
||||||
"a<!>z",
|
|
||||||
"a$<!---->$z",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment6",
|
|
||||||
"a<!->z",
|
|
||||||
"a$<!----->$z",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment7",
|
|
||||||
"a<!---<>z",
|
|
||||||
"a$<!---<>z-->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment8",
|
|
||||||
"a<!--z",
|
|
||||||
"a$<!--z-->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment9",
|
|
||||||
"a<!--z-",
|
|
||||||
"a$<!--z-->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment10",
|
|
||||||
"a<!--z--",
|
|
||||||
"a$<!--z-->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment11",
|
|
||||||
"a<!--z---",
|
|
||||||
"a$<!--z--->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment12",
|
|
||||||
"a<!--z----",
|
|
||||||
"a$<!--z---->",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment13",
|
|
||||||
"a<!--x--!>z",
|
|
||||||
"a$<!--x-->$z",
|
|
||||||
},
|
|
||||||
// An attribute with a backslash.
|
|
||||||
{
|
|
||||||
"backslash",
|
|
||||||
`<p id="a\"b">`,
|
|
||||||
`<p id="a\" b"="">`,
|
|
||||||
},
|
|
||||||
// Entities, tag name and attribute key lower-casing, and whitespace
|
|
||||||
// normalization within a tag.
|
|
||||||
{
|
|
||||||
"tricky",
|
|
||||||
"<p \t\n iD=\"a"B\" foo=\"bar\"><EM>te<&;xt</em></p>",
|
|
||||||
`<p id="a"B" foo="bar">$<em>$te<&;xt$</em>$</p>`,
|
|
||||||
},
|
|
||||||
// A nonexistent entity. Tokenizing and converting back to a string should
|
|
||||||
// escape the "&" to become "&".
|
|
||||||
{
|
|
||||||
"noSuchEntity",
|
|
||||||
`<a b="c&noSuchEntity;d"><&alsoDoesntExist;&`,
|
|
||||||
`<a b="c&noSuchEntity;d">$<&alsoDoesntExist;&`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"entity without semicolon",
|
|
||||||
`¬it;∉<a b="q=z&=5¬ice=hello¬=world">`,
|
|
||||||
`¬it;∉$<a b="q=z&amp=5&notice=hello¬=world">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"entity with digits",
|
|
||||||
"½",
|
|
||||||
"½",
|
|
||||||
},
|
|
||||||
// Attribute tests:
|
|
||||||
// http://dev.w3.org/html5/pf-summary/Overview.html#attributes
|
|
||||||
{
|
|
||||||
"Empty attribute",
|
|
||||||
`<input disabled FOO>`,
|
|
||||||
`<input disabled="" foo="">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Empty attribute, whitespace",
|
|
||||||
`<input disabled FOO >`,
|
|
||||||
`<input disabled="" foo="">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Unquoted attribute value",
|
|
||||||
`<input value=yes FOO=BAR>`,
|
|
||||||
`<input value="yes" foo="BAR">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Unquoted attribute value, spaces",
|
|
||||||
`<input value = yes FOO = BAR>`,
|
|
||||||
`<input value="yes" foo="BAR">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Unquoted attribute value, trailing space",
|
|
||||||
`<input value=yes FOO=BAR >`,
|
|
||||||
`<input value="yes" foo="BAR">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Single-quoted attribute value",
|
|
||||||
`<input value='yes' FOO='BAR'>`,
|
|
||||||
`<input value="yes" foo="BAR">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Single-quoted attribute value, trailing space",
|
|
||||||
`<input value='yes' FOO='BAR' >`,
|
|
||||||
`<input value="yes" foo="BAR">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Double-quoted attribute value",
|
|
||||||
`<input value="I'm an attribute" FOO="BAR">`,
|
|
||||||
`<input value="I'm an attribute" foo="BAR">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Attribute name characters",
|
|
||||||
`<meta http-equiv="content-type">`,
|
|
||||||
`<meta http-equiv="content-type">`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Mixed attributes",
|
|
||||||
`a<P V="0 1" w='2' X=3 y>z`,
|
|
||||||
`a$<p v="0 1" w="2" x="3" y="">$z`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Attributes with a solitary single quote",
|
|
||||||
`<p id=can't><p id=won't>`,
|
|
||||||
`<p id="can't">$<p id="won't">`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTokenizer(t *testing.T) {
|
|
||||||
loop:
|
|
||||||
for _, tt := range tokenTests {
|
|
||||||
z := NewTokenizer(strings.NewReader(tt.html))
|
|
||||||
if tt.golden != "" {
|
|
||||||
for i, s := range strings.Split(tt.golden, "$") {
|
|
||||||
if z.Next() == ErrorToken {
|
|
||||||
t.Errorf("%s token %d: want %q got error %v", tt.desc, i, s, z.Err())
|
|
||||||
continue loop
|
|
||||||
}
|
|
||||||
actual := z.Token().String()
|
|
||||||
if s != actual {
|
|
||||||
t.Errorf("%s token %d: want %q got %q", tt.desc, i, s, actual)
|
|
||||||
continue loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
z.Next()
|
|
||||||
if z.Err() != io.EOF {
|
|
||||||
t.Errorf("%s: want EOF got %q", tt.desc, z.Err())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMaxBuffer(t *testing.T) {
|
|
||||||
// Exceeding the maximum buffer size generates ErrBufferExceeded.
|
|
||||||
z := NewTokenizer(strings.NewReader("<" + strings.Repeat("t", 10)))
|
|
||||||
z.SetMaxBuf(5)
|
|
||||||
tt := z.Next()
|
|
||||||
if got, want := tt, ErrorToken; got != want {
|
|
||||||
t.Fatalf("token type: got: %v want: %v", got, want)
|
|
||||||
}
|
|
||||||
if got, want := z.Err(), ErrBufferExceeded; got != want {
|
|
||||||
t.Errorf("error type: got: %v want: %v", got, want)
|
|
||||||
}
|
|
||||||
if got, want := string(z.Raw()), "<tttt"; got != want {
|
|
||||||
t.Fatalf("buffered before overflow: got: %q want: %q", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMaxBufferReconstruction(t *testing.T) {
|
|
||||||
// Exceeding the maximum buffer size at any point while tokenizing permits
|
|
||||||
// reconstructing the original input.
|
|
||||||
tests:
|
|
||||||
for _, test := range tokenTests {
|
|
||||||
for maxBuf := 1; ; maxBuf++ {
|
|
||||||
r := strings.NewReader(test.html)
|
|
||||||
z := NewTokenizer(r)
|
|
||||||
z.SetMaxBuf(maxBuf)
|
|
||||||
var tokenized bytes.Buffer
|
|
||||||
for {
|
|
||||||
tt := z.Next()
|
|
||||||
tokenized.Write(z.Raw())
|
|
||||||
if tt == ErrorToken {
|
|
||||||
if err := z.Err(); err != io.EOF && err != ErrBufferExceeded {
|
|
||||||
t.Errorf("%s: unexpected error: %v", test.desc, err)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Anything tokenized along with untokenized input or data left in the reader.
|
|
||||||
assembled, err := ioutil.ReadAll(io.MultiReader(&tokenized, bytes.NewReader(z.Buffered()), r))
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%s: ReadAll: %v", test.desc, err)
|
|
||||||
continue tests
|
|
||||||
}
|
|
||||||
if got, want := string(assembled), test.html; got != want {
|
|
||||||
t.Errorf("%s: reassembled html:\n got: %q\nwant: %q", test.desc, got, want)
|
|
||||||
continue tests
|
|
||||||
}
|
|
||||||
// EOF indicates that we completed tokenization and hence found the max
|
|
||||||
// maxBuf that generates ErrBufferExceeded, so continue to the next test.
|
|
||||||
if z.Err() == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} // buffer sizes
|
|
||||||
} // tests
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPassthrough(t *testing.T) {
|
|
||||||
// Accumulating the raw output for each parse event should reconstruct the
|
|
||||||
// original input.
|
|
||||||
for _, test := range tokenTests {
|
|
||||||
z := NewTokenizer(strings.NewReader(test.html))
|
|
||||||
var parsed bytes.Buffer
|
|
||||||
for {
|
|
||||||
tt := z.Next()
|
|
||||||
parsed.Write(z.Raw())
|
|
||||||
if tt == ErrorToken {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if got, want := parsed.String(), test.html; got != want {
|
|
||||||
t.Errorf("%s: parsed output:\n got: %q\nwant: %q", test.desc, got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBufAPI(t *testing.T) {
|
|
||||||
s := "0<a>1</a>2<b>3<a>4<a>5</a>6</b>7</a>8<a/>9"
|
|
||||||
z := NewTokenizer(bytes.NewBufferString(s))
|
|
||||||
var result bytes.Buffer
|
|
||||||
depth := 0
|
|
||||||
loop:
|
|
||||||
for {
|
|
||||||
tt := z.Next()
|
|
||||||
switch tt {
|
|
||||||
case ErrorToken:
|
|
||||||
if z.Err() != io.EOF {
|
|
||||||
t.Error(z.Err())
|
|
||||||
}
|
|
||||||
break loop
|
|
||||||
case TextToken:
|
|
||||||
if depth > 0 {
|
|
||||||
result.Write(z.Text())
|
|
||||||
}
|
|
||||||
case StartTagToken, EndTagToken:
|
|
||||||
tn, _ := z.TagName()
|
|
||||||
if len(tn) == 1 && tn[0] == 'a' {
|
|
||||||
if tt == StartTagToken {
|
|
||||||
depth++
|
|
||||||
} else {
|
|
||||||
depth--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
u := "14567"
|
|
||||||
v := string(result.Bytes())
|
|
||||||
if u != v {
|
|
||||||
t.Errorf("TestBufAPI: want %q got %q", u, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConvertNewlines(t *testing.T) {
|
|
||||||
testCases := map[string]string{
|
|
||||||
"Mac\rDOS\r\nUnix\n": "Mac\nDOS\nUnix\n",
|
|
||||||
"Unix\nMac\rDOS\r\n": "Unix\nMac\nDOS\n",
|
|
||||||
"DOS\r\nDOS\r\nDOS\r\n": "DOS\nDOS\nDOS\n",
|
|
||||||
"": "",
|
|
||||||
"\n": "\n",
|
|
||||||
"\n\r": "\n\n",
|
|
||||||
"\r": "\n",
|
|
||||||
"\r\n": "\n",
|
|
||||||
"\r\n\n": "\n\n",
|
|
||||||
"\r\n\r": "\n\n",
|
|
||||||
"\r\n\r\n": "\n\n",
|
|
||||||
"\r\r": "\n\n",
|
|
||||||
"\r\r\n": "\n\n",
|
|
||||||
"\r\r\n\n": "\n\n\n",
|
|
||||||
"\r\r\r\n": "\n\n\n",
|
|
||||||
"\r \n": "\n \n",
|
|
||||||
"xyz": "xyz",
|
|
||||||
}
|
|
||||||
for in, want := range testCases {
|
|
||||||
if got := string(convertNewlines([]byte(in))); got != want {
|
|
||||||
t.Errorf("input %q: got %q, want %q", in, got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderEdgeCases(t *testing.T) {
|
|
||||||
const s = "<p>An io.Reader can return (0, nil) or (n, io.EOF).</p>"
|
|
||||||
testCases := []io.Reader{
|
|
||||||
&zeroOneByteReader{s: s},
|
|
||||||
&eofStringsReader{s: s},
|
|
||||||
&stuckReader{},
|
|
||||||
}
|
|
||||||
for i, tc := range testCases {
|
|
||||||
got := []TokenType{}
|
|
||||||
z := NewTokenizer(tc)
|
|
||||||
for {
|
|
||||||
tt := z.Next()
|
|
||||||
if tt == ErrorToken {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
got = append(got, tt)
|
|
||||||
}
|
|
||||||
if err := z.Err(); err != nil && err != io.EOF {
|
|
||||||
if err != io.ErrNoProgress {
|
|
||||||
t.Errorf("i=%d: %v", i, err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
want := []TokenType{
|
|
||||||
StartTagToken,
|
|
||||||
TextToken,
|
|
||||||
EndTagToken,
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
|
||||||
t.Errorf("i=%d: got %v, want %v", i, got, want)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// zeroOneByteReader is like a strings.Reader that alternates between
|
|
||||||
// returning 0 bytes and 1 byte at a time.
|
|
||||||
type zeroOneByteReader struct {
|
|
||||||
s string
|
|
||||||
n int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *zeroOneByteReader) Read(p []byte) (int, error) {
|
|
||||||
if len(p) == 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
if len(r.s) == 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
r.n++
|
|
||||||
if r.n%2 != 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
p[0], r.s = r.s[0], r.s[1:]
|
|
||||||
return 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// eofStringsReader is like a strings.Reader but can return an (n, err) where
|
|
||||||
// n > 0 && err != nil.
|
|
||||||
type eofStringsReader struct {
|
|
||||||
s string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *eofStringsReader) Read(p []byte) (int, error) {
|
|
||||||
n := copy(p, r.s)
|
|
||||||
r.s = r.s[n:]
|
|
||||||
if r.s != "" {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
return n, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
// stuckReader is an io.Reader that always returns no data and no error.
|
|
||||||
type stuckReader struct{}
|
|
||||||
|
|
||||||
func (*stuckReader) Read(p []byte) (int, error) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
rawLevel = iota
|
|
||||||
lowLevel
|
|
||||||
highLevel
|
|
||||||
)
|
|
||||||
|
|
||||||
func benchmarkTokenizer(b *testing.B, level int) {
|
|
||||||
buf, err := ioutil.ReadFile("testdata/go1.html")
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("could not read testdata/go1.html: %v", err)
|
|
||||||
}
|
|
||||||
b.SetBytes(int64(len(buf)))
|
|
||||||
runtime.GC()
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
z := NewTokenizer(bytes.NewBuffer(buf))
|
|
||||||
for {
|
|
||||||
tt := z.Next()
|
|
||||||
if tt == ErrorToken {
|
|
||||||
if err := z.Err(); err != nil && err != io.EOF {
|
|
||||||
b.Fatalf("tokenizer error: %v", err)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
switch level {
|
|
||||||
case rawLevel:
|
|
||||||
// Calling z.Raw just returns the raw bytes of the token. It does
|
|
||||||
// not unescape < to <, or lower-case tag names and attribute keys.
|
|
||||||
z.Raw()
|
|
||||||
case lowLevel:
|
|
||||||
// Caling z.Text, z.TagName and z.TagAttr returns []byte values
|
|
||||||
// whose contents may change on the next call to z.Next.
|
|
||||||
switch tt {
|
|
||||||
case TextToken, CommentToken, DoctypeToken:
|
|
||||||
z.Text()
|
|
||||||
case StartTagToken, SelfClosingTagToken:
|
|
||||||
_, more := z.TagName()
|
|
||||||
for more {
|
|
||||||
_, _, more = z.TagAttr()
|
|
||||||
}
|
|
||||||
case EndTagToken:
|
|
||||||
z.TagName()
|
|
||||||
}
|
|
||||||
case highLevel:
|
|
||||||
// Calling z.Token converts []byte values to strings whose validity
|
|
||||||
// extend beyond the next call to z.Next.
|
|
||||||
z.Token()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkRawLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, rawLevel) }
|
|
||||||
func BenchmarkLowLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, lowLevel) }
|
|
||||||
func BenchmarkHighLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, highLevel) }
|
|
|
@ -1,119 +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 httpguts
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isChar(c rune) bool { return c <= 127 }
|
|
||||||
|
|
||||||
func isCtl(c rune) bool { return c <= 31 || c == 127 }
|
|
||||||
|
|
||||||
func isSeparator(c rune) bool {
|
|
||||||
switch c {
|
|
||||||
case '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t':
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsToken(t *testing.T) {
|
|
||||||
for i := 0; i <= 130; i++ {
|
|
||||||
r := rune(i)
|
|
||||||
expected := isChar(r) && !isCtl(r) && !isSeparator(r)
|
|
||||||
if IsTokenRune(r) != expected {
|
|
||||||
t.Errorf("isToken(0x%x) = %v", r, !expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHeaderValuesContainsToken(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
vals []string
|
|
||||||
token string
|
|
||||||
want bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
vals: []string{"foo"},
|
|
||||||
token: "foo",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"bar", "foo"},
|
|
||||||
token: "foo",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"foo"},
|
|
||||||
token: "FOO",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"foo"},
|
|
||||||
token: "bar",
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{" foo "},
|
|
||||||
token: "FOO",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"foo,bar"},
|
|
||||||
token: "FOO",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"bar,foo,bar"},
|
|
||||||
token: "FOO",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"bar , foo"},
|
|
||||||
token: "FOO",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"foo ,bar "},
|
|
||||||
token: "FOO",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"bar, foo ,bar"},
|
|
||||||
token: "FOO",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vals: []string{"bar , foo"},
|
|
||||||
token: "FOO",
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
got := HeaderValuesContainsToken(tt.vals, tt.token)
|
|
||||||
if got != tt.want {
|
|
||||||
t.Errorf("headerValuesContainsToken(%q, %q) = %v; want %v", tt.vals, tt.token, got, tt.want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPunycodeHostPort(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
in, want string
|
|
||||||
}{
|
|
||||||
{"www.google.com", "www.google.com"},
|
|
||||||
{"гофер.рф", "xn--c1ae0ajs.xn--p1ai"},
|
|
||||||
{"bücher.de", "xn--bcher-kva.de"},
|
|
||||||
{"bücher.de:8080", "xn--bcher-kva.de:8080"},
|
|
||||||
{"[1::6]:8080", "[1::6]:8080"},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
got, err := PunycodeHostPort(tt.in)
|
|
||||||
if tt.want != got || err != nil {
|
|
||||||
t.Errorf("PunycodeHostPort(%q) = %q, %v, want %q, nil", tt.in, got, err, tt.want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue