Escaping `XmlNameProcessors` write a colon in XML names as-is, producing output that can not be read back

Đang mở Phù hợp với người mới
#923 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
85/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java
Lĩnh vực
backend

Hướng nghiên cứu

Xem Base64NameProcessor và ReplaceNameProcessor. Sửa đổi các mẫu regex VALID_XML_NAME và tập hợp ký tự được phép để loại trừ dấu hai chấm, để các tên như a:b được thoát hoặc thay thế. Cập nhật phương thức encodeName() cho phù hợp. Thêm các kiểm tra khứ hồi để xác minh rằng các tên chứa dấu hai chấm được tuần tự hóa thành XML hợp lệ và giải tuần tự hóa mà không có StreamReadException.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug

Both escaping processors from XmlNameProcessors treat a colon as a valid XML name character, so a name that contains one is written out verbatim:

  • Base64NameProcessor.VALID_XML_NAME is [a-zA-Z_:]([a-zA-Z0-9_:.-])*, i.e. a name holding a colon counts as already valid and is not escaped
  • ReplaceNameProcessor keeps : in both of its allowed sets (^[^a-zA-Z_:], [^a-zA-Z0-9_:-])

Output is namespace-aware, though, so the colon comes back as a prefix that nothing declares and the document can no longer be read by this module:

<DTO><badMap><a:b>xyz</a:b></badMap></DTO>
tools.jackson.core.exc.StreamReadException:
Undeclared namespace prefix "a"
 at [row,col {unknown-source}]: [1,18]
 at [Source: (String)"<DTO><badMap><a:b>xyz</a:b></badMap></DTO>"; line: 1, column: 19]
Caused by: com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "a"

Keys like a:b:c or :leading are not even well-formed, so they fail in the Stax reader before namespace resolution.

The javadoc of both processors lists the colon as "only exposed if underlying parser is in non-namespace-aware mode", but encoding has no knowledge of which parser will read the result back, and newAlwaysOnBase64Processor() already handles the same keys cleanly. Round-tripping names that are not valid XML names is what these two processors exist for, so the colon looks like an oversight in the allowed sets rather than a deliberate exception.

Version information

3.3.0-SNAPSHOT (3.x). The allowed sets have looked this way since the mechanism was added (#531), so 3.0/3.1/3.2 and 2.x behave the same.

Reproduction
public static class DTO {
    public Map<String, String> badMap = new HashMap<>();
}

private XmlFactory xmlFactory(XmlNameProcessor nameProcessor) {
    return XmlFactory.builder().xmlNameProcessor(nameProcessor).build();
}

@Test
public void colonInNameRoundTrips() throws Exception {
    XmlMapper mapper = XmlMapper.builder(
            xmlFactory(XmlNameProcessors.newBase64Processor())).build();

    DTO dto = new DTO();
    dto.badMap.put("a:b", "xyz");

    String xml = mapper.writeValueAsString(dto);
    // writes <DTO><badMap><a:b>xyz</a:b></badMap></DTO>
    mapper.readValue(xml, DTO.class); // StreamReadException: Undeclared namespace prefix "a"
}

Same for newReplacementProcessor(), which writes <a:b> rather than replacing the colon. newAlwaysOnBase64Processor() is fine, since it escapes every name.

Expected behavior

A name containing a colon should be escaped (base64, still a lossless round trip) or replaced, like any other character that cannot appear in a written XML name, so that what these processors write can be read back.

Only encodeName() would need to change: decodeName() keys off the prefix for base64 and is a no-op for replacement, so names read from a non-namespace-aware parser are still passed through untouched.

Additional context

PR #921 has the fix plus round-trip tests. Targeted at 3.x since it changes what gets written for these names.

Ngôn ngữ chính
Java
Star
636
Fork
250
Merge trung bình
7 giờ 10 phút
Pull request đã merge (30 ngày)
8

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của FasterXML/jackson-dataformat-xml

Tất cả issue của FasterXML/jackson-dataformat-xml

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.