代码之家  ›  专栏  ›  技术社区  ›  Jerry An

如何触发html。Golang中的分析错误

  •  0
  • Jerry An  · 技术社区  · 4 年前

    我正在编写一个Go函数来读取HTML响应体并提取页面标题。总的来说,该函数运行得很好,但我想测试响应体根本不是正确HTML的代码路径。我为单元测试创建一些无效HTML的简单尝试都失败了。

    显然,根据 html.Parse documentation ,这是因为:

    HTML5解析算法[]非常复杂。结果树可以包含隐式创建的节点,这些节点没有显式 <tag> 列在r的数据中,节点的父节点可能不同于初始处理开始和结束所暗示的嵌套 <标签> s.相反,显式 <标签> r的数据中的s可以被静默地丢弃,而在生成的树中没有相应的节点。

    以下是一些代码,演示了我一直采用的方法:

    https://play.golang.org/p/T5WjdtjNcqq

    package main
    
    import (
        "bytes"
        "fmt"
        "golang.org/x/net/html"
    )
    
    func main() {
        inputs := []string{ "",
            "~",
            "<",
            "<ht",
            "<html",
            "<html>",
            "<html><",
            "<html><titl",
            "<html><title",
            "<html><title>",
            "<html><title>The C Progr",
            "<html><title>The C Programming Language",
            "<html><title>The C Programming Language<",
            "<html><title>The C Programming Language</",
            "<html><title>The C Programming Language</ti",
            "<html><title>The C Programming Language</title",
            "<html><title>The C Programming Language</title>",
            "<html><title>The C Programming Language</title><",
            "<html><title>The C Programming Language</title></",
            "<html><title>The C Programming Language</title></ht",
            "<html><title>The C Programming Language</title></html",
            "<html><title>The C Programming Language</title></html>",
        }
    
        for _, in := range inputs {
            fmt.Printf("%s\n", in)
    
            r := bytes.NewReader([]byte(in))
            _, err := html.Parse(r)
            if err != nil {
                fmt.Printf("COULD NOT PARSE HTML\n")
                panic(err)
            }
        }
    }
    

    我真傻,我本以为其中许多都会产生错误,因为从表面上看,它们是无效的HTML,但上面的代码在所有输入字符串中都没有 panic ing——也就是说,没有非- nil err 从…起 html.Parse()

    我想我很感激一个宽容/宽容的HTML解析器,但是:有人有一个文本示例在输入Go时会产生错误吗 html。解析() ?

    编辑1

    结合Ferrybig和CreationTribe的评论,我甚至尝试了一个巨大的随机字节流:

        rand.Seed(time.Now().UnixNano())
    
        in := make([]byte, 0)
        for i := 0; i < 2147483647; i++ {
            in = append(in, byte(rand.Intn(255)))
        }
        fmt.Printf("len(in) : %d\n", len(in))
    
        r := bytes.NewReader(in)
        _, err := html.Parse(r)
    

    它仍然没有出错。

    是否没有将导致 html。解析() 出错?

    0 回复  |  直到 6 年前
        1
  •  3
  •   icio    6 年前

    快速阅读 https://github.com/golang/net/blob/master/html/token.go ,似乎唯一返回的错误可能是:

    • io.EOF一旦r被完全读取成功;
    • 底层io.Reader返回的任何其他错误;或
    • html。ErrBufferExceeded

    在初次阅读如何触发ErrBufferExceeded后,我并不清楚,但您可以从html中触发错误。通过提供一个伪读取器进行分析:

    type ErrReader struct { Error error }
    
    func (e *ErrReader) Read([]byte) (int, error) {
        return nil, e.Error
    }
    

    https://play.golang.org/p/s78HpfMLAI8

    希望能有所帮助