[
https://issues.apache.org/jira/browse/PDFBOX-2815?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Tilman Hausherr updated PDFBOX-2815:
------------------------------------
Description:
In COSStream.getDecodeResult(), we have this:
{code}
if (unFilteredStream == null)
{
doDecode();
}
{code}
{code}
if (unFilteredStream == null || decodeResult == null)
{
... throw exception.... (supposedly, decode failed)
}
{code}
The problem is that there is a race condition here. If thread 1 enters this
method, it sees that unFilteredStream is null, so starts decoding. Before
actually running the decode, it creates unFilteredStream, then starts decode.
Now, thread 2 enters, sees that unFilteredStream is not null (thread 1 already
created it), gets to the next if statement, sees that decodeResult is null
(thread 1 is not finished decode yet), and thinks that the decode failed.
I have solved this on my side by creating:
{code}
private void ensureDecoded()
{
synchronized (this)
{
if (unFilteredStream == null)
{
doDecode();
}
}
}
{code}
and then replace all 3 instances of this:
{code}
if (unFilteredStream == null)
{
doDecode();
}
{code}
with this:
{code}
ensureDecoded();
{code}
was:
In COSStream.getDecodeResult(), we have this:
if (unFilteredStream == null)
{
doDecode();
}
if (unFilteredStream == null || decodeResult == null)
{
... throw exception.... (supposedly, decode failed)
}
The problem is that there is a race condition here. If thread 1 enters this
method, it sees that unFilteredStream is null, so starts decoding. Before
actually running the decode, it creates unFilteredStream, then starts decode.
Now, thread 2 enters, sees that unFilteredStream is not null (thread 1 already
created it), gets to the next if statement, sees that decodeResult is null
(thread 1 is not finished decode yet), and thinks that the decode failed.
I have solved this on my side by creating:
private void ensureDecoded()
{
synchronized (this)
{
if (unFilteredStream == null)
{
doDecode();
}
}
}
and then replace all 3 instances of this:
if (unFilteredStream == null)
{
doDecode();
}
with this:
ensureDecoded();
> Race conditions in COSStream decoding
> -------------------------------------
>
> Key: PDFBOX-2815
> URL: https://issues.apache.org/jira/browse/PDFBOX-2815
> Project: PDFBox
> Issue Type: Bug
> Components: PDModel
> Affects Versions: 2.0.0
> Environment: Slow filter decoders
> Reporter: Jesse Long
> Priority: Minor
>
> In COSStream.getDecodeResult(), we have this:
> {code}
> if (unFilteredStream == null)
> {
> doDecode();
> }
> {code}
> {code}
> if (unFilteredStream == null || decodeResult == null)
> {
> ... throw exception.... (supposedly, decode failed)
> }
> {code}
> The problem is that there is a race condition here. If thread 1 enters this
> method, it sees that unFilteredStream is null, so starts decoding. Before
> actually running the decode, it creates unFilteredStream, then starts decode.
> Now, thread 2 enters, sees that unFilteredStream is not null (thread 1
> already created it), gets to the next if statement, sees that decodeResult is
> null (thread 1 is not finished decode yet), and thinks that the decode failed.
> I have solved this on my side by creating:
> {code}
> private void ensureDecoded()
> {
> synchronized (this)
> {
> if (unFilteredStream == null)
> {
> doDecode();
> }
> }
> }
> {code}
> and then replace all 3 instances of this:
> {code}
> if (unFilteredStream == null)
> {
> doDecode();
> }
> {code}
> with this:
> {code}
> ensureDecoded();
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]