Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
xmloxide — 순수 Rust로 작성된 libxml2 재구현 | Kitploit
도구/GitHubGitHub/jonwiggins/xmloxide
Static AnalysisVulnerability AnalysisCode AnalysisFuzzingBinary AnalysisLearning & EducationCurated ResourcesLabs & Practice
GitHubjonwiggins/xmloxide

xmloxide

순수 Rust로 작성된 libxml2 재구현

저장소 보기
84831개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

xmloxide

CI crates.io docs.rs License: MIT MSRV

libxml2의 순수 Rust 재구현 — 오픈 소스 세계에서 사실상 표준인 XML/HTML 파싱 라이브러리입니다.

libxml2는 2025년 12월에 알려진 보안 문제로 인해 공식적으로 유지보수가 중단되었습니다. xmloxide는 동일한 적합성 테스트 스위트를 통과하는 메모리 안전하고 고성능인 대체제를 목표로 합니다.

Features

  • 메모리 안전 — 공개 API에 unsafe가 전혀 없는 아레나 기반 트리
  • 규격 준수 — W3C XML 적합성 테스트 스위트 100% 통과 (1727/1727 해당 테스트)
  • 오류 복구 — libxml2처럼 잘못된 XML도 파싱하여 사용 가능한 트리 생성
  • 다중 파싱 API — DOM 트리, SAX2 스트리밍, XmlReader 풀, 푸시/증분
  • HTML 파서 — 자동 닫힘 및 void 요소를 지원하는 오류 허용 HTML 4.01 파싱
  • — 전체 토크나이저 및 트리 빌더 (8810/8810 html5lib-tests 통과)
