2121
2222import java .io .File ;
2323import java .io .FileInputStream ;
24+ import java .io .FilterReader ;
25+ import java .io .IOException ;
2426import java .io .InputStreamReader ;
2527import java .io .Reader ;
2628import java .util .ArrayList ;
@@ -60,7 +62,8 @@ public boolean hasViolations()
6062
6163 private void loadResult ( File pmdFile , String encoding ) throws MavenReportException
6264 {
63- try ( Reader reader1 = new InputStreamReader ( new FileInputStream ( pmdFile ), encoding ) )
65+ try ( Reader reader1 = new BomFilter ( encoding , new InputStreamReader (
66+ new FileInputStream ( pmdFile ), encoding ) ) )
6467 {
6568 PmdXpp3Reader reader = new PmdXpp3Reader ();
6669 PmdErrorDetail details = reader .read ( reader1 , false );
@@ -82,6 +85,63 @@ private void loadResult( File pmdFile, String encoding ) throws MavenReportExcep
8285 }
8386 }
8487
88+ // Note: This seems to be a bug in PMD's XMLRenderer. The BOM is rendered multiple times.
89+ // once at the beginning of the file, which is Ok, but also in the middle of the file.
90+ // This filter just skips all BOMs if the encoding is not UTF-8
91+ private static class BomFilter extends FilterReader
92+ {
93+ private static final char BOM = '\uFEFF' ;
94+ private final boolean filter ;
95+
96+ BomFilter ( String encoding , Reader in )
97+ {
98+ super ( in );
99+ filter = !"UTF-8" .equalsIgnoreCase ( encoding );
100+ }
101+
102+ @ Override
103+ public int read () throws IOException
104+ {
105+ int c = super .read ();
106+
107+ if ( !filter )
108+ {
109+ return c ;
110+ }
111+
112+ while ( c != -1 && c == BOM )
113+ {
114+ c = super .read ();
115+ }
116+ return c ;
117+ }
118+
119+ @ Override
120+ public int read ( char [] cbuf , int off , int len ) throws IOException
121+ {
122+ int count = super .read ( cbuf , off , len );
123+
124+ if ( !filter )
125+ {
126+ return count ;
127+ }
128+
129+ if ( count != -1 )
130+ {
131+ for ( int i = off ; i < off + count ; i ++ )
132+ {
133+ if ( cbuf [i ] == BOM )
134+ {
135+ // shift the content one char to the left
136+ System .arraycopy ( cbuf , i + 1 , cbuf , i , off + count - 1 - i );
137+ count --;
138+ }
139+ }
140+ }
141+ return count ;
142+ }
143+ }
144+
85145 public Collection <Violation > getViolations ()
86146 {
87147 return violations ;
0 commit comments