Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8149179

[JEP 110] ArrayIndexOutOfBoundsException is thrown when update table max size

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P4
    • 9
    • 9
    • core-libs

    Description

      The below test is on HPack dynamic table,

      import java.lang.reflect.Field;
      import java.lang.reflect.Method;
      import java.nio.ByteBuffer;

      import sun.net.httpclient.hpack.Decoder;
      import sun.net.httpclient.hpack.DecodingCallback;

      public class SimpleHeaderTableTest {

          private static final DecodingCallback DEFAULT = (name, value) -> {
              System.out.println(name + ": " + value);
          };

          public static void main(String[] args) {
              Decoder decoder = new Decoder(80);
              printTableSize(decoder); // maxSize=80, size=0

              // Insert entry (h-a: v-a) into the dynamic table.
              decoder.decode(hexToBuffer("4003682d6103762d61"), DEFAULT, false);
              printTableSize(decoder); // maxSize=80, size=38

              // Insert entry (h-b: v-b) into the dynamic table.
              decoder.decode(hexToBuffer("4003682d6203762d62"), DEFAULT, false);
              printTableSize(decoder); // maxSize=80, size=76

              // Insert entry (h-cc: v-cc) into the dynamic table, and evict the entry (h-a: v-a).
              decoder.decode(hexToBuffer("4004682d636304762d6363"), DEFAULT, false);
              printTableSize(decoder); // maxSize=80, size=78

              // Update table size to 50, and evict the entry (h-b: v-b)
              decoder.decode(hexToBuffer("3f13"), DEFAULT, false);
              printTableSize(decoder); // maxSize=50, size=40
          }

          private static void printTableSize(Decoder decoder) {
              System.out.printf("maxSize=%s, size=%s%n", tableMaxSize(decoder), tableSize(decoder));
          }
          
          private static int tableSize(Decoder decoder) {
              try {
                  return getTableSize(decoder, "size");
              } catch (Exception e) {
                  throw new RuntimeException("Retrieve size failed.");
              }
          }

          private static int tableMaxSize(Decoder decoder) {
              try {
                  return getTableSize(decoder, "maxSize");
              } catch (Exception e) {
                  throw new RuntimeException("Retrieve size failed.");
              }
          }

          private static int getTableSize(Decoder decoder, String sizeField)
                  throws Exception {
              Object headerTable = getHeaderTable(decoder);
              Method method = headerTable.getClass().getDeclaredMethod(sizeField);
              method.setAccessible(true);
              return (int) method.invoke(headerTable);
          }

          private static Object getHeaderTable(Decoder decoder) throws Exception {
              Field field = decoder.getClass().getDeclaredField("table");
              field.setAccessible(true);
              return (Object) field.get(decoder);
          }

          private static ByteBuffer hexToBuffer(String hex) {
              return ByteBuffer.wrap(hexToBytes(hex));
          }

          private static byte[] hexToBytes(String hex) {
              int len = hex.length();
              byte[] bytes = new byte[len / 2];
              for (int i = 0; i < len; i += 2) {
                  bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                          + Character.digit(hex.charAt(i + 1), 16));
              }
              return bytes;
          }
      }

      The output is the following,
      maxSize=80, size=0
      h-a: v-a
      maxSize=80, size=38
      h-b: v-b
      maxSize=80, size=76
      h-cc: v-cc
      maxSize=80, size=78
      Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
      at java.lang.System.arraycopy(Native Method)
      at sun.net.httpclient.hpack.HeaderTable$CircularBuffer.resize(HeaderTable.java:441)
      at sun.net.httpclient.hpack.HeaderTable$Table.setCapacity(HeaderTable.java:373)
      at sun.net.httpclient.hpack.HeaderTable.setMaxSize(HeaderTable.java:234)
      at sun.net.httpclient.hpack.Decoder.resumeSizeUpdate(Decoder.java:333)
      at sun.net.httpclient.hpack.Decoder.proceed(Decoder.java:125)
      at sun.net.httpclient.hpack.Decoder.decode(Decoder.java:100)
      at httpclient.hpack.SimpleHeaderTableTest.main(SimpleHeaderTableTest.java:33)

      Attachments

        Activity

          People

            prappo Pavel Rappo
            jjiang John Jiang
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: