pjfanning opened a new pull request, #1228:
URL: https://github.com/apache/poi/pull/1228

   Two small fixes to OPC part-name handling, surfaced during a review of the 
zip/OPC layer.
   
   ### 1. Off-by-one in `PackagePartName.checkPCharCompliant`
   
   The percent-escape length check was:
   
   ```java
   if ((length - i) < 2 || !isHexDigit(segment.charAt(i+1)) || 
!isHexDigit(segment.charAt(i+2))) {
   ```
   
   A valid escape is `%` plus **two** hex digits, so it needs three characters 
— the guard should be `< 3`. With `i == length-2` the guard passes and the code 
then indexes `charAt(i+2) == charAt(length)`, throwing 
`StringIndexOutOfBoundsException` instead of a clean `InvalidFormatException`.
   
   This is **not reachable** from a parsed part name today, because every path 
constructs the name via `new URI(...)`, which rejects a truncated escape 
(`URISyntaxException: Malformed escape pair`) before validation runs. Corrected 
defensively; no test, since no input reaches it.
   
   ### 2. `ZipPartMarshaller` corrupts percent-encoded part names on save
   
   The marshaller derived the zip item name from the **decoded** 
`getPartName().getURI().getPath()`:
   
   ```java
   new 
ZipArchiveEntry(ZipHelper.getZipItemNameFromOPCName(part.getPartName().getURI().getPath()));
   ```
   
   On read, the zip item name is turned back into a part name verbatim 
(`ZipHelper.getOPCNameFromZipItemName` just prepends `/`), and the content-type 
registration uses the ASCII `getName()`. So a part whose name contains a 
percent-encoded character (e.g. `/foo/a%40b.xml`) was written as the decoded 
`foo/[email protected]` and came back with a different name after a save/open 
round-trip. Switched to `getName()` for consistency with the read path and the 
content-type manager.
   
   Added `TestPackage.percentEncodedPartNameRoundTrips`, which fails before 
this change and passes after. (For normal, unencoded part names `getName()` and 
`getURI().getPath()` are identical, so there is no behaviour change there.)
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to