docs: private static SimpleEntry<byte[], Integer> readAllBytes(final InputStream inputStream, final long fileSizeHint)
              throws IOException {
          if (fileSizeHint > MAX_BUFFER_SIZE) {
              throw new IOException("InputStream is too large to read");
          }
          final int bufferSize = fileSizeHint < 1L
                  // If fileSizeHint is unknown, use default buffer size 
                  ? DEFAULT_BUFFER_SIZE
                  // fileSizeHint is just a hint -- limit the max allocated buffer size, so that invalid ZipEntry
                  // lengths do not become a memory allocation attack vector
                  : Math.min((int) fileSizeHint, MAX_INITIAL_BUFFER_SIZE);
          byte[] buf = new byte[bufferSize];
  
          int bufLength = buf.length;
          int totBytesRead = 0;
          for (int bytesRead;;) {
              // Fill buffer -- may fill more or fewer bytes than buffer size
              while ((bytesRead = inputStream.read(buf, totBytesRead, bufLength - totBytesRead)) > 0) {
                  totBytesRead += bytesRead;
              }
              if (bytesRead < 0) {
                  // Reached end of stream
                  break;
              }
              // bytesRead == 0 => grow buffer, avoiding overflow
              if (bufLength <= MAX_BUFFER_SIZE - bufLength) {
                  bufLength = bufLength << 1;
              } else {
                  if (bufLength == MAX_BUFFER_SIZE) {
                      throw new IOException("InputStream too large to read");
                  }
                  bufLength = MAX_BUFFER_SIZE;
              }
              buf = Arrays.copyOf(buf, bufLength);
          }
          // Return buffer and number of bytes read
          return new SimpleEntry<>((bufLength == totBytesRead) ? buf : Arrays.copyOf(buf, totBytesRead),
                  totBytesRead);
      }