WHATWG HTML5 파서
HTML Living Standard
  • HTML5 스트리밍 — DOM 트리를 구축하지 않고 토크나이저를 감싸는 HTML5용 SAX 유사 콜백 API (html5::sax)
  • CSS 선택자 — 친숙한 CSS 구문(css::select)으로 요소 쿼리, 결합자, 의사 클래스 및 빠른 #id 조회 포함
  • XPath 1.0+ — 모든 XPath 1.0 핵심 함수와 주요 XPath 2.0 함수(matches(), replace(), tokenize(), upper-case(), lower-case(), abs(), min(), max() 등)를 포함한 완전한 표현식 파서 및 평가기
  • 검증 — DTD, RelaxNG, XML Schema (XSD), ISO Schematron (ISO/IEC 19757-3) 검증
  • Serde 통합 — Rust 타입과 XML (역)직렬화를 위한 선택적 serde 기능
  • 비동기 파싱 — tokio::io::AsyncRead 소스에서 파싱을 위한 선택적 async 기능
  • 정식 XML — C14N 1.0 및 Exclusive C14N 직렬화
  • XInclude — 문서 포함 처리
  • XML 카탈로그 — URI 해석을 위한 OASIS XML 카탈로그
  • xmllint CLI — XML 파싱, 검증 및 쿼리를 위한 명령줄 도구
  • 가능한 Zero-copy — 빠른 비교를 위한 문자열 인터닝
  • 전역 상태 없음 — 각 Document는 독립적이며 Send + Sync
  • C/C++ FFI — C/C++ 프로젝트에 포함하기 위한 전체 C API 및 헤더 파일 (include/xmloxide.h)
  • 최소 의존성 — encoding_rs만 사용 (라이브러리에는 다른 의존성이 없으며, clap은 CLI 전용)
  • Quick Start

    root@kitploit:~
    use xmloxide::Document;
    
    let doc = Document::parse_str("<root><child>Hello</child></root>").unwrap();
    let root = doc.root_element().unwrap();
    assert_eq!(doc.node_name(root), Some("root"));
    assert_eq!(doc.text_content(root), "Hello");
    

    Serialization

    root@kitploit:~
    use xmloxide::Document;
    use xmloxide::serial::serialize;
    
    let doc = Document::parse_str("<root><child>Hello</child></root>").unwrap();
    let xml = serialize(&doc);
    assert_eq!(xml, "<root><child>Hello</child></root>");
    

    XPath Queries

    root@kitploit:~
    use xmloxide::Document;
    use xmloxide::xpath::{evaluate, XPathValue};
    
    let doc = Document::parse_str("<library><book><title>Rust</title></book></library>").unwrap();
    let root = doc.root_element().unwrap();
    let result = evaluate(&doc, root, "count(book)").unwrap();
    assert_eq!(result.to_number(), 1.0);
    

    SAX2 Streaming

    root@kitploit:~
    use xmloxide::sax::{parse_sax, SaxHandler, DefaultHandler};
    use xmloxide::parser::ParseOptions;
    
    struct MyHandler;
    impl SaxHandler for MyHandler {
        fn start_element(&mut self, name: &str, _: Option<&str>, _: Option<&str>,
                         _: &[(String, String, Option<String>, Option<String>)]) {
            println!("Element: {name}");
        }
    }
    
    parse_sax("<root><child/></root>", &ParseOptions::default(), &mut MyHandler).unwrap();
    

    HTML Parsing

    root@kitploit:~
    use xmloxide::html::parse_html;
    
    let doc = parse_html("<p>Hello <br> World").unwrap();
    let root = doc.root_element().unwrap();
    assert_eq!(doc.node_name(root), Some("html"));
    

    CSS Selectors

    root@kitploit:~
    use xmloxide::css::select;
    use xmloxide::Document;
    
    let doc = Document::parse_str(r#"<div><p class="intro">Hello</p><p>World</p></div>"#).unwrap();
    let root = doc.root_element().unwrap();
    let intros = select(&doc, root, "p.intro").unwrap();
    assert_eq!(intros.len(), 1);
    assert_eq!(doc.text_content(intros[0]), "Hello");
    

    HTML5 Parsing (WHATWG)

    root@kitploit:~
    use xmloxide::html5::parse_html5;
    
    let doc = parse_html5("<p>Hello <b>world</b>").unwrap();
    let root = doc.root_element().unwrap();
    assert_eq!(doc.node_name(root), Some("html"));
    

    Fragment parsing (the algorithm behind innerHTML) is also supported:

    root@kitploit:~
    use xmloxide::html5::{parse_html5_with_options, Html5ParseOptions};
    
    let opts = Html5ParseOptions {
        scripting: false,
        fragment_context: Some("body".to_string()),
    };
    let doc = parse_html5_with_options("<p>fragment</p>", &opts).unwrap();
    

    HTML5 Streaming (SAX-like)

    root@kitploit:~
    use xmloxide::html5::sax::{Html5SaxHandler, parse_html5_sax};
    
    struct LinkExtractor { hrefs: Vec<String> }
    impl Html5SaxHandler for LinkExtractor {
        fn start_element(&mut self, name: &str, attrs: &[(String, String)], _sc: bool) {
            if name == "a" {
                if let Some((_, href)) = attrs.iter().find(|(n, _)| n == "href") {
                    self.hrefs.push(href.clone());
                }
            }
        }
    }
    
    let mut handler = LinkExtractor { hrefs: Vec::new() };
    parse_html5_sax(r#"<a href="https://github.com/jonwiggins/xmloxide/blob/main/page">Link</a>"#, &mut handler);
    assert_eq!(handler.hrefs, vec!["/page"]);
    

    Error Recovery

    root@kitploit:~
    use xmloxide::parser::{parse_str_with_options, ParseOptions};
    
    let opts = ParseOptions::default().recover(true);
    let doc = parse_str_with_options("<root><unclosed>", &opts).unwrap();
    for diag in &doc.diagnostics {
        eprintln!("{}", diag);
    }
    

    CLI Tool

    root@kitploit:~
    # Parse and pretty-print
    xmllint --format document.xml
    
    # Validate against a schema
    xmllint --schema schema.xsd document.xml
    xmllint --relaxng schema.rng document.xml
    xmllint --schematron schema.sch document.xml
    xmllint --dtdvalid schema.dtd document.xml
    
    # XPath query
    xmllint --xpath "//title" document.xml
    
    # Canonical XML
    xmllint --c14n document.xml
    
    # Parse HTML
    xmllint --html page.html
    

    Module Overview

    ModuleDescription
    tree아레나 기반 DOM 트리 (Document, NodeId, NodeKind)
    parser오류 복구를 지원하는 XML 1.0 재귀 하향 파서
    parser::push청크 입력을 위한 푸시/증분 파서
    html오류 허용 HTML 4.01 파서
    html5WHATWG HTML Living Standard 파서 (토크나이저 + 트리 빌더)
    html5::saxHTML5용 스트리밍 SAX 유사 API (DOM 트리 구축 없음)
    css문서 트리 쿼리를 위한 CSS 선택자 엔진
    saxSAX2 스트리밍 이벤트 기반 파서
    readerXmlReader 풀 기반 파싱 API
    serialXML, HTML 및 HTML5 직렬화기, Canonical XML (C14N) 포함
    xpathXPath 1.0+ 표현식 파서 및 평가기
    validation::dtdDTD 파싱 및 검증
    validation::relaxngRelaxNG 스키마 검증
    validation::xsdXML Schema (XSD) 검증
    validation::schematronISO Schematron 규칙 기반 검증
    serde_xmlSerde XML (역)직렬화 (선택적 serde 기능)
    async_xmltokio::io::AsyncRead를 통한 비동기 파싱 (선택적 async 기능)
    xincludeXInclude 1.0 문서 포함
    catalogURI 해석을 위한 OASIS XML 카탈로그
    encoding문자 인코딩 감지 및 트랜스코딩
    ffiC/C++ FFI 바인딩 (include/xmloxide.h)

    Performance

    파싱 처리량은 libxml2와 경쟁력이 있습니다 — 대부분의 문서에서 3-4% 이내, SVG의 경우 12% 더 빠릅니다. 직렬화는 아레나 기반 트리 설계 덕분에 1.5-2.4배 더 빠릅니다. XPath는 모든 벤치마크에서 1.1-2.7배 더 빠릅니다.

    Parsing:

    DocumentSizexmloxidelibxml2Result
    Atom 피드4.9 KB26.7 µs (176 MiB/s)25.5 µs (184 MiB/s)약 4% 느림
    SVG 도면6.3 KB58.5 µs (103 MiB/s)65.6 µs (92 MiB/s)12% 더 빠름
    Maven POM11.5 KB76.9 µs (142 MiB/s)74.2 µs (148 MiB/s)약 4% 느림
    XHTML 페이지10.2 KB69.5 µs (139 MiB/s)61.5 µs (157 MiB/s)약 13% 느림
    대용량 (374 KB)374 KB2.15 ms (169 MiB/s)2.08 ms (175 MiB/s)약 3% 느림

    Serialization:

    DocumentSizexmloxidelibxml2Result
    Atom 피드4.9 KB11.3 µs17.5 µs1.5배 더 빠름
    Maven POM11.5 KB20.1 µs47.5 µs2.4배 더 빠름
    대용량 (374 KB)374 KB614 µs1397 µs2.3배 더 빠름

    XPath:

    표현식xmloxidelibxml2Result
    단순 경로 (//entry/title)1.51 µs1.63 µs8% 더 빠름
    속성 조건 (//book[@id])5.91 µs15.99 µs2.7배 더 빠름
    count() 함수1.09 µs1.67 µs1.5배 더 빠름
    string() 함수1.32 µs1.77 µs1.3배 더 빠름

    주요 최적화: 빠른 직렬화를 위한 아레나 기반 트리, 문자 검증을 위한 바이트 수준 사전 검사, 대량 텍스트 스캔, 이름 파싱을 위한 ASCII 고속 경로, 제로 카피 요소 이름 분할, 인라인 엔터티 해석, XPath // 단계 융합 및 융합 축 확장, 인라인 트리 접근자, 자식/하위 축에 대한 이름 테스트 고속 경로.

    root@kitploit:~
    # Run benchmarks (requires libxml2 system library)
    cargo bench --features bench-libxml2 --bench comparison_bench
    

    Testing

    • 1078개의 단위 테스트 — 모든 모듈
    • 138개의 FFI 테스트 — 전체 C API 표면 (SAX, Schematron 및 CSS 포함)
    • libxml2 호환성 테스트 스위트 — 119/119 테스트 통과 (100%) — XML 파싱, 네임스페이스, 오류 감지 및 HTML 파싱 포함
    • W3C XML 적합성 테스트 스위트 — 1727/1727 해당 테스트 통과 (100%)
    • html5lib-tests — 7032/7032 토크나이저 테스트 + 1778/1778 트리 구성 테스트 (100%)
    • 통합 테스트 — 실제 XML/HTML 문서, 엣지 케이스 및 오류 복구 포함
    root@kitploit:~
    cargo test --all-features
    

    C/C++ FFI

    xmloxide는 C/C++ 프로젝트(예: Chromium, 게임 엔진 또는 현재 libxml2를 사용하는 모든 코드베이스)에 포함할 수 있는 C 호환 API를 제공합니다.

    root@kitploit:~
    # Build shared + static libraries (uses the included Makefile)
    make
    
    # Or build individually:
    make shared   # .so / .dylib / .dll
    make static   # .a / .lib
    
    # Build and run the C example
    make example
    
    root@kitploit:~
    #include "xmloxide.h"
    
    xmloxide_document *doc = xmloxide_parse_str("<root>Hello</root>");
    uint32_t root = xmloxide_doc_root_element(doc);
    char *name = xmloxide_node_name(doc, root);   // "root"
    char *text = xmloxide_node_text_content(doc, root); // "Hello"
    
    xmloxide_free_string(name);
    xmloxide_free_string(text);
    xmloxide_free_doc(doc);
    

    전체 API(트리 탐색 및 변형, XPath 평가, 직렬화(일반 및 정리 인쇄), HTML/HTML5 파싱, DTD/RelaxNG/XSD/Schematron 검증, C14N, SAX 스트리밍, XmlReader, 푸시 파서 및 XML 카탈로그 포함)는 include/xmloxide.h에 선언되어 있습니다.

    Migrating from libxml2

    libxml2xmloxide (Rust)xmloxide (C FFI)
    xmlReadMemoryDocument::parse_strxmloxide_parse_str
    xmlReadFileDocument::parse_filexmloxide_parse_file
    xmlParseDocDocument::parse_bytesxmloxide_parse_bytes
    htmlReadMemoryhtml::parse_htmlxmloxide_parse_html
    (HTML5 parsing)html5::parse_html5—
    (HTML5 fragment / innerHTML)html5::parse_html5_with_options—
    (HTML5 streaming)html5::sax::parse_html5_sax—
    (CSS selectors / querySelector)css::select—
    xmlFreeDoc(drop Document)xmloxide_free_doc
    xmlDocGetRootElementdoc.root_element()xmloxide_doc_root_element
    xmlNodeGetContentdoc.text_content(id)xmloxide_node_text_content
    xmlNodeSetContentdoc.set_text_content(id, s)xmloxide_set_text_content
    xmlGetPropdoc.attribute(id, name)xmloxide_node_attribute
    xmlSetPropdoc.set_attribute(...)xmloxide_set_attribute
    xmlNewNodedoc.create_node(...)

    Thread safety: Unlike libxml2, xmloxide has no global state. Each Document is self-contained and Send + Sync. The FFI layer uses thread-local storage for the last error message — each thread has its own error state. No initialization or cleanup functions are needed.

    스레드 안전성: libxml2와 달리 xmloxide에는 전역 상태가 없습니다. 각 Document는 독립적이며 Send + Sync입니다. FFI 계층은 마지막 오류 메시지에 대해 스레드 로컬 저장소를 사용합니다. 각 스레드는 자체 오류 상태를 가집니다. 초기화 또는 정리 함수가 필요하지 않습니다.

    Fuzzing

    xmloxide includes fuzz targets for security testing:

    root@kitploit:~
    # Install cargo-fuzz (requires nightly)
    cargo install cargo-fuzz
    
    # Run a fuzz target
    cargo +nightly fuzz run fuzz_xml_parse
    cargo +nightly fuzz run fuzz_html_parse
    cargo +nightly fuzz run fuzz_html5_parse
    cargo +nightly fuzz run fuzz_html5_fragment
    cargo +nightly fuzz run fuzz_xpath
    cargo +nightly fuzz run fuzz_roundtrip
    cargo +nightly fuzz run fuzz_sax
    cargo +nightly fuzz run fuzz_reader
    cargo +nightly fuzz run fuzz_push
    cargo +nightly fuzz run fuzz_validation
    cargo +nightly fuzz run fuzz_schematron
    

    xmloxide는 보안 테스트를 위한 퍼징 타겟을 포함합니다.

    Building

    root@kitploit:~
    cargo build
    cargo test
    cargo clippy --all-targets --all-features -- -D warnings
    cargo bench
    

    Minimum supported Rust version: 1.81

    최소 지원 Rust 버전: 1.81

    Limitations

    • XML 1.1 미지원 — xmloxide는 XML 1.0(5판)만 구현합니다. XML 1.1은 거의 사용되지 않으며 계획에 없습니다.
    • XSLT 미지원 — XSLT는 별도 사양(libxslt)으로 범위를 벗어납니다.
    • HTML 파서 — HTML 4.01 파서(libxml2의 동작과 일치)와 전체 WHATWG HTML5 파서가 모두 제공됩니다. HTML5 파서는 html5lib-tests를 100% 통과합니다.
    • 푸시 파서는 내부적으로 버퍼링 — 푸시/증분 파서 API(PushParser)는 현재 모든 푸시된 데이터를 버퍼링하고 finish()에서 전체 파싱을 수행합니다. libxml2의 xmlParseChunk처럼 진정한 스트리밍 방식이 아닙니다. 대용량 문서 처리를 위한 메모리 제약이 있는 경우 SAX 스트리밍(XML용 parse_sax, HTML5용 html5::sax::parse_html5_sax)을 대안으로 사용할 수 있습니다.
    • XPath namespace:: 축 — namespace:: 축은 범위 내 네임스페이스가 일치할 때 요소 노드를 반환합니다(별도의 네임스페이스 노드를 구체화하지 않음). 이는 속성 축과 동일한 패턴을 따릅니다.

    Contributing

    기여에 대해서는 CONTRIBUTING.md를 참조하세요.

    Changelog

    버전 기록은 CHANGELOG.md를 참조하세요.

    License

    MIT

    도구 다운로드
    xmloxide_create_element
    xmlNewTextdoc.create_node(Text{..})xmloxide_create_text
    xmlAddChilddoc.append_child(p, c)xmloxide_append_child
    xmlAddPrevSiblingdoc.insert_before(ref, c)xmloxide_insert_before
    xmlUnlinkNodedoc.remove_node(id)xmloxide_remove_node
    xmlCopyNodedoc.clone_node(id, deep)xmloxide_clone_node
    xmlGetIDdoc.element_by_id(s)xmloxide_element_by_id
    xmlDocDumpMemoryserial::serialize(&doc)xmloxide_serialize
    xmlDocDumpFormatMemoryserial::serialize_with_optionsxmloxide_serialize_pretty
    htmlDocDumpMemoryserial::html::serialize_htmlxmloxide_serialize_html
    xmlC14NDocDumpMemoryserial::c14n::canonicalizexmloxide_canonicalize
    xmlXPathEvalExpressionxpath::evaluatexmloxide_xpath_eval
    xmlValidateDtdvalidation::dtd::validatexmloxide_validate_dtd
    xmlRelaxNGValidateDocvalidation::relaxng::validatexmloxide_validate_relaxng
    xmlSchemaValidateDocvalidation::xsd::validate_xsdxmloxide_validate_xsd
    (Schematron validation)validation::schematron::validate_schematronxmloxide_validate_schematron
    xmlXIncludeProcessxinclude::process_xincludesxmloxide_process_xincludes
    xmlLoadCatalogCatalog::parsexmloxide_parse_catalog
    xmlSAX2... callbackssax::SaxHandler traitxmloxide_sax_parse
    xmlTextReaderReadreader::XmlReaderxmloxide_reader_read
    xmlCreatePushParserCtxtparser::PushParserxmloxide_push_parser_new
    xmlParseChunkPushParser::pushxmloxide_push_parser_push