Buggy code:
final class FreqProxTermsWriter extends TermsHashConsumer { @ Override public TermsHashConsumerPerThread addThread ( TermsHashPerThread perThread ) { } private static int compareText ( final char [ ] text1 , int pos1 , final char [ ] text2 , int pos2 ) { } @ Override void abort ( ) { } @ Override public void flush ( Map < TermsHashConsumerPerThread , Collection < TermsHashConsumerPerField > > threadsAndFields , final SegmentWriteState state ) throws IOException { } private byte [ ] payloadBuffer ; void appendPostings ( String fieldName , SegmentWriteState state , FreqProxTermsWriterPerField [ ] fields , FormatPostingsFieldsConsumer consumer ) throws IOException , CorruptIndexException { int numFields = fields . length ; final FreqProxFieldMergeState [ ] mergeStates = new FreqProxFieldMergeState [ numFields ] ; for ( int i = 0 ; i < numFields ; i ++ ) { FreqProxFieldMergeState fms = mergeStates [ i ] = new FreqProxFieldMergeState ( fields [ i ] ) ; assert ( fms . field . fieldInfo ) == ( fields [ 0 ] . fieldInfo ) ; boolean result = fms . nextTerm ( ) ; assert result ; } final FormatPostingsTermsConsumer termsConsumer = consumer . addField ( fields [ 0 ] . fieldInfo ) ; final Term protoTerm = new Term ( fieldName ) ; FreqProxFieldMergeState [ ] termStates = new FreqProxFieldMergeState [ numFields ] ; final IndexOptions currentFieldIndexOptions = fields [ 0 ] . fieldInfo . indexOptions ; final Map < Term , Integer > segDeletes ; if ( ( ( state . segDeletes ) != null ) && ( ( state . segDeletes . terms . size ( ) ) > 0 ) ) { segDeletes = state . segDeletes . terms ; } else { segDeletes = null ; } try { while ( numFields > 0 ) { termStates [ 0 ] = mergeStates [ 0 ] ; int numToMerge = 1 ; for ( int i = 1 ; i < numFields ; i ++ ) { final char [ ] text = mergeStates [ i ] . text ; final int textOffset = mergeStates [ i ] . textOffset ; final int cmp = FreqProxTermsWriter . compareText ( text , textOffset , termStates [ 0 ] . text , termStates [ 0 ] . textOffset ) ; if ( cmp < 0 ) { termStates [ 0 ] = mergeStates [ i ] ; numToMerge = 1 ; } else if ( cmp == 0 ) termStates [ ( numToMerge ++ ) ] = mergeStates [ i ] ; } final FormatPostingsDocsConsumer docConsumer = termsConsumer . addTerm ( termStates [ 0 ] . text , termStates [ 0 ] . textOffset ) ; final int delDocLimit ; if ( segDeletes != null ) { final Integer docIDUpto = segDeletes . get ( protoTerm . createTerm ( termStates [ 0 ] . termText ( ) ) ) ; if ( docIDUpto != null ) { delDocLimit = docIDUpto ; } else { delDocLimit = 0 ; } } else { delDocLimit = 0 ; } try { while ( numToMerge > 0 ) { FreqProxFieldMergeState minState = termStates [ 0 ] ; for ( int i = 1 ; i < numToMerge ; i ++ ) if ( ( termStates [ i ] . docID ) < ( minState . docID ) ) minState = termStates [ i ] ; final int termDocFreq = minState . termFreq ; final FormatPostingsPositionsConsumer posConsumer = docConsumer . addDoc ( minState . docID , termDocFreq ) ; if ( ( minState . docID ) < delDocLimit ) { if ( ( state . deletedDocs ) == null ) { state . deletedDocs = new org . apache . lucene . util . BitVector ( state . numDocs ) ; } state . deletedDocs . set ( minState . docID ) ; } final ByteSliceReader prox = minState . prox ; if ( currentFieldIndexOptions == ( IndexOptions . DOCS_AND_FREQS_AND_POSITIONS ) ) { try { int position = 0 ; for ( int j = 0 ; j < termDocFreq ; j ++ ) { final int code = prox . readVInt ( ) ; <START_BUG> position += code > > 1 ; <END_BUG> final int payloadLength ; if ( ( code & 1 ) != 0 ) { payloadLength = prox . readVInt ( ) ; if ( ( ( payloadBuffer ) == null ) || ( ( payloadBuffer . length ) < payloadLength ) ) payloadBuffer = new byte [ payloadLength ] ; prox . readBytes ( payloadBuffer , 0 , payloadLength ) ; } else payloadLength = 0 ; posConsumer . addPosition ( position , payloadBuffer , 0 , payloadLength ) ; } } finally { posConsumer . finish ( ) ; } } if ( ! ( minState . nextDoc ( ) ) ) { int upto = 0 ; for ( int i = 0 ; i < numToMerge ; i ++ ) if ( ( termStates [ i ] ) != minState ) termStates [ ( upto ++ ) ] = termStates [ i ] ; numToMerge -- ; assert upto == numToMerge ; if ( ! ( minState . nextTerm ( ) ) ) { upto = 0 ; for ( int i = 0 ; i < numFields ; i ++ ) if ( ( mergeStates [ i ] ) != minState ) mergeStates [ ( upto ++ ) ] = mergeStates [ i ] ; numFields -- ; assert upto == numFields ; } } } } finally { docConsumer . finish ( ) ; } } } finally { termsConsumer . finish ( ) ; } } final UTF8Result termsUTF8 = new UnicodeUtil . UTF8Result ( ) ; }

Fix:
position += code > > > 1 ;