Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetPrinterAttributesAsync() throws "0 length attribute name found not in a 1setOf" from Lexmark printers #3

Open
xqrzd opened this issue Dec 9, 2024 · 6 comments · May be fixed by #8
Labels
question Further information is requested

Comments

@xqrzd
Copy link

xqrzd commented Dec 9, 2024

It seems to have regressed from this commit, 37b0660
Reverting to the prior implementation of GetNormalizedName() fixes the issue,

var normalizedName = string.IsNullOrEmpty(name) && prevAttribute != null ? prevAttribute.Name : name;
if (string.IsNullOrEmpty(normalizedName))
{
    throw new ArgumentException("0 length attribute name found not in a 1setOf");
}

When the exception is thrown in GetNormalizedName(), tag is Keyword, name is an empty string, and prevAttribute is two-sided-long-edge. If it's helpful I can attach the binary response from the printer.

@danielklecha
Copy link
Owner

@xqrzd Sorry, I missed notification.
If the tag is Keyword, the name is an empty string, and the prevAttribute is two-sided-long-edge, then why was return prevAttribute.Name; not used?
Is prevAttribute.Name also an empty string?
Even if you have 3 attributes with the same name then previous value should be calculated correctly.

@danielklecha danielklecha added the question Further information is requested label Jan 12, 2025
@danielklecha
Copy link
Owner

danielklecha commented Jan 12, 2025

I searched for public printers.
I tested GetPrinterAttributesAsync with:

  • Lexmark X464de
  • Lexmark M3150
  • Lexmark MS510
  • Lexmark T652

I didn't get an exception.

@gmuth
Copy link

gmuth commented Feb 9, 2025

Providing the IPP response of Get-Printer-Attributes is a good idea.
This helps the IPP developer community to get test data for different printers.

JIPP includes some printers: https://github.com/HPInc/jipp/tree/master/jipp-core/src/test/resources/printer
ipp-client includes only few responses: https://github.com/gmuth/ipp-client-kotlin/tree/master/printers, https://github.com/gmuth/ipp-client-kotlin/tree/master/src/test/resources

I've started a project to collect and share printer-attributes as raw ipp-response:
https://github.com/gmuth/document-format-supported/tree/main/printers

Raw IPP response can be used by mocks for tests e.g. like this https://github.com/gmuth/ipp-client-kotlin/blob/master/src/test/kotlin/de/gmuth/ipp/client/CupsClientTests.kt.

@georg-jung
Copy link

@danielklecha I experienced the same issue with a HP Color LaserJet MFP M476dn. Thanks @gmuth for providing an easy way to share these responses for debugging!

I added a PR with a response from the printer I'm experiencing this with to your repo: gmuth/document-format-supported#2

Also attached here: HP Color LaserJet MFP M476dn.zip

Note that the actual problematic response SharpIppNext tries to parse seems to be protocol version 1.1, while @gmuth's tool dumps a 2.0 response.

@georg-jung
Copy link

Debug output when the exception is thrown:

(NameWithoutLanguage) media-type-supported: heavyRough
(NameWithoutLanguage) media-type-supported: toughPaper
(NameWithoutLanguage) media-type-supported: photographic-film
(BegCollection) job-constraints-supported: no value
(MemberAttrName) : resolver-name
(NameWithoutLanguage) : duplex-unsupported-media
(MemberAttrName) : sides
(Keyword) : two-sided-short-edge
 ---> System.ArgumentException: 0 length attribute name found not in a 1setOf
   at SharpIpp.Protocol.IppProtocol.GetNormalizedName(Tag tag, String name, IppAttribute prevAttribute)
   at SharpIpp.Protocol.IppProtocol.ReadAttribute(Tag tag, BinaryReader stream, IppAttribute prevAttribute)
   at SharpIpp.Protocol.IppProtocol.ReadSections(BinaryReader reader, IIppResponseMessage res)
   at SharpIpp.Protocol.IppProtocol.ReadIppResponseAsync(Stream stream, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at SharpIpp.Protocol.IppProtocol.ReadIppResponseAsync(Stream stream, CancellationToken cancellationToken)
   at SharpIpp.SharpIppClient.SendAsync(Uri printer, IIppRequestMessage ippRequest, CancellationToken cancellationToken)
   at SharpIpp.SharpIppClient.SendAsync[TIn,TOut](TIn data, Func`2 constructRequestFunc, Func`2 constructResponseFunc, CancellationToken cancellationToken)
   at LepoIppTest.MainForm.listAttributesButton_Click(Object sender, EventArgs e)
ResponseMessage: Version: 1.1
StatusCode: SuccessfulOk
RequestId: 1
Sections:
Tag: OperationAttributesTag

Interestingly, this happens around two-sided-long-edge for my HP printer too.

@georg-jung
Copy link

georg-jung commented Feb 12, 2025

I created a dump of the raw response by my printer that produces this behaviour. HP Color LaserJet MFP M476dn IPP 1.1 GetPrinterAttributes anonymized.zip

I manually anonymized the data inside in a similar way to what @gmuth's tool would do, but I didn't change the lengths of any attributes, so this file is as close as it gets to the original.

This dump is an IPP 1.1 response, as SharpIppNext would get. I actually created a small SharpIppNext-based tool that dumps these responses (it doesn't automatically apply any changes/anonymization to the dumps). Maybe that could be helpful to e.g. add some more real printer responses to the unit tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants