mirror of
https://github.com/storytold/winprint.rs.git
synced 2026-11-15 06:44:28 +00:00
fix(ticket): write QName values as prefix:local
PropertyValue::QName was written with OwnedName's Display, which puts
the namespace URI in front ("{uri}psk:LongEdgeFirst"). That is not a
valid QName, so PTMergeAndValidatePrintTicket rejects any delta ticket
carrying a QName value copied from a driver's PrintCapabilities with
0x80040005 (E_DELTA_PRINTTICKET_FORMAT). The Microsoft IPP Class
Driver lists Letter, A4 and Executive with such a property, so
printing those sizes fails (storytold/pdfcraft#3823).
Write the value as prefix:local, and declare the value's prefix on the
root so a namespace used only in a value stays bound.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d1dc3c2089
commit
cbffb07d78
1 file changed
+29
-1
@@ -256,6 +256,9 @@ impl XmlSerializer for super::PropertyValue {
|
||||
ns.put("psf", NS_PSF);
|
||||
ns.put("xsi", NS_XSI);
|
||||
collect_namespace_from_name(&self.xsi_type(), ns);
|
||||
if let super::PropertyValue::QName(q) = self {
|
||||
collect_namespace_from_name(q, ns);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_to<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<(), xml::writer::Error> {
|
||||
@@ -270,8 +273,10 @@ impl XmlSerializer for super::PropertyValue {
|
||||
super::PropertyValue::Integer(i) => {
|
||||
writer.write(XmlEvent::characters(&i.to_string()))?;
|
||||
}
|
||||
// `OwnedName`'s `Display` prefixes the namespace URI (`{uri}psk:Name`), which is not
|
||||
// a valid QName, so drivers reject the ticket.
|
||||
super::PropertyValue::QName(q) => {
|
||||
writer.write(XmlEvent::characters(&q.to_string()))?;
|
||||
writer.write(XmlEvent::characters(format_name(q).as_ref()))?;
|
||||
}
|
||||
super::PropertyValue::Unknown(_, s) => {
|
||||
writer.write(XmlEvent::characters(s))?;
|
||||
@@ -337,4 +342,27 @@ mod tests {
|
||||
let xml2 = document.to_xml();
|
||||
assert_eq!(xml1, xml2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_qname_value_as_prefixed_name() {
|
||||
// As the Microsoft IPP Class Driver lists Letter (storytold/pdfcraft#3823).
|
||||
let origin = br#"<psf:PrintTicket version="1" xmlns:psf="http://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:psk="http://schemas.microsoft.com/windows/2003/08/printing/printschemakeywords" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns0003="http://schemas.microsoft.com/windows/2013/12/printing/printschemaframework2" xmlns:ns0004="urn:only-used-in-a-value">
|
||||
<psf:Feature name="psk:PageMediaSize">
|
||||
<psf:Option name="psk:NorthAmericaLetter">
|
||||
<psf:Property name="ns0003:feedDirectionOverride">
|
||||
<psf:Value xsi:type="xsd:QName">psk:LongEdgeFirst</psf:Value>
|
||||
</psf:Property>
|
||||
<psf:Property name="psk:DisplayName">
|
||||
<psf:Value xsi:type="xsd:QName">ns0004:Letter</psf:Value>
|
||||
</psf:Property>
|
||||
</psf:Option>
|
||||
</psf:Feature>
|
||||
</psf:PrintTicket>"#;
|
||||
let document = PrintTicketDocument::parse_from_bytes(origin).unwrap();
|
||||
let xml = String::from_utf8(document.to_xml()).unwrap();
|
||||
assert!(xml.contains(">psk:LongEdgeFirst<"), "{xml}");
|
||||
assert!(xml.contains(">ns0004:Letter<"), "{xml}");
|
||||
assert!(xml.contains(r#"xmlns:ns0004="urn:only-used-in-a-value""#), "{xml}");
|
||||
assert!(!xml.contains('{'), "{xml}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user