Skip to content

ArrayPoolBufferWriter buffer is used after dispose in Ascii85, AsciiHex and RunLength filters #964

@BobLd

Description

@BobLd

The ArrayPoolBufferWriter buffer is used after being dispose in Ascii85, AsciiHex and RunLength filters.

This means the buffer can already be being re-used when the output is used.

2 ways to replicate the issue:

  • Set the clearArray parameter to true in ArrayPool<T>.Shared.Return(buffer, true);. The filters corresponding filters tests will fail.
  • Run parallel loops of decoding, e.g. in Ascii85FilterTests:
            Parallel.For(0, 100000, (i) =>
            {
                if (i % 2 == 0)
                {
                    var bytes = Encoding.ASCII.GetBytes("9jqo^zBlbD-");

                    var result = filter.Decode(bytes, dictionary, 1);

                    var text = Encoding.ASCII.GetString(result.ToArray());

                    Assert.Equal("Man \0\0\0\0is d", text);
                }
                else
                {
                    const string input =
                        @"0d&.mDdmGg4?O`>9P&*SFD)dS2E2gC4pl@QEb/Zr$8N_r$:7]!01IZ=0eskNAdU47<+?7h+B3Ol2_m!C+?)#1+B1
`9>:<KhASu!rA7]9oF*)G6@;U'.@ps6t@V$[&ART*lARTXoCj@HP2DlU*/0HBI+B1r?0H_r%1a#ac$<nof.3LB""+=MAS+D58'ATD3qCj@.
           F@;@;70ea^uAKYi.Eb-A7E+*6f+EV:*DBN1?0ek+_+B1r?<%9""=ASu!rA7]9oF*)G6@;U'<.3MT)$8<SS1,pCU6jd-H;e7
C#1,U1&Ft""Og2'=;YEa`c,ASu!rA8,po+Dk\3BQ%F&+CT;%+CQ]A1,'h!Ft""Oh2'=;UBl%3eCh4`'DBMbD7O]H>0H_br.:""&q8d[6p/M
T()<(%'A;f?Ma+CT;%+E_a:A0>K&EZek1D/aN,F)u&6DBNA*A0>f4BOu4*+EM76E,9eK+B3(_<%9""p.!0AMEb031ATMF#F<G%,DIIR2+Cno
&@3B9%+CT.1.3LK*+=KNS6V0ilAoD^,@<=+N>p**=$</Jt-rY&$AKYo'+EV:.+Cf>,E,oN2F(oQ1+D#G#De*R""B-;&&FD,T'F!+n3AKY4b
F*22=@:F%a+=SF4C'moi+=Li?EZeh0FD)e-@<>p#@;]TuBl.9kATKCFGA(],AKYo5BOu4*+CT;%+C#7pF_Pr+@VfTuDf0B:+=SF4C'moi+=
Li?EZek1DKKT1F`2DD/TboKAKY](@:s.m/h%oBC'mC/$>""*cF*)G6@;Q?_DIdZpC&~>";

                    var result = filter.Decode(Encoding.ASCII.GetBytes(input), dictionary, 0);

                    var text = Encoding.ASCII.GetString(result.ToArray());

                    Assert.Equal(PdfContent.Replace("\r\n", "\n"), text);
                }
            });

the bytes of one case will be found in the second case.

The solution is to create a copy of the buffer before returning.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions