3535import org .apache .hadoop .io .IOUtils ;
3636import org .apache .hadoop .io .WritableUtils ;
3737import org .apache .yetus .audience .InterfaceAudience ;
38+ import org .slf4j .Logger ;
39+ import org .slf4j .LoggerFactory ;
3840
3941import org .apache .hbase .thirdparty .com .google .common .base .Function ;
4042import org .apache .hbase .thirdparty .com .google .common .collect .Lists ;
4648@ InterfaceAudience .Private
4749public class KeyValueUtil {
4850
51+ private static final Logger LOG = LoggerFactory .getLogger (KeyValueUtil .class );
52+
4953 /**************** length *********************/
5054
5155 /**
@@ -524,87 +528,120 @@ static String bytesToHex(byte[] buf, int offset, int length) {
524528 }
525529
526530 static void checkKeyValueBytes (byte [] buf , int offset , int length , boolean withTags ) {
531+ if (buf == null ) {
532+ String msg = "Invalid to have null byte array in KeyValue." ;
533+ LOG .warn (msg );
534+ throw new IllegalArgumentException (msg );
535+ }
536+
527537 int pos = offset , endOffset = offset + length ;
528538 // check the key
529539 if (pos + Bytes .SIZEOF_INT > endOffset ) {
530- throw new IllegalArgumentException (
531- "Overflow when reading key length at position=" + pos + bytesToHex (buf , offset , length ));
540+ String msg =
541+ "Overflow when reading key length at position=" + pos + bytesToHex (buf , offset , length );
542+ LOG .warn (msg );
543+ throw new IllegalArgumentException (msg );
532544 }
533545 int keyLen = Bytes .toInt (buf , pos , Bytes .SIZEOF_INT );
534546 pos += Bytes .SIZEOF_INT ;
535547 if (keyLen <= 0 || pos + keyLen > endOffset ) {
536- throw new IllegalArgumentException (
537- "Invalid key length in KeyValue. keyLength=" + keyLen + bytesToHex (buf , offset , length ));
548+ String msg =
549+ "Invalid key length in KeyValue. keyLength=" + keyLen + bytesToHex (buf , offset , length );
550+ LOG .warn (msg );
551+ throw new IllegalArgumentException (msg );
538552 }
539553 // check the value
540554 if (pos + Bytes .SIZEOF_INT > endOffset ) {
541- throw new IllegalArgumentException ("Overflow when reading value length at position=" + pos
542- + bytesToHex (buf , offset , length ));
555+ String msg =
556+ "Overflow when reading value length at position=" + pos + bytesToHex (buf , offset , length );
557+ LOG .warn (msg );
558+ throw new IllegalArgumentException (msg );
543559 }
544560 int valLen = Bytes .toInt (buf , pos , Bytes .SIZEOF_INT );
545561 pos += Bytes .SIZEOF_INT ;
546562 if (valLen < 0 || pos + valLen > endOffset ) {
547- throw new IllegalArgumentException ("Invalid value length in KeyValue, valueLength=" + valLen
548- + bytesToHex (buf , offset , length ));
563+ String msg = "Invalid value length in KeyValue, valueLength=" + valLen +
564+ bytesToHex (buf , offset , length );
565+ LOG .warn (msg );
566+ throw new IllegalArgumentException (msg );
549567 }
550568 // check the row
551569 if (pos + Bytes .SIZEOF_SHORT > endOffset ) {
552- throw new IllegalArgumentException (
553- "Overflow when reading row length at position=" + pos + bytesToHex (buf , offset , length ));
570+ String msg =
571+ "Overflow when reading row length at position=" + pos + bytesToHex (buf , offset , length );
572+ LOG .warn (msg );
573+ throw new IllegalArgumentException (msg );
554574 }
555575 short rowLen = Bytes .toShort (buf , pos , Bytes .SIZEOF_SHORT );
556576 pos += Bytes .SIZEOF_SHORT ;
557577 if (rowLen < 0 || pos + rowLen > endOffset ) {
558- throw new IllegalArgumentException (
559- "Invalid row length in KeyValue, rowLength=" + rowLen + bytesToHex (buf , offset , length ));
578+ String msg =
579+ "Invalid row length in KeyValue, rowLength=" + rowLen + bytesToHex (buf , offset , length );
580+ LOG .warn (msg );
581+ throw new IllegalArgumentException (msg );
560582 }
561583 pos += rowLen ;
562584 // check the family
563585 if (pos + Bytes .SIZEOF_BYTE > endOffset ) {
564- throw new IllegalArgumentException ("Overflow when reading family length at position=" + pos
565- + bytesToHex (buf , offset , length ));
586+ String msg = "Overflow when reading family length at position=" + pos +
587+ bytesToHex (buf , offset , length );
588+ LOG .warn (msg );
589+ throw new IllegalArgumentException (msg );
566590 }
567591 int familyLen = buf [pos ];
568592 pos += Bytes .SIZEOF_BYTE ;
569593 if (familyLen < 0 || pos + familyLen > endOffset ) {
570- throw new IllegalArgumentException ("Invalid family length in KeyValue, familyLength="
571- + familyLen + bytesToHex (buf , offset , length ));
594+ String msg = "Invalid family length in KeyValue, familyLength=" + familyLen +
595+ bytesToHex (buf , offset , length );
596+ LOG .warn (msg );
597+ throw new IllegalArgumentException (msg );
572598 }
573599 pos += familyLen ;
574600 // check the qualifier
575601 int qualifierLen = keyLen - Bytes .SIZEOF_SHORT - rowLen - Bytes .SIZEOF_BYTE - familyLen
576602 - Bytes .SIZEOF_LONG - Bytes .SIZEOF_BYTE ;
577603 if (qualifierLen < 0 || pos + qualifierLen > endOffset ) {
578- throw new IllegalArgumentException ("Invalid qualifier length in KeyValue, qualifierLen="
579- + qualifierLen + bytesToHex (buf , offset , length ));
604+ String msg = "Invalid qualifier length in KeyValue, qualifierLen=" + qualifierLen +
605+ bytesToHex (buf , offset , length );
606+ LOG .warn (msg );
607+ throw new IllegalArgumentException (msg );
580608 }
581609 pos += qualifierLen ;
582610 // check the timestamp
583611 if (pos + Bytes .SIZEOF_LONG > endOffset ) {
584- throw new IllegalArgumentException (
585- "Overflow when reading timestamp at position=" + pos + bytesToHex (buf , offset , length ));
612+ String msg =
613+ "Overflow when reading timestamp at position=" + pos + bytesToHex (buf , offset , length );
614+ LOG .warn (msg );
615+ throw new IllegalArgumentException (msg );
586616 }
587617 long timestamp = Bytes .toLong (buf , pos , Bytes .SIZEOF_LONG );
588618 if (timestamp < 0 ) {
589- throw new IllegalArgumentException (
590- "Timestamp cannot be negative, ts=" + timestamp + bytesToHex (buf , offset , length ));
619+ String msg =
620+ "Timestamp cannot be negative, ts=" + timestamp + bytesToHex (buf , offset , length );
621+ LOG .warn (msg );
622+ throw new IllegalArgumentException (msg );
591623 }
592624 pos += Bytes .SIZEOF_LONG ;
593625 // check the type
594626 if (pos + Bytes .SIZEOF_BYTE > endOffset ) {
595- throw new IllegalArgumentException (
596- "Overflow when reading type at position=" + pos + bytesToHex (buf , offset , length ));
627+ String msg =
628+ "Overflow when reading type at position=" + pos + bytesToHex (buf , offset , length );
629+ LOG .warn (msg );
630+ throw new IllegalArgumentException (msg );
597631 }
598632 byte type = buf [pos ];
599633 if (!Type .isValidType (type )) {
600- throw new IllegalArgumentException (
601- "Invalid type in KeyValue, type=" + type + bytesToHex (buf , offset , length ));
634+ String msg = "Invalid type in KeyValue, type=" + type + bytesToHex (buf , offset , length );
635+ LOG .warn (msg );
636+ throw new IllegalArgumentException (msg );
602637 }
603638 pos += Bytes .SIZEOF_BYTE ;
604639 // check the value
605640 if (pos + valLen > endOffset ) {
606- throw new IllegalArgumentException (
607- "Overflow when reading value part at position=" + pos + bytesToHex (buf , offset , length ));
641+ String msg =
642+ "Overflow when reading value part at position=" + pos + bytesToHex (buf , offset , length );
643+ LOG .warn (msg );
644+ throw new IllegalArgumentException (msg );
608645 }
609646 pos += valLen ;
610647 // check the tags
@@ -613,39 +650,55 @@ static void checkKeyValueBytes(byte[] buf, int offset, int length, boolean withT
613650 // withTags is true but no tag in the cell.
614651 return ;
615652 }
616- if (pos + Bytes .SIZEOF_SHORT > endOffset ) {
617- throw new IllegalArgumentException ("Overflow when reading tags length at position=" + pos
618- + bytesToHex (buf , offset , length ));
619- }
620- short tagsLen = Bytes .toShort (buf , pos );
621- pos += Bytes .SIZEOF_SHORT ;
622- if (tagsLen < 0 || pos + tagsLen > endOffset ) {
623- throw new IllegalArgumentException ("Invalid tags length in KeyValue at position="
624- + (pos - Bytes .SIZEOF_SHORT ) + bytesToHex (buf , offset , length ));
625- }
626- int tagsEndOffset = pos + tagsLen ;
627- for (; pos < tagsEndOffset ;) {
628- if (pos + Tag .TAG_LENGTH_SIZE > endOffset ) {
629- throw new IllegalArgumentException ("Overflow when reading tag length at position=" + pos
630- + bytesToHex (buf , offset , length ));
631- }
632- short tagLen = Bytes .toShort (buf , pos );
633- pos += Tag .TAG_LENGTH_SIZE ;
634- // tagLen contains one byte tag type, so must be not less than 1.
635- if (tagLen < 1 || pos + tagLen > endOffset ) {
636- throw new IllegalArgumentException (
637- "Invalid tag length at position=" + (pos - Tag .TAG_LENGTH_SIZE ) + ", tagLength="
638- + tagLen + bytesToHex (buf , offset , length ));
639- }
640- pos += tagLen ;
641- }
653+ pos = checkKeyValueTagBytes (buf , offset , length , pos , endOffset );
642654 }
643655 if (pos != endOffset ) {
644- throw new IllegalArgumentException ("Some redundant bytes in KeyValue's buffer, startOffset="
645- + pos + ", endOffset=" + endOffset + bytesToHex (buf , offset , length ));
656+ String msg = "Some redundant bytes in KeyValue's buffer, startOffset=" + pos + ", endOffset="
657+ + endOffset + bytesToHex (buf , offset , length );
658+ LOG .warn (msg );
659+ throw new IllegalArgumentException (msg );
646660 }
647661 }
648662
663+ private static int checkKeyValueTagBytes (byte [] buf , int offset , int length , int pos ,
664+ int endOffset ) {
665+ if (pos + Bytes .SIZEOF_SHORT > endOffset ) {
666+ String msg = "Overflow when reading tags length at position=" + pos +
667+ bytesToHex (buf , offset , length );
668+ LOG .warn (msg );
669+ throw new IllegalArgumentException (msg );
670+ }
671+ short tagsLen = Bytes .toShort (buf , pos );
672+ pos += Bytes .SIZEOF_SHORT ;
673+ if (tagsLen < 0 || pos + tagsLen > endOffset ) {
674+ String msg = "Invalid tags length in KeyValue at position=" + (pos - Bytes .SIZEOF_SHORT )
675+ + bytesToHex (buf , offset , length );
676+ LOG .warn (msg );
677+ throw new IllegalArgumentException (msg );
678+ }
679+ int tagsEndOffset = pos + tagsLen ;
680+ for (; pos < tagsEndOffset ;) {
681+ if (pos + Tag .TAG_LENGTH_SIZE > endOffset ) {
682+ String msg = "Overflow when reading tag length at position=" + pos +
683+ bytesToHex (buf , offset , length );
684+ LOG .warn (msg );
685+ throw new IllegalArgumentException (msg );
686+ }
687+ short tagLen = Bytes .toShort (buf , pos );
688+ pos += Tag .TAG_LENGTH_SIZE ;
689+ // tagLen contains one byte tag type, so must be not less than 1.
690+ if (tagLen < 1 || pos + tagLen > endOffset ) {
691+ String msg =
692+ "Invalid tag length at position=" + (pos - Tag .TAG_LENGTH_SIZE ) + ", tagLength="
693+ + tagLen + bytesToHex (buf , offset , length );
694+ LOG .warn (msg );
695+ throw new IllegalArgumentException (msg );
696+ }
697+ pos += tagLen ;
698+ }
699+ return pos ;
700+ }
701+
649702 /**
650703 * Create a KeyValue reading from the raw InputStream. Named
651704 * <code>createKeyValueFromInputStream</code> so doesn't clash with {@link #create(DataInput)}
0 commit comments