10f66f451Sopenharmony_ci/*
20f66f451Sopenharmony_ci * Simple XZ decoder command line tool
30f66f451Sopenharmony_ci *
40f66f451Sopenharmony_ci * Author: Lasse Collin <lasse.collin@tukaani.org>
50f66f451Sopenharmony_ci *
60f66f451Sopenharmony_ci * This file has been put into the public domain.
70f66f451Sopenharmony_ci * You can do whatever you want with this file.
80f66f451Sopenharmony_ci * Modified for toybox by Isaac Dunham
90f66f451Sopenharmony_ciUSE_XZCAT(NEWTOY(xzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
100f66f451Sopenharmony_ci
110f66f451Sopenharmony_ciconfig XZCAT
120f66f451Sopenharmony_ci  bool "xzcat"
130f66f451Sopenharmony_ci  default n
140f66f451Sopenharmony_ci  help
150f66f451Sopenharmony_ci    usage: xzcat [filename...]
160f66f451Sopenharmony_ci
170f66f451Sopenharmony_ci    Decompress listed files to stdout. Use stdin if no files listed.
180f66f451Sopenharmony_ci
190f66f451Sopenharmony_ci*/
200f66f451Sopenharmony_ci#define FOR_xzcat
210f66f451Sopenharmony_ci#include "toys.h"
220f66f451Sopenharmony_ci
230f66f451Sopenharmony_ci// BEGIN xz.h
240f66f451Sopenharmony_ci
250f66f451Sopenharmony_ci/**
260f66f451Sopenharmony_ci * enum xz_ret - Return codes
270f66f451Sopenharmony_ci * @XZ_OK:                  Everything is OK so far. More input or more
280f66f451Sopenharmony_ci *                          output space is required to continue.
290f66f451Sopenharmony_ci * @XZ_STREAM_END:          Operation finished successfully.
300f66f451Sopenharmony_ci * @XZ_UNSUPPORTED_CHECK:   Integrity check type is not supported. Decoding
310f66f451Sopenharmony_ci *                          is still possible in multi-call mode by simply
320f66f451Sopenharmony_ci *                          calling xz_dec_run() again.
330f66f451Sopenharmony_ci *                          Note that this return value is used only if
340f66f451Sopenharmony_ci *                          XZ_DEC_ANY_CHECK was defined at build time,
350f66f451Sopenharmony_ci *                          which is not used in the kernel. Unsupported
360f66f451Sopenharmony_ci *                          check types return XZ_OPTIONS_ERROR if
370f66f451Sopenharmony_ci *                          XZ_DEC_ANY_CHECK was not defined at build time.
380f66f451Sopenharmony_ci * @XZ_MEM_ERROR:           Allocating memory failed. The amount of memory
390f66f451Sopenharmony_ci *                          that was tried to be allocated was no more than the
400f66f451Sopenharmony_ci *                          dict_max argument given to xz_dec_init().
410f66f451Sopenharmony_ci * @XZ_MEMLIMIT_ERROR:      A bigger LZMA2 dictionary would be needed than
420f66f451Sopenharmony_ci *                          allowed by the dict_max argument given to
430f66f451Sopenharmony_ci *                          xz_dec_init().
440f66f451Sopenharmony_ci * @XZ_FORMAT_ERROR:        File format was not recognized (wrong magic
450f66f451Sopenharmony_ci *                          bytes).
460f66f451Sopenharmony_ci * @XZ_OPTIONS_ERROR:       This implementation doesn't support the requested
470f66f451Sopenharmony_ci *                          compression options. In the decoder this means
480f66f451Sopenharmony_ci *                          that the header CRC32 matches, but the header
490f66f451Sopenharmony_ci *                          itself specifies something that we don't support.
500f66f451Sopenharmony_ci * @XZ_DATA_ERROR:          Compressed data is corrupt.
510f66f451Sopenharmony_ci * @XZ_BUF_ERROR:           Cannot make any progress. Details are slightly
520f66f451Sopenharmony_ci *                          different between multi-call and single-call
530f66f451Sopenharmony_ci *                          mode; more information below.
540f66f451Sopenharmony_ci *
550f66f451Sopenharmony_ci * XZ_BUF_ERROR is returned when two consecutive calls to XZ code cannot
560f66f451Sopenharmony_ci * consume any input and cannot produce any new output. This happens when
570f66f451Sopenharmony_ci * there is no new input available, or the output buffer is full while at
580f66f451Sopenharmony_ci * least one output byte is still pending. Assuming your code is not buggy,
590f66f451Sopenharmony_ci * you can get this error only when decoding a compressed stream that is
600f66f451Sopenharmony_ci * truncated or otherwise corrupt.
610f66f451Sopenharmony_ci */
620f66f451Sopenharmony_cienum xz_ret {
630f66f451Sopenharmony_ci  XZ_OK,
640f66f451Sopenharmony_ci  XZ_STREAM_END,
650f66f451Sopenharmony_ci  XZ_UNSUPPORTED_CHECK,
660f66f451Sopenharmony_ci  XZ_MEM_ERROR,
670f66f451Sopenharmony_ci  XZ_MEMLIMIT_ERROR,
680f66f451Sopenharmony_ci  XZ_FORMAT_ERROR,
690f66f451Sopenharmony_ci  XZ_OPTIONS_ERROR,
700f66f451Sopenharmony_ci  XZ_DATA_ERROR,
710f66f451Sopenharmony_ci  XZ_BUF_ERROR
720f66f451Sopenharmony_ci};
730f66f451Sopenharmony_ci
740f66f451Sopenharmony_ci/**
750f66f451Sopenharmony_ci * struct xz_buf - Passing input and output buffers to XZ code
760f66f451Sopenharmony_ci * @in:         Beginning of the input buffer. This may be NULL if and only
770f66f451Sopenharmony_ci *              if in_pos is equal to in_size.
780f66f451Sopenharmony_ci * @in_pos:     Current position in the input buffer. This must not exceed
790f66f451Sopenharmony_ci *              in_size.
800f66f451Sopenharmony_ci * @in_size:    Size of the input buffer
810f66f451Sopenharmony_ci * @out:        Beginning of the output buffer. This may be NULL if and only
820f66f451Sopenharmony_ci *              if out_pos is equal to out_size.
830f66f451Sopenharmony_ci * @out_pos:    Current position in the output buffer. This must not exceed
840f66f451Sopenharmony_ci *              out_size.
850f66f451Sopenharmony_ci * @out_size:   Size of the output buffer
860f66f451Sopenharmony_ci *
870f66f451Sopenharmony_ci * Only the contents of the output buffer from out[out_pos] onward, and
880f66f451Sopenharmony_ci * the variables in_pos and out_pos are modified by the XZ code.
890f66f451Sopenharmony_ci */
900f66f451Sopenharmony_cistruct xz_buf {
910f66f451Sopenharmony_ci  const uint8_t *in;
920f66f451Sopenharmony_ci  size_t in_pos;
930f66f451Sopenharmony_ci  size_t in_size;
940f66f451Sopenharmony_ci
950f66f451Sopenharmony_ci  uint8_t *out;
960f66f451Sopenharmony_ci  size_t out_pos;
970f66f451Sopenharmony_ci  size_t out_size;
980f66f451Sopenharmony_ci};
990f66f451Sopenharmony_ci
1000f66f451Sopenharmony_ci/**
1010f66f451Sopenharmony_ci * struct xz_dec - Opaque type to hold the XZ decoder state
1020f66f451Sopenharmony_ci */
1030f66f451Sopenharmony_cistruct xz_dec;
1040f66f451Sopenharmony_ci
1050f66f451Sopenharmony_ci/**
1060f66f451Sopenharmony_ci * xz_dec_init() - Allocate and initialize a XZ decoder state
1070f66f451Sopenharmony_ci * @mode:       Operation mode
1080f66f451Sopenharmony_ci * @dict_max:   Maximum size of the LZMA2 dictionary (history buffer) for
1090f66f451Sopenharmony_ci *              multi-call decoding. LZMA2 dictionary is always 2^n bytes
1100f66f451Sopenharmony_ci *              or 2^n + 2^(n-1) bytes (the latter sizes are less common
1110f66f451Sopenharmony_ci *              in practice), so other values for dict_max don't make sense.
1120f66f451Sopenharmony_ci *              In the kernel, dictionary sizes of 64 KiB, 128 KiB, 256 KiB,
1130f66f451Sopenharmony_ci *              512 KiB, and 1 MiB are probably the only reasonable values,
1140f66f451Sopenharmony_ci *              except for kernel and initramfs images where a bigger
1150f66f451Sopenharmony_ci *              dictionary can be fine and useful.
1160f66f451Sopenharmony_ci *
1170f66f451Sopenharmony_ci * dict_max specifies the maximum allowed dictionary size that xz_dec_run()
1180f66f451Sopenharmony_ci * may allocate once it has parsed the dictionary size from the stream
1190f66f451Sopenharmony_ci * headers. This way excessive allocations can be avoided while still
1200f66f451Sopenharmony_ci * limiting the maximum memory usage to a sane value to prevent running the
1210f66f451Sopenharmony_ci * system out of memory when decompressing streams from untrusted sources.
1220f66f451Sopenharmony_ci *
1230f66f451Sopenharmony_ci * On success, xz_dec_init() returns a pointer to struct xz_dec, which is
1240f66f451Sopenharmony_ci * ready to be used with xz_dec_run(). If memory allocation fails,
1250f66f451Sopenharmony_ci * xz_dec_init() returns NULL.
1260f66f451Sopenharmony_ci */
1270f66f451Sopenharmony_cistruct xz_dec *xz_dec_init(uint32_t dict_max);
1280f66f451Sopenharmony_ci
1290f66f451Sopenharmony_ci/**
1300f66f451Sopenharmony_ci * xz_dec_run() - Run the XZ decoder
1310f66f451Sopenharmony_ci * @s:          Decoder state allocated using xz_dec_init()
1320f66f451Sopenharmony_ci * @b:          Input and output buffers
1330f66f451Sopenharmony_ci *
1340f66f451Sopenharmony_ci * The possible return values depend on build options and operation mode.
1350f66f451Sopenharmony_ci * See enum xz_ret for details.
1360f66f451Sopenharmony_ci *
1370f66f451Sopenharmony_ci * Note that if an error occurs in single-call mode (return value is not
1380f66f451Sopenharmony_ci * XZ_STREAM_END), b->in_pos and b->out_pos are not modified and the
1390f66f451Sopenharmony_ci * contents of the output buffer from b->out[b->out_pos] onward are
1400f66f451Sopenharmony_ci * undefined. This is true even after XZ_BUF_ERROR, because with some filter
1410f66f451Sopenharmony_ci * chains, there may be a second pass over the output buffer, and this pass
1420f66f451Sopenharmony_ci * cannot be properly done if the output buffer is truncated. Thus, you
1430f66f451Sopenharmony_ci * cannot give the single-call decoder a too small buffer and then expect to
1440f66f451Sopenharmony_ci * get that amount valid data from the beginning of the stream. You must use
1450f66f451Sopenharmony_ci * the multi-call decoder if you don't want to uncompress the whole stream.
1460f66f451Sopenharmony_ci */
1470f66f451Sopenharmony_cienum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b);
1480f66f451Sopenharmony_ci
1490f66f451Sopenharmony_ci/**
1500f66f451Sopenharmony_ci * xz_dec_reset() - Reset an already allocated decoder state
1510f66f451Sopenharmony_ci * @s:          Decoder state allocated using xz_dec_init()
1520f66f451Sopenharmony_ci *
1530f66f451Sopenharmony_ci * This function can be used to reset the multi-call decoder state without
1540f66f451Sopenharmony_ci * freeing and reallocating memory with xz_dec_end() and xz_dec_init().
1550f66f451Sopenharmony_ci *
1560f66f451Sopenharmony_ci * In single-call mode, xz_dec_reset() is always called in the beginning of
1570f66f451Sopenharmony_ci * xz_dec_run(). Thus, explicit call to xz_dec_reset() is useful only in
1580f66f451Sopenharmony_ci * multi-call mode.
1590f66f451Sopenharmony_ci */
1600f66f451Sopenharmony_civoid xz_dec_reset(struct xz_dec *s);
1610f66f451Sopenharmony_ci
1620f66f451Sopenharmony_ci/**
1630f66f451Sopenharmony_ci * xz_dec_end() - Free the memory allocated for the decoder state
1640f66f451Sopenharmony_ci * @s:          Decoder state allocated using xz_dec_init(). If s is NULL,
1650f66f451Sopenharmony_ci *              this function does nothing.
1660f66f451Sopenharmony_ci */
1670f66f451Sopenharmony_civoid xz_dec_end(struct xz_dec *s);
1680f66f451Sopenharmony_ci
1690f66f451Sopenharmony_ci/*
1700f66f451Sopenharmony_ci * Update CRC32 value using the polynomial from IEEE-802.3. To start a new
1710f66f451Sopenharmony_ci * calculation, the third argument must be zero. To continue the calculation,
1720f66f451Sopenharmony_ci * the previously returned value is passed as the third argument.
1730f66f451Sopenharmony_ci */
1740f66f451Sopenharmony_cistatic uint32_t xz_crc32_table[256];
1750f66f451Sopenharmony_ci
1760f66f451Sopenharmony_ciuint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
1770f66f451Sopenharmony_ci{
1780f66f451Sopenharmony_ci  crc = ~crc;
1790f66f451Sopenharmony_ci
1800f66f451Sopenharmony_ci  while (size != 0) {
1810f66f451Sopenharmony_ci    crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
1820f66f451Sopenharmony_ci    --size;
1830f66f451Sopenharmony_ci  }
1840f66f451Sopenharmony_ci
1850f66f451Sopenharmony_ci  return ~crc;
1860f66f451Sopenharmony_ci}
1870f66f451Sopenharmony_ci
1880f66f451Sopenharmony_cistatic uint64_t xz_crc64_table[256];
1890f66f451Sopenharmony_ci
1900f66f451Sopenharmony_ci
1910f66f451Sopenharmony_ci// END xz.h
1920f66f451Sopenharmony_ci
1930f66f451Sopenharmony_cistatic uint8_t in[BUFSIZ];
1940f66f451Sopenharmony_cistatic uint8_t out[BUFSIZ];
1950f66f451Sopenharmony_ci
1960f66f451Sopenharmony_civoid do_xzcat(int fd, char *name)
1970f66f451Sopenharmony_ci{
1980f66f451Sopenharmony_ci  struct xz_buf b;
1990f66f451Sopenharmony_ci  struct xz_dec *s;
2000f66f451Sopenharmony_ci  enum xz_ret ret;
2010f66f451Sopenharmony_ci  const char *msg;
2020f66f451Sopenharmony_ci
2030f66f451Sopenharmony_ci  crc_init(xz_crc32_table, 1);
2040f66f451Sopenharmony_ci  const uint64_t poly = 0xC96C5795D7870F42ULL;
2050f66f451Sopenharmony_ci  uint32_t i;
2060f66f451Sopenharmony_ci  uint32_t j;
2070f66f451Sopenharmony_ci  uint64_t r;
2080f66f451Sopenharmony_ci
2090f66f451Sopenharmony_ci  /* initialize CRC64 table*/
2100f66f451Sopenharmony_ci  for (i = 0; i < 256; ++i) {
2110f66f451Sopenharmony_ci    r = i;
2120f66f451Sopenharmony_ci    for (j = 0; j < 8; ++j)
2130f66f451Sopenharmony_ci      r = (r >> 1) ^ (poly & ~((r & 1) - 1));
2140f66f451Sopenharmony_ci
2150f66f451Sopenharmony_ci    xz_crc64_table[i] = r;
2160f66f451Sopenharmony_ci  }
2170f66f451Sopenharmony_ci
2180f66f451Sopenharmony_ci  /*
2190f66f451Sopenharmony_ci   * Support up to 64 MiB dictionary. The actually needed memory
2200f66f451Sopenharmony_ci   * is allocated once the headers have been parsed.
2210f66f451Sopenharmony_ci   */
2220f66f451Sopenharmony_ci  s = xz_dec_init(1 << 26);
2230f66f451Sopenharmony_ci  if (s == NULL) {
2240f66f451Sopenharmony_ci    msg = "Memory allocation failed\n";
2250f66f451Sopenharmony_ci    goto error;
2260f66f451Sopenharmony_ci  }
2270f66f451Sopenharmony_ci
2280f66f451Sopenharmony_ci  b.in = in;
2290f66f451Sopenharmony_ci  b.in_pos = 0;
2300f66f451Sopenharmony_ci  b.in_size = 0;
2310f66f451Sopenharmony_ci  b.out = out;
2320f66f451Sopenharmony_ci  b.out_pos = 0;
2330f66f451Sopenharmony_ci  b.out_size = BUFSIZ;
2340f66f451Sopenharmony_ci
2350f66f451Sopenharmony_ci  for (;;) {
2360f66f451Sopenharmony_ci    if (b.in_pos == b.in_size) {
2370f66f451Sopenharmony_ci      b.in_size = read(fd, in, sizeof(in));
2380f66f451Sopenharmony_ci      b.in_pos = 0;
2390f66f451Sopenharmony_ci    }
2400f66f451Sopenharmony_ci
2410f66f451Sopenharmony_ci    ret = xz_dec_run(s, &b);
2420f66f451Sopenharmony_ci
2430f66f451Sopenharmony_ci    if (b.out_pos == sizeof(out)) {
2440f66f451Sopenharmony_ci      if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
2450f66f451Sopenharmony_ci        msg = "Write error\n";
2460f66f451Sopenharmony_ci        goto error;
2470f66f451Sopenharmony_ci      }
2480f66f451Sopenharmony_ci
2490f66f451Sopenharmony_ci      b.out_pos = 0;
2500f66f451Sopenharmony_ci    }
2510f66f451Sopenharmony_ci
2520f66f451Sopenharmony_ci    if (ret == XZ_OK)
2530f66f451Sopenharmony_ci      continue;
2540f66f451Sopenharmony_ci
2550f66f451Sopenharmony_ci    if (ret == XZ_UNSUPPORTED_CHECK)
2560f66f451Sopenharmony_ci      continue;
2570f66f451Sopenharmony_ci
2580f66f451Sopenharmony_ci    if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
2590f66f451Sopenharmony_ci      msg = "Write error\n";
2600f66f451Sopenharmony_ci      goto error;
2610f66f451Sopenharmony_ci    }
2620f66f451Sopenharmony_ci
2630f66f451Sopenharmony_ci    switch (ret) {
2640f66f451Sopenharmony_ci    case XZ_STREAM_END:
2650f66f451Sopenharmony_ci      xz_dec_end(s);
2660f66f451Sopenharmony_ci      return;
2670f66f451Sopenharmony_ci
2680f66f451Sopenharmony_ci    case XZ_MEM_ERROR:
2690f66f451Sopenharmony_ci      msg = "Memory allocation failed\n";
2700f66f451Sopenharmony_ci      goto error;
2710f66f451Sopenharmony_ci
2720f66f451Sopenharmony_ci    case XZ_MEMLIMIT_ERROR:
2730f66f451Sopenharmony_ci      msg = "Memory usage limit reached\n";
2740f66f451Sopenharmony_ci      goto error;
2750f66f451Sopenharmony_ci
2760f66f451Sopenharmony_ci    case XZ_FORMAT_ERROR:
2770f66f451Sopenharmony_ci      msg = "Not a .xz file\n";
2780f66f451Sopenharmony_ci      goto error;
2790f66f451Sopenharmony_ci
2800f66f451Sopenharmony_ci    case XZ_OPTIONS_ERROR:
2810f66f451Sopenharmony_ci      msg = "Unsupported options in the .xz headers\n";
2820f66f451Sopenharmony_ci      goto error;
2830f66f451Sopenharmony_ci
2840f66f451Sopenharmony_ci    case XZ_DATA_ERROR:
2850f66f451Sopenharmony_ci    case XZ_BUF_ERROR:
2860f66f451Sopenharmony_ci      msg = "File is corrupt\n";
2870f66f451Sopenharmony_ci      goto error;
2880f66f451Sopenharmony_ci
2890f66f451Sopenharmony_ci    default:
2900f66f451Sopenharmony_ci      msg = "Bug!\n";
2910f66f451Sopenharmony_ci      goto error;
2920f66f451Sopenharmony_ci    }
2930f66f451Sopenharmony_ci  }
2940f66f451Sopenharmony_ci
2950f66f451Sopenharmony_cierror:
2960f66f451Sopenharmony_ci  xz_dec_end(s);
2970f66f451Sopenharmony_ci  error_exit("%s", msg);
2980f66f451Sopenharmony_ci}
2990f66f451Sopenharmony_ci
3000f66f451Sopenharmony_civoid xzcat_main(void)
3010f66f451Sopenharmony_ci{
3020f66f451Sopenharmony_ci  loopfiles(toys.optargs, do_xzcat);
3030f66f451Sopenharmony_ci}
3040f66f451Sopenharmony_ci
3050f66f451Sopenharmony_ci// BEGIN xz_private.h
3060f66f451Sopenharmony_ci
3070f66f451Sopenharmony_ci
3080f66f451Sopenharmony_ci/* Uncomment as needed to enable BCJ filter decoders.
3090f66f451Sopenharmony_ci * These cost about 2.5 k when all are enabled; SPARC and IA64 make 0.7 k
3100f66f451Sopenharmony_ci * */
3110f66f451Sopenharmony_ci
3120f66f451Sopenharmony_ci#define XZ_DEC_X86
3130f66f451Sopenharmony_ci#define XZ_DEC_POWERPC
3140f66f451Sopenharmony_ci#define XZ_DEC_IA64
3150f66f451Sopenharmony_ci#define XZ_DEC_ARM
3160f66f451Sopenharmony_ci#define XZ_DEC_ARMTHUMB
3170f66f451Sopenharmony_ci#define XZ_DEC_SPARC
3180f66f451Sopenharmony_ci
3190f66f451Sopenharmony_ci
3200f66f451Sopenharmony_ci#define memeq(a, b, size) (memcmp(a, b, size) == 0)
3210f66f451Sopenharmony_ci
3220f66f451Sopenharmony_ci/* Inline functions to access unaligned unsigned 32-bit integers */
3230f66f451Sopenharmony_ci#ifndef get_unaligned_le32
3240f66f451Sopenharmony_cistatic inline uint32_t get_unaligned_le32(const uint8_t *buf)
3250f66f451Sopenharmony_ci{
3260f66f451Sopenharmony_ci  return (uint32_t)buf[0]
3270f66f451Sopenharmony_ci      | ((uint32_t)buf[1] << 8)
3280f66f451Sopenharmony_ci      | ((uint32_t)buf[2] << 16)
3290f66f451Sopenharmony_ci      | ((uint32_t)buf[3] << 24);
3300f66f451Sopenharmony_ci}
3310f66f451Sopenharmony_ci#endif
3320f66f451Sopenharmony_ci
3330f66f451Sopenharmony_ci#ifndef get_unaligned_be32
3340f66f451Sopenharmony_cistatic inline uint32_t get_unaligned_be32(const uint8_t *buf)
3350f66f451Sopenharmony_ci{
3360f66f451Sopenharmony_ci  return (uint32_t)(buf[0] << 24)
3370f66f451Sopenharmony_ci      | ((uint32_t)buf[1] << 16)
3380f66f451Sopenharmony_ci      | ((uint32_t)buf[2] << 8)
3390f66f451Sopenharmony_ci      | (uint32_t)buf[3];
3400f66f451Sopenharmony_ci}
3410f66f451Sopenharmony_ci#endif
3420f66f451Sopenharmony_ci
3430f66f451Sopenharmony_ci#ifndef put_unaligned_le32
3440f66f451Sopenharmony_cistatic inline void put_unaligned_le32(uint32_t val, uint8_t *buf)
3450f66f451Sopenharmony_ci{
3460f66f451Sopenharmony_ci  buf[0] = (uint8_t)val;
3470f66f451Sopenharmony_ci  buf[1] = (uint8_t)(val >> 8);
3480f66f451Sopenharmony_ci  buf[2] = (uint8_t)(val >> 16);
3490f66f451Sopenharmony_ci  buf[3] = (uint8_t)(val >> 24);
3500f66f451Sopenharmony_ci}
3510f66f451Sopenharmony_ci#endif
3520f66f451Sopenharmony_ci
3530f66f451Sopenharmony_ci#ifndef put_unaligned_be32
3540f66f451Sopenharmony_cistatic inline void put_unaligned_be32(uint32_t val, uint8_t *buf)
3550f66f451Sopenharmony_ci{
3560f66f451Sopenharmony_ci  buf[0] = (uint8_t)(val >> 24);
3570f66f451Sopenharmony_ci  buf[1] = (uint8_t)(val >> 16);
3580f66f451Sopenharmony_ci  buf[2] = (uint8_t)(val >> 8);
3590f66f451Sopenharmony_ci  buf[3] = (uint8_t)val;
3600f66f451Sopenharmony_ci}
3610f66f451Sopenharmony_ci#endif
3620f66f451Sopenharmony_ci
3630f66f451Sopenharmony_ci/*
3640f66f451Sopenharmony_ci * Use get_unaligned_le32() also for aligned access for simplicity. On
3650f66f451Sopenharmony_ci * little endian systems, #define get_le32(ptr) (*(const uint32_t *)(ptr))
3660f66f451Sopenharmony_ci * could save a few bytes in code size.
3670f66f451Sopenharmony_ci */
3680f66f451Sopenharmony_ci#ifndef get_le32
3690f66f451Sopenharmony_ci#	define get_le32 get_unaligned_le32
3700f66f451Sopenharmony_ci#endif
3710f66f451Sopenharmony_ci
3720f66f451Sopenharmony_ci/*
3730f66f451Sopenharmony_ci * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ.
3740f66f451Sopenharmony_ci * XZ_DEC_BCJ is used to enable generic support for BCJ decoders.
3750f66f451Sopenharmony_ci */
3760f66f451Sopenharmony_ci#ifndef XZ_DEC_BCJ
3770f66f451Sopenharmony_ci#	if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \
3780f66f451Sopenharmony_ci      || defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \
3790f66f451Sopenharmony_ci      || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \
3800f66f451Sopenharmony_ci      || defined(XZ_DEC_SPARC)
3810f66f451Sopenharmony_ci#		define XZ_DEC_BCJ
3820f66f451Sopenharmony_ci#	endif
3830f66f451Sopenharmony_ci#endif
3840f66f451Sopenharmony_ci
3850f66f451Sopenharmony_ci/*
3860f66f451Sopenharmony_ci * Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used
3870f66f451Sopenharmony_ci * before calling xz_dec_lzma2_run().
3880f66f451Sopenharmony_ci */
3890f66f451Sopenharmony_cistruct xz_dec_lzma2 *xz_dec_lzma2_create(uint32_t dict_max);
3900f66f451Sopenharmony_ci
3910f66f451Sopenharmony_ci/*
3920f66f451Sopenharmony_ci * Decode the LZMA2 properties (one byte) and reset the decoder. Return
3930f66f451Sopenharmony_ci * XZ_OK on success, XZ_MEMLIMIT_ERROR if the preallocated dictionary is not
3940f66f451Sopenharmony_ci * big enough, and XZ_OPTIONS_ERROR if props indicates something that this
3950f66f451Sopenharmony_ci * decoder doesn't support.
3960f66f451Sopenharmony_ci */
3970f66f451Sopenharmony_cienum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s,
3980f66f451Sopenharmony_ci           uint8_t props);
3990f66f451Sopenharmony_ci
4000f66f451Sopenharmony_ci/* Decode raw LZMA2 stream from b->in to b->out. */
4010f66f451Sopenharmony_cienum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
4020f66f451Sopenharmony_ci               struct xz_buf *b);
4030f66f451Sopenharmony_ci
4040f66f451Sopenharmony_ci// END "xz_private.h"
4050f66f451Sopenharmony_ci
4060f66f451Sopenharmony_ci
4070f66f451Sopenharmony_ci
4080f66f451Sopenharmony_ci
4090f66f451Sopenharmony_ci/*
4100f66f451Sopenharmony_ci * Branch/Call/Jump (BCJ) filter decoders
4110f66f451Sopenharmony_ci * The rest of the code is inside this ifdef. It makes things a little more
4120f66f451Sopenharmony_ci * convenient when building without support for any BCJ filters.
4130f66f451Sopenharmony_ci */
4140f66f451Sopenharmony_ci#ifdef XZ_DEC_BCJ
4150f66f451Sopenharmony_ci
4160f66f451Sopenharmony_cistruct xz_dec_bcj {
4170f66f451Sopenharmony_ci  /* Type of the BCJ filter being used */
4180f66f451Sopenharmony_ci  enum {
4190f66f451Sopenharmony_ci    BCJ_X86 = 4,        /* x86 or x86-64 */
4200f66f451Sopenharmony_ci    BCJ_POWERPC = 5,    /* Big endian only */
4210f66f451Sopenharmony_ci    BCJ_IA64 = 6,       /* Big or little endian */
4220f66f451Sopenharmony_ci    BCJ_ARM = 7,        /* Little endian only */
4230f66f451Sopenharmony_ci    BCJ_ARMTHUMB = 8,   /* Little endian only */
4240f66f451Sopenharmony_ci    BCJ_SPARC = 9       /* Big or little endian */
4250f66f451Sopenharmony_ci  } type;
4260f66f451Sopenharmony_ci
4270f66f451Sopenharmony_ci  /*
4280f66f451Sopenharmony_ci   * Return value of the next filter in the chain. We need to preserve
4290f66f451Sopenharmony_ci   * this information across calls, because we must not call the next
4300f66f451Sopenharmony_ci   * filter anymore once it has returned XZ_STREAM_END.
4310f66f451Sopenharmony_ci   */
4320f66f451Sopenharmony_ci  enum xz_ret ret;
4330f66f451Sopenharmony_ci
4340f66f451Sopenharmony_ci  /*
4350f66f451Sopenharmony_ci   * Absolute position relative to the beginning of the uncompressed
4360f66f451Sopenharmony_ci   * data (in a single .xz Block). We care only about the lowest 32
4370f66f451Sopenharmony_ci   * bits so this doesn't need to be uint64_t even with big files.
4380f66f451Sopenharmony_ci   */
4390f66f451Sopenharmony_ci  uint32_t pos;
4400f66f451Sopenharmony_ci
4410f66f451Sopenharmony_ci  /* x86 filter state */
4420f66f451Sopenharmony_ci  uint32_t x86_prev_mask;
4430f66f451Sopenharmony_ci
4440f66f451Sopenharmony_ci  /* Temporary space to hold the variables from struct xz_buf */
4450f66f451Sopenharmony_ci  uint8_t *out;
4460f66f451Sopenharmony_ci  size_t out_pos;
4470f66f451Sopenharmony_ci  size_t out_size;
4480f66f451Sopenharmony_ci
4490f66f451Sopenharmony_ci  struct {
4500f66f451Sopenharmony_ci    /* Amount of already filtered data in the beginning of buf */
4510f66f451Sopenharmony_ci    size_t filtered;
4520f66f451Sopenharmony_ci
4530f66f451Sopenharmony_ci    /* Total amount of data currently stored in buf  */
4540f66f451Sopenharmony_ci    size_t size;
4550f66f451Sopenharmony_ci
4560f66f451Sopenharmony_ci    /*
4570f66f451Sopenharmony_ci     * Buffer to hold a mix of filtered and unfiltered data. This
4580f66f451Sopenharmony_ci     * needs to be big enough to hold Alignment + 2 * Look-ahead:
4590f66f451Sopenharmony_ci     *
4600f66f451Sopenharmony_ci     * Type         Alignment   Look-ahead
4610f66f451Sopenharmony_ci     * x86              1           4
4620f66f451Sopenharmony_ci     * PowerPC          4           0
4630f66f451Sopenharmony_ci     * IA-64           16           0
4640f66f451Sopenharmony_ci     * ARM              4           0
4650f66f451Sopenharmony_ci     * ARM-Thumb        2           2
4660f66f451Sopenharmony_ci     * SPARC            4           0
4670f66f451Sopenharmony_ci     */
4680f66f451Sopenharmony_ci    uint8_t buf[16];
4690f66f451Sopenharmony_ci  } temp;
4700f66f451Sopenharmony_ci};
4710f66f451Sopenharmony_ci
4720f66f451Sopenharmony_ci/*
4730f66f451Sopenharmony_ci * Decode the Filter ID of a BCJ filter. This implementation doesn't
4740f66f451Sopenharmony_ci * support custom start offsets, so no decoding of Filter Properties
4750f66f451Sopenharmony_ci * is needed. Returns XZ_OK if the given Filter ID is supported.
4760f66f451Sopenharmony_ci * Otherwise XZ_OPTIONS_ERROR is returned.
4770f66f451Sopenharmony_ci */
4780f66f451Sopenharmony_cienum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id);
4790f66f451Sopenharmony_ci
4800f66f451Sopenharmony_ci/*
4810f66f451Sopenharmony_ci * Decode raw BCJ + LZMA2 stream. This must be used only if there actually is
4820f66f451Sopenharmony_ci * a BCJ filter in the chain. If the chain has only LZMA2, xz_dec_lzma2_run()
4830f66f451Sopenharmony_ci * must be called directly.
4840f66f451Sopenharmony_ci */
4850f66f451Sopenharmony_cienum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
4860f66f451Sopenharmony_ci             struct xz_dec_lzma2 *lzma2,
4870f66f451Sopenharmony_ci             struct xz_buf *b);
4880f66f451Sopenharmony_ci
4890f66f451Sopenharmony_ci#ifdef XZ_DEC_X86
4900f66f451Sopenharmony_ci/*
4910f66f451Sopenharmony_ci * This is used to test the most significant byte of a memory address
4920f66f451Sopenharmony_ci * in an x86 instruction.
4930f66f451Sopenharmony_ci */
4940f66f451Sopenharmony_cistatic inline int bcj_x86_test_msbyte(uint8_t b)
4950f66f451Sopenharmony_ci{
4960f66f451Sopenharmony_ci  return b == 0x00 || b == 0xFF;
4970f66f451Sopenharmony_ci}
4980f66f451Sopenharmony_ci
4990f66f451Sopenharmony_cistatic size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
5000f66f451Sopenharmony_ci{
5010f66f451Sopenharmony_ci  static const int mask_to_allowed_status[8]
5020f66f451Sopenharmony_ci    = { 1,1,1,0,1,0,0,0 };
5030f66f451Sopenharmony_ci
5040f66f451Sopenharmony_ci  static const uint8_t mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
5050f66f451Sopenharmony_ci
5060f66f451Sopenharmony_ci  size_t i;
5070f66f451Sopenharmony_ci  size_t prev_pos = (size_t)-1;
5080f66f451Sopenharmony_ci  uint32_t prev_mask = s->x86_prev_mask;
5090f66f451Sopenharmony_ci  uint32_t src;
5100f66f451Sopenharmony_ci  uint32_t dest;
5110f66f451Sopenharmony_ci  uint32_t j;
5120f66f451Sopenharmony_ci  uint8_t b;
5130f66f451Sopenharmony_ci
5140f66f451Sopenharmony_ci  if (size <= 4)
5150f66f451Sopenharmony_ci    return 0;
5160f66f451Sopenharmony_ci
5170f66f451Sopenharmony_ci  size -= 4;
5180f66f451Sopenharmony_ci  for (i = 0; i < size; ++i) {
5190f66f451Sopenharmony_ci    if ((buf[i] & 0xFE) != 0xE8)
5200f66f451Sopenharmony_ci      continue;
5210f66f451Sopenharmony_ci
5220f66f451Sopenharmony_ci    prev_pos = i - prev_pos;
5230f66f451Sopenharmony_ci    if (prev_pos > 3) {
5240f66f451Sopenharmony_ci      prev_mask = 0;
5250f66f451Sopenharmony_ci    } else {
5260f66f451Sopenharmony_ci      prev_mask = (prev_mask << (prev_pos - 1)) & 7;
5270f66f451Sopenharmony_ci      if (prev_mask != 0) {
5280f66f451Sopenharmony_ci        b = buf[i + 4 - mask_to_bit_num[prev_mask]];
5290f66f451Sopenharmony_ci        if (!mask_to_allowed_status[prev_mask]
5300f66f451Sopenharmony_ci            || bcj_x86_test_msbyte(b)) {
5310f66f451Sopenharmony_ci          prev_pos = i;
5320f66f451Sopenharmony_ci          prev_mask = (prev_mask << 1) | 1;
5330f66f451Sopenharmony_ci          continue;
5340f66f451Sopenharmony_ci        }
5350f66f451Sopenharmony_ci      }
5360f66f451Sopenharmony_ci    }
5370f66f451Sopenharmony_ci
5380f66f451Sopenharmony_ci    prev_pos = i;
5390f66f451Sopenharmony_ci
5400f66f451Sopenharmony_ci    if (bcj_x86_test_msbyte(buf[i + 4])) {
5410f66f451Sopenharmony_ci      src = get_unaligned_le32(buf + i + 1);
5420f66f451Sopenharmony_ci      for (;;) {
5430f66f451Sopenharmony_ci        dest = src - (s->pos + (uint32_t)i + 5);
5440f66f451Sopenharmony_ci        if (prev_mask == 0)
5450f66f451Sopenharmony_ci          break;
5460f66f451Sopenharmony_ci
5470f66f451Sopenharmony_ci        j = mask_to_bit_num[prev_mask] * 8;
5480f66f451Sopenharmony_ci        b = (uint8_t)(dest >> (24 - j));
5490f66f451Sopenharmony_ci        if (!bcj_x86_test_msbyte(b))
5500f66f451Sopenharmony_ci          break;
5510f66f451Sopenharmony_ci
5520f66f451Sopenharmony_ci        src = dest ^ (((uint32_t)1 << (32 - j)) - 1);
5530f66f451Sopenharmony_ci      }
5540f66f451Sopenharmony_ci
5550f66f451Sopenharmony_ci      dest &= 0x01FFFFFF;
5560f66f451Sopenharmony_ci      dest |= (uint32_t)0 - (dest & 0x01000000);
5570f66f451Sopenharmony_ci      put_unaligned_le32(dest, buf + i + 1);
5580f66f451Sopenharmony_ci      i += 4;
5590f66f451Sopenharmony_ci    } else {
5600f66f451Sopenharmony_ci      prev_mask = (prev_mask << 1) | 1;
5610f66f451Sopenharmony_ci    }
5620f66f451Sopenharmony_ci  }
5630f66f451Sopenharmony_ci
5640f66f451Sopenharmony_ci  prev_pos = i - prev_pos;
5650f66f451Sopenharmony_ci  s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1);
5660f66f451Sopenharmony_ci  return i;
5670f66f451Sopenharmony_ci}
5680f66f451Sopenharmony_ci#endif
5690f66f451Sopenharmony_ci
5700f66f451Sopenharmony_ci#ifdef XZ_DEC_POWERPC
5710f66f451Sopenharmony_cistatic size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
5720f66f451Sopenharmony_ci{
5730f66f451Sopenharmony_ci  size_t i;
5740f66f451Sopenharmony_ci  uint32_t instr;
5750f66f451Sopenharmony_ci
5760f66f451Sopenharmony_ci  for (i = 0; i + 4 <= size; i += 4) {
5770f66f451Sopenharmony_ci    instr = get_unaligned_be32(buf + i);
5780f66f451Sopenharmony_ci    if ((instr & 0xFC000003) == 0x48000001) {
5790f66f451Sopenharmony_ci      instr &= 0x03FFFFFC;
5800f66f451Sopenharmony_ci      instr -= s->pos + (uint32_t)i;
5810f66f451Sopenharmony_ci      instr &= 0x03FFFFFC;
5820f66f451Sopenharmony_ci      instr |= 0x48000001;
5830f66f451Sopenharmony_ci      put_unaligned_be32(instr, buf + i);
5840f66f451Sopenharmony_ci    }
5850f66f451Sopenharmony_ci  }
5860f66f451Sopenharmony_ci
5870f66f451Sopenharmony_ci  return i;
5880f66f451Sopenharmony_ci}
5890f66f451Sopenharmony_ci#endif
5900f66f451Sopenharmony_ci
5910f66f451Sopenharmony_ci#ifdef XZ_DEC_IA64
5920f66f451Sopenharmony_cistatic size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
5930f66f451Sopenharmony_ci{
5940f66f451Sopenharmony_ci  static const uint8_t branch_table[32] = {
5950f66f451Sopenharmony_ci    0, 0, 0, 0, 0, 0, 0, 0,
5960f66f451Sopenharmony_ci    0, 0, 0, 0, 0, 0, 0, 0,
5970f66f451Sopenharmony_ci    4, 4, 6, 6, 0, 0, 7, 7,
5980f66f451Sopenharmony_ci    4, 4, 0, 0, 4, 4, 0, 0
5990f66f451Sopenharmony_ci  };
6000f66f451Sopenharmony_ci
6010f66f451Sopenharmony_ci  /*
6020f66f451Sopenharmony_ci   * The local variables take a little bit stack space, but it's less
6030f66f451Sopenharmony_ci   * than what LZMA2 decoder takes, so it doesn't make sense to reduce
6040f66f451Sopenharmony_ci   * stack usage here without doing that for the LZMA2 decoder too.
6050f66f451Sopenharmony_ci   */
6060f66f451Sopenharmony_ci
6070f66f451Sopenharmony_ci  /* Loop counters */
6080f66f451Sopenharmony_ci  size_t i;
6090f66f451Sopenharmony_ci  size_t j;
6100f66f451Sopenharmony_ci
6110f66f451Sopenharmony_ci  /* Instruction slot (0, 1, or 2) in the 128-bit instruction word */
6120f66f451Sopenharmony_ci  uint32_t slot;
6130f66f451Sopenharmony_ci
6140f66f451Sopenharmony_ci  /* Bitwise offset of the instruction indicated by slot */
6150f66f451Sopenharmony_ci  uint32_t bit_pos;
6160f66f451Sopenharmony_ci
6170f66f451Sopenharmony_ci  /* bit_pos split into byte and bit parts */
6180f66f451Sopenharmony_ci  uint32_t byte_pos;
6190f66f451Sopenharmony_ci  uint32_t bit_res;
6200f66f451Sopenharmony_ci
6210f66f451Sopenharmony_ci  /* Address part of an instruction */
6220f66f451Sopenharmony_ci  uint32_t addr;
6230f66f451Sopenharmony_ci
6240f66f451Sopenharmony_ci  /* Mask used to detect which instructions to convert */
6250f66f451Sopenharmony_ci  uint32_t mask;
6260f66f451Sopenharmony_ci
6270f66f451Sopenharmony_ci  /* 41-bit instruction stored somewhere in the lowest 48 bits */
6280f66f451Sopenharmony_ci  uint64_t instr;
6290f66f451Sopenharmony_ci
6300f66f451Sopenharmony_ci  /* Instruction normalized with bit_res for easier manipulation */
6310f66f451Sopenharmony_ci  uint64_t norm;
6320f66f451Sopenharmony_ci
6330f66f451Sopenharmony_ci  for (i = 0; i + 16 <= size; i += 16) {
6340f66f451Sopenharmony_ci    mask = branch_table[buf[i] & 0x1F];
6350f66f451Sopenharmony_ci    for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) {
6360f66f451Sopenharmony_ci      if (((mask >> slot) & 1) == 0)
6370f66f451Sopenharmony_ci        continue;
6380f66f451Sopenharmony_ci
6390f66f451Sopenharmony_ci      byte_pos = bit_pos >> 3;
6400f66f451Sopenharmony_ci      bit_res = bit_pos & 7;
6410f66f451Sopenharmony_ci      instr = 0;
6420f66f451Sopenharmony_ci      for (j = 0; j < 6; ++j)
6430f66f451Sopenharmony_ci        instr |= (uint64_t)(buf[i + j + byte_pos])
6440f66f451Sopenharmony_ci            << (8 * j);
6450f66f451Sopenharmony_ci
6460f66f451Sopenharmony_ci      norm = instr >> bit_res;
6470f66f451Sopenharmony_ci
6480f66f451Sopenharmony_ci      if (((norm >> 37) & 0x0F) == 0x05
6490f66f451Sopenharmony_ci          && ((norm >> 9) & 0x07) == 0) {
6500f66f451Sopenharmony_ci        addr = (norm >> 13) & 0x0FFFFF;
6510f66f451Sopenharmony_ci        addr |= ((uint32_t)(norm >> 36) & 1) << 20;
6520f66f451Sopenharmony_ci        addr <<= 4;
6530f66f451Sopenharmony_ci        addr -= s->pos + (uint32_t)i;
6540f66f451Sopenharmony_ci        addr >>= 4;
6550f66f451Sopenharmony_ci
6560f66f451Sopenharmony_ci        norm &= ~((uint64_t)0x8FFFFF << 13);
6570f66f451Sopenharmony_ci        norm |= (uint64_t)(addr & 0x0FFFFF) << 13;
6580f66f451Sopenharmony_ci        norm |= (uint64_t)(addr & 0x100000)
6590f66f451Sopenharmony_ci            << (36 - 20);
6600f66f451Sopenharmony_ci
6610f66f451Sopenharmony_ci        instr &= (1 << bit_res) - 1;
6620f66f451Sopenharmony_ci        instr |= norm << bit_res;
6630f66f451Sopenharmony_ci
6640f66f451Sopenharmony_ci        for (j = 0; j < 6; j++)
6650f66f451Sopenharmony_ci          buf[i + j + byte_pos]
6660f66f451Sopenharmony_ci            = (uint8_t)(instr >> (8 * j));
6670f66f451Sopenharmony_ci      }
6680f66f451Sopenharmony_ci    }
6690f66f451Sopenharmony_ci  }
6700f66f451Sopenharmony_ci
6710f66f451Sopenharmony_ci  return i;
6720f66f451Sopenharmony_ci}
6730f66f451Sopenharmony_ci#endif
6740f66f451Sopenharmony_ci
6750f66f451Sopenharmony_ci#ifdef XZ_DEC_ARM
6760f66f451Sopenharmony_cistatic size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
6770f66f451Sopenharmony_ci{
6780f66f451Sopenharmony_ci  size_t i;
6790f66f451Sopenharmony_ci  uint32_t addr;
6800f66f451Sopenharmony_ci
6810f66f451Sopenharmony_ci  for (i = 0; i + 4 <= size; i += 4) {
6820f66f451Sopenharmony_ci    if (buf[i + 3] == 0xEB) {
6830f66f451Sopenharmony_ci      addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
6840f66f451Sopenharmony_ci          | ((uint32_t)buf[i + 2] << 16);
6850f66f451Sopenharmony_ci      addr <<= 2;
6860f66f451Sopenharmony_ci      addr -= s->pos + (uint32_t)i + 8;
6870f66f451Sopenharmony_ci      addr >>= 2;
6880f66f451Sopenharmony_ci      buf[i] = (uint8_t)addr;
6890f66f451Sopenharmony_ci      buf[i + 1] = (uint8_t)(addr >> 8);
6900f66f451Sopenharmony_ci      buf[i + 2] = (uint8_t)(addr >> 16);
6910f66f451Sopenharmony_ci    }
6920f66f451Sopenharmony_ci  }
6930f66f451Sopenharmony_ci
6940f66f451Sopenharmony_ci  return i;
6950f66f451Sopenharmony_ci}
6960f66f451Sopenharmony_ci#endif
6970f66f451Sopenharmony_ci
6980f66f451Sopenharmony_ci#ifdef XZ_DEC_ARMTHUMB
6990f66f451Sopenharmony_cistatic size_t bcj_armthumb(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
7000f66f451Sopenharmony_ci{
7010f66f451Sopenharmony_ci  size_t i;
7020f66f451Sopenharmony_ci  uint32_t addr;
7030f66f451Sopenharmony_ci
7040f66f451Sopenharmony_ci  for (i = 0; i + 4 <= size; i += 2) {
7050f66f451Sopenharmony_ci    if ((buf[i + 1] & 0xF8) == 0xF0
7060f66f451Sopenharmony_ci        && (buf[i + 3] & 0xF8) == 0xF8) {
7070f66f451Sopenharmony_ci      addr = (((uint32_t)buf[i + 1] & 0x07) << 19)
7080f66f451Sopenharmony_ci          | ((uint32_t)buf[i] << 11)
7090f66f451Sopenharmony_ci          | (((uint32_t)buf[i + 3] & 0x07) << 8)
7100f66f451Sopenharmony_ci          | (uint32_t)buf[i + 2];
7110f66f451Sopenharmony_ci      addr <<= 1;
7120f66f451Sopenharmony_ci      addr -= s->pos + (uint32_t)i + 4;
7130f66f451Sopenharmony_ci      addr >>= 1;
7140f66f451Sopenharmony_ci      buf[i + 1] = (uint8_t)(0xF0 | ((addr >> 19) & 0x07));
7150f66f451Sopenharmony_ci      buf[i] = (uint8_t)(addr >> 11);
7160f66f451Sopenharmony_ci      buf[i + 3] = (uint8_t)(0xF8 | ((addr >> 8) & 0x07));
7170f66f451Sopenharmony_ci      buf[i + 2] = (uint8_t)addr;
7180f66f451Sopenharmony_ci      i += 2;
7190f66f451Sopenharmony_ci    }
7200f66f451Sopenharmony_ci  }
7210f66f451Sopenharmony_ci
7220f66f451Sopenharmony_ci  return i;
7230f66f451Sopenharmony_ci}
7240f66f451Sopenharmony_ci#endif
7250f66f451Sopenharmony_ci
7260f66f451Sopenharmony_ci#ifdef XZ_DEC_SPARC
7270f66f451Sopenharmony_cistatic size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
7280f66f451Sopenharmony_ci{
7290f66f451Sopenharmony_ci  size_t i;
7300f66f451Sopenharmony_ci  uint32_t instr;
7310f66f451Sopenharmony_ci
7320f66f451Sopenharmony_ci  for (i = 0; i + 4 <= size; i += 4) {
7330f66f451Sopenharmony_ci    instr = get_unaligned_be32(buf + i);
7340f66f451Sopenharmony_ci    if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
7350f66f451Sopenharmony_ci      instr <<= 2;
7360f66f451Sopenharmony_ci      instr -= s->pos + (uint32_t)i;
7370f66f451Sopenharmony_ci      instr >>= 2;
7380f66f451Sopenharmony_ci      instr = ((uint32_t)0x40000000 - (instr & 0x400000))
7390f66f451Sopenharmony_ci          | 0x40000000 | (instr & 0x3FFFFF);
7400f66f451Sopenharmony_ci      put_unaligned_be32(instr, buf + i);
7410f66f451Sopenharmony_ci    }
7420f66f451Sopenharmony_ci  }
7430f66f451Sopenharmony_ci
7440f66f451Sopenharmony_ci  return i;
7450f66f451Sopenharmony_ci}
7460f66f451Sopenharmony_ci#endif
7470f66f451Sopenharmony_ci
7480f66f451Sopenharmony_ci/*
7490f66f451Sopenharmony_ci * Apply the selected BCJ filter. Update *pos and s->pos to match the amount
7500f66f451Sopenharmony_ci * of data that got filtered.
7510f66f451Sopenharmony_ci *
7520f66f451Sopenharmony_ci * NOTE: This is implemented as a switch statement to avoid using function
7530f66f451Sopenharmony_ci * pointers, which could be problematic in the kernel boot code, which must
7540f66f451Sopenharmony_ci * avoid pointers to static data (at least on x86).
7550f66f451Sopenharmony_ci */
7560f66f451Sopenharmony_cistatic void bcj_apply(struct xz_dec_bcj *s,
7570f66f451Sopenharmony_ci          uint8_t *buf, size_t *pos, size_t size)
7580f66f451Sopenharmony_ci{
7590f66f451Sopenharmony_ci  size_t filtered;
7600f66f451Sopenharmony_ci
7610f66f451Sopenharmony_ci  buf += *pos;
7620f66f451Sopenharmony_ci  size -= *pos;
7630f66f451Sopenharmony_ci
7640f66f451Sopenharmony_ci  switch (s->type) {
7650f66f451Sopenharmony_ci#ifdef XZ_DEC_X86
7660f66f451Sopenharmony_ci  case BCJ_X86:
7670f66f451Sopenharmony_ci    filtered = bcj_x86(s, buf, size);
7680f66f451Sopenharmony_ci    break;
7690f66f451Sopenharmony_ci#endif
7700f66f451Sopenharmony_ci#ifdef XZ_DEC_POWERPC
7710f66f451Sopenharmony_ci  case BCJ_POWERPC:
7720f66f451Sopenharmony_ci    filtered = bcj_powerpc(s, buf, size);
7730f66f451Sopenharmony_ci    break;
7740f66f451Sopenharmony_ci#endif
7750f66f451Sopenharmony_ci#ifdef XZ_DEC_IA64
7760f66f451Sopenharmony_ci  case BCJ_IA64:
7770f66f451Sopenharmony_ci    filtered = bcj_ia64(s, buf, size);
7780f66f451Sopenharmony_ci    break;
7790f66f451Sopenharmony_ci#endif
7800f66f451Sopenharmony_ci#ifdef XZ_DEC_ARM
7810f66f451Sopenharmony_ci  case BCJ_ARM:
7820f66f451Sopenharmony_ci    filtered = bcj_arm(s, buf, size);
7830f66f451Sopenharmony_ci    break;
7840f66f451Sopenharmony_ci#endif
7850f66f451Sopenharmony_ci#ifdef XZ_DEC_ARMTHUMB
7860f66f451Sopenharmony_ci  case BCJ_ARMTHUMB:
7870f66f451Sopenharmony_ci    filtered = bcj_armthumb(s, buf, size);
7880f66f451Sopenharmony_ci    break;
7890f66f451Sopenharmony_ci#endif
7900f66f451Sopenharmony_ci#ifdef XZ_DEC_SPARC
7910f66f451Sopenharmony_ci  case BCJ_SPARC:
7920f66f451Sopenharmony_ci    filtered = bcj_sparc(s, buf, size);
7930f66f451Sopenharmony_ci    break;
7940f66f451Sopenharmony_ci#endif
7950f66f451Sopenharmony_ci  default:
7960f66f451Sopenharmony_ci    /* Never reached but silence compiler warnings. */
7970f66f451Sopenharmony_ci    filtered = 0;
7980f66f451Sopenharmony_ci    break;
7990f66f451Sopenharmony_ci  }
8000f66f451Sopenharmony_ci
8010f66f451Sopenharmony_ci  *pos += filtered;
8020f66f451Sopenharmony_ci  s->pos += filtered;
8030f66f451Sopenharmony_ci}
8040f66f451Sopenharmony_ci
8050f66f451Sopenharmony_ci/*
8060f66f451Sopenharmony_ci * Flush pending filtered data from temp to the output buffer.
8070f66f451Sopenharmony_ci * Move the remaining mixture of possibly filtered and unfiltered
8080f66f451Sopenharmony_ci * data to the beginning of temp.
8090f66f451Sopenharmony_ci */
8100f66f451Sopenharmony_cistatic void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b)
8110f66f451Sopenharmony_ci{
8120f66f451Sopenharmony_ci  size_t copy_size;
8130f66f451Sopenharmony_ci
8140f66f451Sopenharmony_ci  copy_size = minof(s->temp.filtered, b->out_size - b->out_pos);
8150f66f451Sopenharmony_ci  memcpy(b->out + b->out_pos, s->temp.buf, copy_size);
8160f66f451Sopenharmony_ci  b->out_pos += copy_size;
8170f66f451Sopenharmony_ci
8180f66f451Sopenharmony_ci  s->temp.filtered -= copy_size;
8190f66f451Sopenharmony_ci  s->temp.size -= copy_size;
8200f66f451Sopenharmony_ci  memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size);
8210f66f451Sopenharmony_ci}
8220f66f451Sopenharmony_ci
8230f66f451Sopenharmony_ci/*
8240f66f451Sopenharmony_ci * The BCJ filter functions are primitive in sense that they process the
8250f66f451Sopenharmony_ci * data in chunks of 1-16 bytes. To hide this issue, this function does
8260f66f451Sopenharmony_ci * some buffering.
8270f66f451Sopenharmony_ci */
8280f66f451Sopenharmony_cienum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
8290f66f451Sopenharmony_ci             struct xz_dec_lzma2 *lzma2,
8300f66f451Sopenharmony_ci             struct xz_buf *b)
8310f66f451Sopenharmony_ci{
8320f66f451Sopenharmony_ci  size_t out_start;
8330f66f451Sopenharmony_ci
8340f66f451Sopenharmony_ci  /*
8350f66f451Sopenharmony_ci   * Flush pending already filtered data to the output buffer. Return
8360f66f451Sopenharmony_ci   * immediatelly if we couldn't flush everything, or if the next
8370f66f451Sopenharmony_ci   * filter in the chain had already returned XZ_STREAM_END.
8380f66f451Sopenharmony_ci   */
8390f66f451Sopenharmony_ci  if (s->temp.filtered > 0) {
8400f66f451Sopenharmony_ci    bcj_flush(s, b);
8410f66f451Sopenharmony_ci    if (s->temp.filtered > 0)
8420f66f451Sopenharmony_ci      return XZ_OK;
8430f66f451Sopenharmony_ci
8440f66f451Sopenharmony_ci    if (s->ret == XZ_STREAM_END)
8450f66f451Sopenharmony_ci      return XZ_STREAM_END;
8460f66f451Sopenharmony_ci  }
8470f66f451Sopenharmony_ci
8480f66f451Sopenharmony_ci  /*
8490f66f451Sopenharmony_ci   * If we have more output space than what is currently pending in
8500f66f451Sopenharmony_ci   * temp, copy the unfiltered data from temp to the output buffer
8510f66f451Sopenharmony_ci   * and try to fill the output buffer by decoding more data from the
8520f66f451Sopenharmony_ci   * next filter in the chain. Apply the BCJ filter on the new data
8530f66f451Sopenharmony_ci   * in the output buffer. If everything cannot be filtered, copy it
8540f66f451Sopenharmony_ci   * to temp and rewind the output buffer position accordingly.
8550f66f451Sopenharmony_ci   *
8560f66f451Sopenharmony_ci   * This needs to be always run when temp.size == 0 to handle a special
8570f66f451Sopenharmony_ci   * case where the output buffer is full and the next filter has no
8580f66f451Sopenharmony_ci   * more output coming but hasn't returned XZ_STREAM_END yet.
8590f66f451Sopenharmony_ci   */
8600f66f451Sopenharmony_ci  if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
8610f66f451Sopenharmony_ci    out_start = b->out_pos;
8620f66f451Sopenharmony_ci    memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
8630f66f451Sopenharmony_ci    b->out_pos += s->temp.size;
8640f66f451Sopenharmony_ci
8650f66f451Sopenharmony_ci    s->ret = xz_dec_lzma2_run(lzma2, b);
8660f66f451Sopenharmony_ci    if (s->ret != XZ_STREAM_END
8670f66f451Sopenharmony_ci        && (s->ret != XZ_OK ))
8680f66f451Sopenharmony_ci      return s->ret;
8690f66f451Sopenharmony_ci
8700f66f451Sopenharmony_ci    bcj_apply(s, b->out, &out_start, b->out_pos);
8710f66f451Sopenharmony_ci
8720f66f451Sopenharmony_ci    /*
8730f66f451Sopenharmony_ci     * As an exception, if the next filter returned XZ_STREAM_END,
8740f66f451Sopenharmony_ci     * we can do that too, since the last few bytes that remain
8750f66f451Sopenharmony_ci     * unfiltered are meant to remain unfiltered.
8760f66f451Sopenharmony_ci     */
8770f66f451Sopenharmony_ci    if (s->ret == XZ_STREAM_END)
8780f66f451Sopenharmony_ci      return XZ_STREAM_END;
8790f66f451Sopenharmony_ci
8800f66f451Sopenharmony_ci    s->temp.size = b->out_pos - out_start;
8810f66f451Sopenharmony_ci    b->out_pos -= s->temp.size;
8820f66f451Sopenharmony_ci    memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
8830f66f451Sopenharmony_ci
8840f66f451Sopenharmony_ci    /*
8850f66f451Sopenharmony_ci     * If there wasn't enough input to the next filter to fill
8860f66f451Sopenharmony_ci     * the output buffer with unfiltered data, there's no point
8870f66f451Sopenharmony_ci     * to try decoding more data to temp.
8880f66f451Sopenharmony_ci     */
8890f66f451Sopenharmony_ci    if (b->out_pos + s->temp.size < b->out_size)
8900f66f451Sopenharmony_ci      return XZ_OK;
8910f66f451Sopenharmony_ci  }
8920f66f451Sopenharmony_ci
8930f66f451Sopenharmony_ci  /*
8940f66f451Sopenharmony_ci   * We have unfiltered data in temp. If the output buffer isn't full
8950f66f451Sopenharmony_ci   * yet, try to fill the temp buffer by decoding more data from the
8960f66f451Sopenharmony_ci   * next filter. Apply the BCJ filter on temp. Then we hopefully can
8970f66f451Sopenharmony_ci   * fill the actual output buffer by copying filtered data from temp.
8980f66f451Sopenharmony_ci   * A mix of filtered and unfiltered data may be left in temp; it will
8990f66f451Sopenharmony_ci   * be taken care on the next call to this function.
9000f66f451Sopenharmony_ci   */
9010f66f451Sopenharmony_ci  if (b->out_pos < b->out_size) {
9020f66f451Sopenharmony_ci    /* Make b->out{,_pos,_size} temporarily point to s->temp. */
9030f66f451Sopenharmony_ci    s->out = b->out;
9040f66f451Sopenharmony_ci    s->out_pos = b->out_pos;
9050f66f451Sopenharmony_ci    s->out_size = b->out_size;
9060f66f451Sopenharmony_ci    b->out = s->temp.buf;
9070f66f451Sopenharmony_ci    b->out_pos = s->temp.size;
9080f66f451Sopenharmony_ci    b->out_size = sizeof(s->temp.buf);
9090f66f451Sopenharmony_ci
9100f66f451Sopenharmony_ci    s->ret = xz_dec_lzma2_run(lzma2, b);
9110f66f451Sopenharmony_ci
9120f66f451Sopenharmony_ci    s->temp.size = b->out_pos;
9130f66f451Sopenharmony_ci    b->out = s->out;
9140f66f451Sopenharmony_ci    b->out_pos = s->out_pos;
9150f66f451Sopenharmony_ci    b->out_size = s->out_size;
9160f66f451Sopenharmony_ci
9170f66f451Sopenharmony_ci    if (s->ret != XZ_OK && s->ret != XZ_STREAM_END)
9180f66f451Sopenharmony_ci      return s->ret;
9190f66f451Sopenharmony_ci
9200f66f451Sopenharmony_ci    bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size);
9210f66f451Sopenharmony_ci
9220f66f451Sopenharmony_ci    /*
9230f66f451Sopenharmony_ci     * If the next filter returned XZ_STREAM_END, we mark that
9240f66f451Sopenharmony_ci     * everything is filtered, since the last unfiltered bytes
9250f66f451Sopenharmony_ci     * of the stream are meant to be left as is.
9260f66f451Sopenharmony_ci     */
9270f66f451Sopenharmony_ci    if (s->ret == XZ_STREAM_END)
9280f66f451Sopenharmony_ci      s->temp.filtered = s->temp.size;
9290f66f451Sopenharmony_ci
9300f66f451Sopenharmony_ci    bcj_flush(s, b);
9310f66f451Sopenharmony_ci    if (s->temp.filtered > 0)
9320f66f451Sopenharmony_ci      return XZ_OK;
9330f66f451Sopenharmony_ci  }
9340f66f451Sopenharmony_ci
9350f66f451Sopenharmony_ci  return s->ret;
9360f66f451Sopenharmony_ci}
9370f66f451Sopenharmony_ci
9380f66f451Sopenharmony_cienum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
9390f66f451Sopenharmony_ci{
9400f66f451Sopenharmony_ci  switch (id) {
9410f66f451Sopenharmony_ci#ifdef XZ_DEC_X86
9420f66f451Sopenharmony_ci  case BCJ_X86:
9430f66f451Sopenharmony_ci#endif
9440f66f451Sopenharmony_ci#ifdef XZ_DEC_POWERPC
9450f66f451Sopenharmony_ci  case BCJ_POWERPC:
9460f66f451Sopenharmony_ci#endif
9470f66f451Sopenharmony_ci#ifdef XZ_DEC_IA64
9480f66f451Sopenharmony_ci  case BCJ_IA64:
9490f66f451Sopenharmony_ci#endif
9500f66f451Sopenharmony_ci#ifdef XZ_DEC_ARM
9510f66f451Sopenharmony_ci  case BCJ_ARM:
9520f66f451Sopenharmony_ci#endif
9530f66f451Sopenharmony_ci#ifdef XZ_DEC_ARMTHUMB
9540f66f451Sopenharmony_ci  case BCJ_ARMTHUMB:
9550f66f451Sopenharmony_ci#endif
9560f66f451Sopenharmony_ci#ifdef XZ_DEC_SPARC
9570f66f451Sopenharmony_ci  case BCJ_SPARC:
9580f66f451Sopenharmony_ci#endif
9590f66f451Sopenharmony_ci    break;
9600f66f451Sopenharmony_ci
9610f66f451Sopenharmony_ci  default:
9620f66f451Sopenharmony_ci    /* Unsupported Filter ID */
9630f66f451Sopenharmony_ci    return XZ_OPTIONS_ERROR;
9640f66f451Sopenharmony_ci  }
9650f66f451Sopenharmony_ci
9660f66f451Sopenharmony_ci  s->type = id;
9670f66f451Sopenharmony_ci  s->ret = XZ_OK;
9680f66f451Sopenharmony_ci  s->pos = 0;
9690f66f451Sopenharmony_ci  s->x86_prev_mask = 0;
9700f66f451Sopenharmony_ci  s->temp.filtered = 0;
9710f66f451Sopenharmony_ci  s->temp.size = 0;
9720f66f451Sopenharmony_ci
9730f66f451Sopenharmony_ci  return XZ_OK;
9740f66f451Sopenharmony_ci}
9750f66f451Sopenharmony_ci
9760f66f451Sopenharmony_ci#endif
9770f66f451Sopenharmony_ci/*
9780f66f451Sopenharmony_ci * LZMA2 decoder
9790f66f451Sopenharmony_ci */
9800f66f451Sopenharmony_ci
9810f66f451Sopenharmony_ci
9820f66f451Sopenharmony_ci// BEGIN xz_lzma2.h
9830f66f451Sopenharmony_ci/*
9840f66f451Sopenharmony_ci * LZMA2 definitions
9850f66f451Sopenharmony_ci *
9860f66f451Sopenharmony_ci */
9870f66f451Sopenharmony_ci
9880f66f451Sopenharmony_ci
9890f66f451Sopenharmony_ci/* Range coder constants */
9900f66f451Sopenharmony_ci#define RC_SHIFT_BITS 8
9910f66f451Sopenharmony_ci#define RC_TOP_BITS 24
9920f66f451Sopenharmony_ci#define RC_TOP_VALUE (1 << RC_TOP_BITS)
9930f66f451Sopenharmony_ci#define RC_BIT_MODEL_TOTAL_BITS 11
9940f66f451Sopenharmony_ci#define RC_BIT_MODEL_TOTAL (1 << RC_BIT_MODEL_TOTAL_BITS)
9950f66f451Sopenharmony_ci#define RC_MOVE_BITS 5
9960f66f451Sopenharmony_ci
9970f66f451Sopenharmony_ci/*
9980f66f451Sopenharmony_ci * Maximum number of position states. A position state is the lowest pb
9990f66f451Sopenharmony_ci * number of bits of the current uncompressed offset. In some places there
10000f66f451Sopenharmony_ci * are different sets of probabilities for different position states.
10010f66f451Sopenharmony_ci */
10020f66f451Sopenharmony_ci#define POS_STATES_MAX (1 << 4)
10030f66f451Sopenharmony_ci
10040f66f451Sopenharmony_ci/*
10050f66f451Sopenharmony_ci * This enum is used to track which LZMA symbols have occurred most recently
10060f66f451Sopenharmony_ci * and in which order. This information is used to predict the next symbol.
10070f66f451Sopenharmony_ci *
10080f66f451Sopenharmony_ci * Symbols:
10090f66f451Sopenharmony_ci *  - Literal: One 8-bit byte
10100f66f451Sopenharmony_ci *  - Match: Repeat a chunk of data at some distance
10110f66f451Sopenharmony_ci *  - Long repeat: Multi-byte match at a recently seen distance
10120f66f451Sopenharmony_ci *  - Short repeat: One-byte repeat at a recently seen distance
10130f66f451Sopenharmony_ci *
10140f66f451Sopenharmony_ci * The symbol names are in from STATE_oldest_older_previous. REP means
10150f66f451Sopenharmony_ci * either short or long repeated match, and NONLIT means any non-literal.
10160f66f451Sopenharmony_ci */
10170f66f451Sopenharmony_cienum lzma_state {
10180f66f451Sopenharmony_ci  STATE_LIT_LIT,
10190f66f451Sopenharmony_ci  STATE_MATCH_LIT_LIT,
10200f66f451Sopenharmony_ci  STATE_REP_LIT_LIT,
10210f66f451Sopenharmony_ci  STATE_SHORTREP_LIT_LIT,
10220f66f451Sopenharmony_ci  STATE_MATCH_LIT,
10230f66f451Sopenharmony_ci  STATE_REP_LIT,
10240f66f451Sopenharmony_ci  STATE_SHORTREP_LIT,
10250f66f451Sopenharmony_ci  STATE_LIT_MATCH,
10260f66f451Sopenharmony_ci  STATE_LIT_LONGREP,
10270f66f451Sopenharmony_ci  STATE_LIT_SHORTREP,
10280f66f451Sopenharmony_ci  STATE_NONLIT_MATCH,
10290f66f451Sopenharmony_ci  STATE_NONLIT_REP
10300f66f451Sopenharmony_ci};
10310f66f451Sopenharmony_ci
10320f66f451Sopenharmony_ci/* Total number of states */
10330f66f451Sopenharmony_ci#define STATES 12
10340f66f451Sopenharmony_ci
10350f66f451Sopenharmony_ci/* The lowest 7 states indicate that the previous state was a literal. */
10360f66f451Sopenharmony_ci#define LIT_STATES 7
10370f66f451Sopenharmony_ci
10380f66f451Sopenharmony_ci/* Indicate that the latest symbol was a literal. */
10390f66f451Sopenharmony_cistatic inline void lzma_state_literal(enum lzma_state *state)
10400f66f451Sopenharmony_ci{
10410f66f451Sopenharmony_ci  if (*state <= STATE_SHORTREP_LIT_LIT)
10420f66f451Sopenharmony_ci    *state = STATE_LIT_LIT;
10430f66f451Sopenharmony_ci  else if (*state <= STATE_LIT_SHORTREP)
10440f66f451Sopenharmony_ci    *state -= 3;
10450f66f451Sopenharmony_ci  else
10460f66f451Sopenharmony_ci    *state -= 6;
10470f66f451Sopenharmony_ci}
10480f66f451Sopenharmony_ci
10490f66f451Sopenharmony_ci/* Indicate that the latest symbol was a match. */
10500f66f451Sopenharmony_cistatic inline void lzma_state_match(enum lzma_state *state)
10510f66f451Sopenharmony_ci{
10520f66f451Sopenharmony_ci  *state = *state < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH;
10530f66f451Sopenharmony_ci}
10540f66f451Sopenharmony_ci
10550f66f451Sopenharmony_ci/* Indicate that the latest state was a long repeated match. */
10560f66f451Sopenharmony_cistatic inline void lzma_state_long_rep(enum lzma_state *state)
10570f66f451Sopenharmony_ci{
10580f66f451Sopenharmony_ci  *state = *state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP;
10590f66f451Sopenharmony_ci}
10600f66f451Sopenharmony_ci
10610f66f451Sopenharmony_ci/* Indicate that the latest symbol was a short match. */
10620f66f451Sopenharmony_cistatic inline void lzma_state_short_rep(enum lzma_state *state)
10630f66f451Sopenharmony_ci{
10640f66f451Sopenharmony_ci  *state = *state < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP;
10650f66f451Sopenharmony_ci}
10660f66f451Sopenharmony_ci
10670f66f451Sopenharmony_ci/* Test if the previous symbol was a literal. */
10680f66f451Sopenharmony_cistatic inline int lzma_state_is_literal(enum lzma_state state)
10690f66f451Sopenharmony_ci{
10700f66f451Sopenharmony_ci  return state < LIT_STATES;
10710f66f451Sopenharmony_ci}
10720f66f451Sopenharmony_ci
10730f66f451Sopenharmony_ci/* Each literal coder is divided in three sections:
10740f66f451Sopenharmony_ci *   - 0x001-0x0FF: Without match byte
10750f66f451Sopenharmony_ci *   - 0x101-0x1FF: With match byte; match bit is 0
10760f66f451Sopenharmony_ci *   - 0x201-0x2FF: With match byte; match bit is 1
10770f66f451Sopenharmony_ci *
10780f66f451Sopenharmony_ci * Match byte is used when the previous LZMA symbol was something else than
10790f66f451Sopenharmony_ci * a literal (that is, it was some kind of match).
10800f66f451Sopenharmony_ci */
10810f66f451Sopenharmony_ci#define LITERAL_CODER_SIZE 0x300
10820f66f451Sopenharmony_ci
10830f66f451Sopenharmony_ci/* Maximum number of literal coders */
10840f66f451Sopenharmony_ci#define LITERAL_CODERS_MAX (1 << 4)
10850f66f451Sopenharmony_ci
10860f66f451Sopenharmony_ci/* Minimum length of a match is two bytes. */
10870f66f451Sopenharmony_ci#define MATCH_LEN_MIN 2
10880f66f451Sopenharmony_ci
10890f66f451Sopenharmony_ci/* Match length is encoded with 4, 5, or 10 bits.
10900f66f451Sopenharmony_ci *
10910f66f451Sopenharmony_ci * Length   Bits
10920f66f451Sopenharmony_ci *  2-9      4 = Choice=0 + 3 bits
10930f66f451Sopenharmony_ci * 10-17     5 = Choice=1 + Choice2=0 + 3 bits
10940f66f451Sopenharmony_ci * 18-273   10 = Choice=1 + Choice2=1 + 8 bits
10950f66f451Sopenharmony_ci */
10960f66f451Sopenharmony_ci#define LEN_LOW_BITS 3
10970f66f451Sopenharmony_ci#define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS)
10980f66f451Sopenharmony_ci#define LEN_MID_BITS 3
10990f66f451Sopenharmony_ci#define LEN_MID_SYMBOLS (1 << LEN_MID_BITS)
11000f66f451Sopenharmony_ci#define LEN_HIGH_BITS 8
11010f66f451Sopenharmony_ci#define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS)
11020f66f451Sopenharmony_ci#define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS)
11030f66f451Sopenharmony_ci
11040f66f451Sopenharmony_ci/*
11050f66f451Sopenharmony_ci * Maximum length of a match is 273 which is a result of the encoding
11060f66f451Sopenharmony_ci * described above.
11070f66f451Sopenharmony_ci */
11080f66f451Sopenharmony_ci#define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1)
11090f66f451Sopenharmony_ci
11100f66f451Sopenharmony_ci/*
11110f66f451Sopenharmony_ci * Different sets of probabilities are used for match distances that have
11120f66f451Sopenharmony_ci * very short match length: Lengths of 2, 3, and 4 bytes have a separate
11130f66f451Sopenharmony_ci * set of probabilities for each length. The matches with longer length
11140f66f451Sopenharmony_ci * use a shared set of probabilities.
11150f66f451Sopenharmony_ci */
11160f66f451Sopenharmony_ci#define DIST_STATES 4
11170f66f451Sopenharmony_ci
11180f66f451Sopenharmony_ci/*
11190f66f451Sopenharmony_ci * Get the index of the appropriate probability array for decoding
11200f66f451Sopenharmony_ci * the distance slot.
11210f66f451Sopenharmony_ci */
11220f66f451Sopenharmony_cistatic inline uint32_t lzma_get_dist_state(uint32_t len)
11230f66f451Sopenharmony_ci{
11240f66f451Sopenharmony_ci  return len < DIST_STATES + MATCH_LEN_MIN
11250f66f451Sopenharmony_ci      ? len - MATCH_LEN_MIN : DIST_STATES - 1;
11260f66f451Sopenharmony_ci}
11270f66f451Sopenharmony_ci
11280f66f451Sopenharmony_ci/*
11290f66f451Sopenharmony_ci * The highest two bits of a 32-bit match distance are encoded using six bits.
11300f66f451Sopenharmony_ci * This six-bit value is called a distance slot. This way encoding a 32-bit
11310f66f451Sopenharmony_ci * value takes 6-36 bits, larger values taking more bits.
11320f66f451Sopenharmony_ci */
11330f66f451Sopenharmony_ci#define DIST_SLOT_BITS 6
11340f66f451Sopenharmony_ci#define DIST_SLOTS (1 << DIST_SLOT_BITS)
11350f66f451Sopenharmony_ci
11360f66f451Sopenharmony_ci/* Match distances up to 127 are fully encoded using probabilities. Since
11370f66f451Sopenharmony_ci * the highest two bits (distance slot) are always encoded using six bits,
11380f66f451Sopenharmony_ci * the distances 0-3 don't need any additional bits to encode, since the
11390f66f451Sopenharmony_ci * distance slot itself is the same as the actual distance. DIST_MODEL_START
11400f66f451Sopenharmony_ci * indicates the first distance slot where at least one additional bit is
11410f66f451Sopenharmony_ci * needed.
11420f66f451Sopenharmony_ci */
11430f66f451Sopenharmony_ci#define DIST_MODEL_START 4
11440f66f451Sopenharmony_ci
11450f66f451Sopenharmony_ci/*
11460f66f451Sopenharmony_ci * Match distances greater than 127 are encoded in three pieces:
11470f66f451Sopenharmony_ci *   - distance slot: the highest two bits
11480f66f451Sopenharmony_ci *   - direct bits: 2-26 bits below the highest two bits
11490f66f451Sopenharmony_ci *   - alignment bits: four lowest bits
11500f66f451Sopenharmony_ci *
11510f66f451Sopenharmony_ci * Direct bits don't use any probabilities.
11520f66f451Sopenharmony_ci *
11530f66f451Sopenharmony_ci * The distance slot value of 14 is for distances 128-191.
11540f66f451Sopenharmony_ci */
11550f66f451Sopenharmony_ci#define DIST_MODEL_END 14
11560f66f451Sopenharmony_ci
11570f66f451Sopenharmony_ci/* Distance slots that indicate a distance <= 127. */
11580f66f451Sopenharmony_ci#define FULL_DISTANCES_BITS (DIST_MODEL_END / 2)
11590f66f451Sopenharmony_ci#define FULL_DISTANCES (1 << FULL_DISTANCES_BITS)
11600f66f451Sopenharmony_ci
11610f66f451Sopenharmony_ci/*
11620f66f451Sopenharmony_ci * For match distances greater than 127, only the highest two bits and the
11630f66f451Sopenharmony_ci * lowest four bits (alignment) is encoded using probabilities.
11640f66f451Sopenharmony_ci */
11650f66f451Sopenharmony_ci#define ALIGN_BITS 4
11660f66f451Sopenharmony_ci#define ALIGN_SIZE (1 << ALIGN_BITS)
11670f66f451Sopenharmony_ci#define ALIGN_MASK (ALIGN_SIZE - 1)
11680f66f451Sopenharmony_ci
11690f66f451Sopenharmony_ci/* Total number of all probability variables */
11700f66f451Sopenharmony_ci#define PROBS_TOTAL (1846 + LITERAL_CODERS_MAX * LITERAL_CODER_SIZE)
11710f66f451Sopenharmony_ci
11720f66f451Sopenharmony_ci/*
11730f66f451Sopenharmony_ci * LZMA remembers the four most recent match distances. Reusing these
11740f66f451Sopenharmony_ci * distances tends to take less space than re-encoding the actual
11750f66f451Sopenharmony_ci * distance value.
11760f66f451Sopenharmony_ci */
11770f66f451Sopenharmony_ci#define REPS 4
11780f66f451Sopenharmony_ci
11790f66f451Sopenharmony_ci
11800f66f451Sopenharmony_ci// END xz_lzma2.h
11810f66f451Sopenharmony_ci
11820f66f451Sopenharmony_ci/*
11830f66f451Sopenharmony_ci * Range decoder initialization eats the first five bytes of each LZMA chunk.
11840f66f451Sopenharmony_ci */
11850f66f451Sopenharmony_ci#define RC_INIT_BYTES 5
11860f66f451Sopenharmony_ci
11870f66f451Sopenharmony_ci/*
11880f66f451Sopenharmony_ci * Minimum number of usable input buffer to safely decode one LZMA symbol.
11890f66f451Sopenharmony_ci * The worst case is that we decode 22 bits using probabilities and 26
11900f66f451Sopenharmony_ci * direct bits. This may decode at maximum of 20 bytes of input. However,
11910f66f451Sopenharmony_ci * lzma_main() does an extra normalization before returning, thus we
11920f66f451Sopenharmony_ci * need to put 21 here.
11930f66f451Sopenharmony_ci */
11940f66f451Sopenharmony_ci#define LZMA_IN_REQUIRED 21
11950f66f451Sopenharmony_ci
11960f66f451Sopenharmony_ci/*
11970f66f451Sopenharmony_ci * Dictionary (history buffer)
11980f66f451Sopenharmony_ci *
11990f66f451Sopenharmony_ci * These are always true:
12000f66f451Sopenharmony_ci *    start <= pos <= full <= end
12010f66f451Sopenharmony_ci *    pos <= limit <= end
12020f66f451Sopenharmony_ci *    end == size
12030f66f451Sopenharmony_ci *    size <= size_max
12040f66f451Sopenharmony_ci *    allocated <= size
12050f66f451Sopenharmony_ci *
12060f66f451Sopenharmony_ci * Most of these variables are size_t as a relic of single-call mode,
12070f66f451Sopenharmony_ci * in which the dictionary variables address the actual output
12080f66f451Sopenharmony_ci * buffer directly.
12090f66f451Sopenharmony_ci */
12100f66f451Sopenharmony_cistruct dictionary {
12110f66f451Sopenharmony_ci  /* Beginning of the history buffer */
12120f66f451Sopenharmony_ci  uint8_t *buf;
12130f66f451Sopenharmony_ci
12140f66f451Sopenharmony_ci  /* Old position in buf (before decoding more data) */
12150f66f451Sopenharmony_ci  size_t start;
12160f66f451Sopenharmony_ci
12170f66f451Sopenharmony_ci  /* Position in buf */
12180f66f451Sopenharmony_ci  size_t pos;
12190f66f451Sopenharmony_ci
12200f66f451Sopenharmony_ci  /*
12210f66f451Sopenharmony_ci   * How full dictionary is. This is used to detect corrupt input that
12220f66f451Sopenharmony_ci   * would read beyond the beginning of the uncompressed stream.
12230f66f451Sopenharmony_ci   */
12240f66f451Sopenharmony_ci  size_t full;
12250f66f451Sopenharmony_ci
12260f66f451Sopenharmony_ci  /* Write limit; we don't write to buf[limit] or later bytes. */
12270f66f451Sopenharmony_ci  size_t limit;
12280f66f451Sopenharmony_ci
12290f66f451Sopenharmony_ci  /* End of the dictionary buffer. This is the same as the dictionary size. */
12300f66f451Sopenharmony_ci  size_t end;
12310f66f451Sopenharmony_ci
12320f66f451Sopenharmony_ci  /*
12330f66f451Sopenharmony_ci   * Size of the dictionary as specified in Block Header. This is used
12340f66f451Sopenharmony_ci   * together with "full" to detect corrupt input that would make us
12350f66f451Sopenharmony_ci   * read beyond the beginning of the uncompressed stream.
12360f66f451Sopenharmony_ci   */
12370f66f451Sopenharmony_ci  uint32_t size;
12380f66f451Sopenharmony_ci
12390f66f451Sopenharmony_ci  /*
12400f66f451Sopenharmony_ci   * Maximum allowed dictionary size.
12410f66f451Sopenharmony_ci   */
12420f66f451Sopenharmony_ci  uint32_t size_max;
12430f66f451Sopenharmony_ci
12440f66f451Sopenharmony_ci  /*
12450f66f451Sopenharmony_ci   * Amount of memory currently allocated for the dictionary.
12460f66f451Sopenharmony_ci   */
12470f66f451Sopenharmony_ci  uint32_t allocated;
12480f66f451Sopenharmony_ci};
12490f66f451Sopenharmony_ci
12500f66f451Sopenharmony_ci/* Range decoder */
12510f66f451Sopenharmony_cistruct rc_dec {
12520f66f451Sopenharmony_ci  uint32_t range;
12530f66f451Sopenharmony_ci  uint32_t code;
12540f66f451Sopenharmony_ci
12550f66f451Sopenharmony_ci  /*
12560f66f451Sopenharmony_ci   * Number of initializing bytes remaining to be read
12570f66f451Sopenharmony_ci   * by rc_read_init().
12580f66f451Sopenharmony_ci   */
12590f66f451Sopenharmony_ci  uint32_t init_bytes_left;
12600f66f451Sopenharmony_ci
12610f66f451Sopenharmony_ci  /*
12620f66f451Sopenharmony_ci   * Buffer from which we read our input. It can be either
12630f66f451Sopenharmony_ci   * temp.buf or the caller-provided input buffer.
12640f66f451Sopenharmony_ci   */
12650f66f451Sopenharmony_ci  const uint8_t *in;
12660f66f451Sopenharmony_ci  size_t in_pos;
12670f66f451Sopenharmony_ci  size_t in_limit;
12680f66f451Sopenharmony_ci};
12690f66f451Sopenharmony_ci
12700f66f451Sopenharmony_ci/* Probabilities for a length decoder. */
12710f66f451Sopenharmony_cistruct lzma_len_dec {
12720f66f451Sopenharmony_ci  /* Probability of match length being at least 10 */
12730f66f451Sopenharmony_ci  uint16_t choice;
12740f66f451Sopenharmony_ci
12750f66f451Sopenharmony_ci  /* Probability of match length being at least 18 */
12760f66f451Sopenharmony_ci  uint16_t choice2;
12770f66f451Sopenharmony_ci
12780f66f451Sopenharmony_ci  /* Probabilities for match lengths 2-9 */
12790f66f451Sopenharmony_ci  uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
12800f66f451Sopenharmony_ci
12810f66f451Sopenharmony_ci  /* Probabilities for match lengths 10-17 */
12820f66f451Sopenharmony_ci  uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
12830f66f451Sopenharmony_ci
12840f66f451Sopenharmony_ci  /* Probabilities for match lengths 18-273 */
12850f66f451Sopenharmony_ci  uint16_t high[LEN_HIGH_SYMBOLS];
12860f66f451Sopenharmony_ci};
12870f66f451Sopenharmony_ci
12880f66f451Sopenharmony_cistruct lzma_dec {
12890f66f451Sopenharmony_ci  /* Distances of latest four matches */
12900f66f451Sopenharmony_ci  uint32_t rep0;
12910f66f451Sopenharmony_ci  uint32_t rep1;
12920f66f451Sopenharmony_ci  uint32_t rep2;
12930f66f451Sopenharmony_ci  uint32_t rep3;
12940f66f451Sopenharmony_ci
12950f66f451Sopenharmony_ci  /* Types of the most recently seen LZMA symbols */
12960f66f451Sopenharmony_ci  enum lzma_state state;
12970f66f451Sopenharmony_ci
12980f66f451Sopenharmony_ci  /*
12990f66f451Sopenharmony_ci   * Length of a match. This is updated so that dict_repeat can
13000f66f451Sopenharmony_ci   * be called again to finish repeating the whole match.
13010f66f451Sopenharmony_ci   */
13020f66f451Sopenharmony_ci  uint32_t len;
13030f66f451Sopenharmony_ci
13040f66f451Sopenharmony_ci  /*
13050f66f451Sopenharmony_ci   * LZMA properties or related bit masks (number of literal
13060f66f451Sopenharmony_ci   * context bits, a mask dervied from the number of literal
13070f66f451Sopenharmony_ci   * position bits, and a mask dervied from the number
13080f66f451Sopenharmony_ci   * position bits)
13090f66f451Sopenharmony_ci   */
13100f66f451Sopenharmony_ci  uint32_t lc;
13110f66f451Sopenharmony_ci  uint32_t literal_pos_mask; /* (1 << lp) - 1 */
13120f66f451Sopenharmony_ci  uint32_t pos_mask;         /* (1 << pb) - 1 */
13130f66f451Sopenharmony_ci
13140f66f451Sopenharmony_ci  /* If 1, it's a match. Otherwise it's a single 8-bit literal. */
13150f66f451Sopenharmony_ci  uint16_t is_match[STATES][POS_STATES_MAX];
13160f66f451Sopenharmony_ci
13170f66f451Sopenharmony_ci  /* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */
13180f66f451Sopenharmony_ci  uint16_t is_rep[STATES];
13190f66f451Sopenharmony_ci
13200f66f451Sopenharmony_ci  /*
13210f66f451Sopenharmony_ci   * If 0, distance of a repeated match is rep0.
13220f66f451Sopenharmony_ci   * Otherwise check is_rep1.
13230f66f451Sopenharmony_ci   */
13240f66f451Sopenharmony_ci  uint16_t is_rep0[STATES];
13250f66f451Sopenharmony_ci
13260f66f451Sopenharmony_ci  /*
13270f66f451Sopenharmony_ci   * If 0, distance of a repeated match is rep1.
13280f66f451Sopenharmony_ci   * Otherwise check is_rep2.
13290f66f451Sopenharmony_ci   */
13300f66f451Sopenharmony_ci  uint16_t is_rep1[STATES];
13310f66f451Sopenharmony_ci
13320f66f451Sopenharmony_ci  /* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */
13330f66f451Sopenharmony_ci  uint16_t is_rep2[STATES];
13340f66f451Sopenharmony_ci
13350f66f451Sopenharmony_ci  /*
13360f66f451Sopenharmony_ci   * If 1, the repeated match has length of one byte. Otherwise
13370f66f451Sopenharmony_ci   * the length is decoded from rep_len_decoder.
13380f66f451Sopenharmony_ci   */
13390f66f451Sopenharmony_ci  uint16_t is_rep0_long[STATES][POS_STATES_MAX];
13400f66f451Sopenharmony_ci
13410f66f451Sopenharmony_ci  /*
13420f66f451Sopenharmony_ci   * Probability tree for the highest two bits of the match
13430f66f451Sopenharmony_ci   * distance. There is a separate probability tree for match
13440f66f451Sopenharmony_ci   * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].
13450f66f451Sopenharmony_ci   */
13460f66f451Sopenharmony_ci  uint16_t dist_slot[DIST_STATES][DIST_SLOTS];
13470f66f451Sopenharmony_ci
13480f66f451Sopenharmony_ci  /*
13490f66f451Sopenharmony_ci   * Probility trees for additional bits for match distance
13500f66f451Sopenharmony_ci   * when the distance is in the range [4, 127].
13510f66f451Sopenharmony_ci   */
13520f66f451Sopenharmony_ci  uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END];
13530f66f451Sopenharmony_ci
13540f66f451Sopenharmony_ci  /*
13550f66f451Sopenharmony_ci   * Probability tree for the lowest four bits of a match
13560f66f451Sopenharmony_ci   * distance that is equal to or greater than 128.
13570f66f451Sopenharmony_ci   */
13580f66f451Sopenharmony_ci  uint16_t dist_align[ALIGN_SIZE];
13590f66f451Sopenharmony_ci
13600f66f451Sopenharmony_ci  /* Length of a normal match */
13610f66f451Sopenharmony_ci  struct lzma_len_dec match_len_dec;
13620f66f451Sopenharmony_ci
13630f66f451Sopenharmony_ci  /* Length of a repeated match */
13640f66f451Sopenharmony_ci  struct lzma_len_dec rep_len_dec;
13650f66f451Sopenharmony_ci
13660f66f451Sopenharmony_ci  /* Probabilities of literals */
13670f66f451Sopenharmony_ci  uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
13680f66f451Sopenharmony_ci};
13690f66f451Sopenharmony_ci
13700f66f451Sopenharmony_cistruct lzma2_dec {
13710f66f451Sopenharmony_ci  /* Position in xz_dec_lzma2_run(). */
13720f66f451Sopenharmony_ci  enum lzma2_seq {
13730f66f451Sopenharmony_ci    SEQ_CONTROL,
13740f66f451Sopenharmony_ci    SEQ_UNCOMPRESSED_1,
13750f66f451Sopenharmony_ci    SEQ_UNCOMPRESSED_2,
13760f66f451Sopenharmony_ci    SEQ_COMPRESSED_0,
13770f66f451Sopenharmony_ci    SEQ_COMPRESSED_1,
13780f66f451Sopenharmony_ci    SEQ_PROPERTIES,
13790f66f451Sopenharmony_ci    SEQ_LZMA_PREPARE,
13800f66f451Sopenharmony_ci    SEQ_LZMA_RUN,
13810f66f451Sopenharmony_ci    SEQ_COPY
13820f66f451Sopenharmony_ci  } sequence;
13830f66f451Sopenharmony_ci
13840f66f451Sopenharmony_ci  /* Next position after decoding the compressed size of the chunk. */
13850f66f451Sopenharmony_ci  enum lzma2_seq next_sequence;
13860f66f451Sopenharmony_ci
13870f66f451Sopenharmony_ci  /* Uncompressed size of LZMA chunk (2 MiB at maximum) */
13880f66f451Sopenharmony_ci  uint32_t uncompressed;
13890f66f451Sopenharmony_ci
13900f66f451Sopenharmony_ci  /*
13910f66f451Sopenharmony_ci   * Compressed size of LZMA chunk or compressed/uncompressed
13920f66f451Sopenharmony_ci   * size of uncompressed chunk (64 KiB at maximum)
13930f66f451Sopenharmony_ci   */
13940f66f451Sopenharmony_ci  uint32_t compressed;
13950f66f451Sopenharmony_ci
13960f66f451Sopenharmony_ci  /*
13970f66f451Sopenharmony_ci   * True if dictionary reset is needed. This is false before
13980f66f451Sopenharmony_ci   * the first chunk (LZMA or uncompressed).
13990f66f451Sopenharmony_ci   */
14000f66f451Sopenharmony_ci  int need_dict_reset;
14010f66f451Sopenharmony_ci
14020f66f451Sopenharmony_ci  /*
14030f66f451Sopenharmony_ci   * True if new LZMA properties are needed. This is false
14040f66f451Sopenharmony_ci   * before the first LZMA chunk.
14050f66f451Sopenharmony_ci   */
14060f66f451Sopenharmony_ci  int need_props;
14070f66f451Sopenharmony_ci};
14080f66f451Sopenharmony_ci
14090f66f451Sopenharmony_cistruct xz_dec_lzma2 {
14100f66f451Sopenharmony_ci  /*
14110f66f451Sopenharmony_ci   * The order below is important on x86 to reduce code size and
14120f66f451Sopenharmony_ci   * it shouldn't hurt on other platforms. Everything up to and
14130f66f451Sopenharmony_ci   * including lzma.pos_mask are in the first 128 bytes on x86-32,
14140f66f451Sopenharmony_ci   * which allows using smaller instructions to access those
14150f66f451Sopenharmony_ci   * variables. On x86-64, fewer variables fit into the first 128
14160f66f451Sopenharmony_ci   * bytes, but this is still the best order without sacrificing
14170f66f451Sopenharmony_ci   * the readability by splitting the structures.
14180f66f451Sopenharmony_ci   */
14190f66f451Sopenharmony_ci  struct rc_dec rc;
14200f66f451Sopenharmony_ci  struct dictionary dict;
14210f66f451Sopenharmony_ci  struct lzma2_dec lzma2;
14220f66f451Sopenharmony_ci  struct lzma_dec lzma;
14230f66f451Sopenharmony_ci
14240f66f451Sopenharmony_ci  /*
14250f66f451Sopenharmony_ci   * Temporary buffer which holds small number of input bytes between
14260f66f451Sopenharmony_ci   * decoder calls. See lzma2_lzma() for details.
14270f66f451Sopenharmony_ci   */
14280f66f451Sopenharmony_ci  struct {
14290f66f451Sopenharmony_ci    uint32_t size;
14300f66f451Sopenharmony_ci    uint8_t buf[3 * LZMA_IN_REQUIRED];
14310f66f451Sopenharmony_ci  } temp;
14320f66f451Sopenharmony_ci};
14330f66f451Sopenharmony_ci
14340f66f451Sopenharmony_ci/**************
14350f66f451Sopenharmony_ci * Dictionary *
14360f66f451Sopenharmony_ci **************/
14370f66f451Sopenharmony_ci
14380f66f451Sopenharmony_ci/* Reset the dictionary state. */
14390f66f451Sopenharmony_cistatic void dict_reset(struct dictionary *dict)
14400f66f451Sopenharmony_ci{
14410f66f451Sopenharmony_ci  dict->start = 0;
14420f66f451Sopenharmony_ci  dict->pos = 0;
14430f66f451Sopenharmony_ci  dict->limit = 0;
14440f66f451Sopenharmony_ci  dict->full = 0;
14450f66f451Sopenharmony_ci}
14460f66f451Sopenharmony_ci
14470f66f451Sopenharmony_ci/* Set dictionary write limit */
14480f66f451Sopenharmony_cistatic void dict_limit(struct dictionary *dict, size_t out_max)
14490f66f451Sopenharmony_ci{
14500f66f451Sopenharmony_ci  if (dict->end - dict->pos <= out_max)
14510f66f451Sopenharmony_ci    dict->limit = dict->end;
14520f66f451Sopenharmony_ci  else
14530f66f451Sopenharmony_ci    dict->limit = dict->pos + out_max;
14540f66f451Sopenharmony_ci}
14550f66f451Sopenharmony_ci
14560f66f451Sopenharmony_ci/* Return true if at least one byte can be written into the dictionary. */
14570f66f451Sopenharmony_cistatic inline int dict_has_space(const struct dictionary *dict)
14580f66f451Sopenharmony_ci{
14590f66f451Sopenharmony_ci  return dict->pos < dict->limit;
14600f66f451Sopenharmony_ci}
14610f66f451Sopenharmony_ci
14620f66f451Sopenharmony_ci/*
14630f66f451Sopenharmony_ci * Get a byte from the dictionary at the given distance. The distance is
14640f66f451Sopenharmony_ci * assumed to valid, or as a special case, zero when the dictionary is
14650f66f451Sopenharmony_ci * still empty. This special case is needed for single-call decoding to
14660f66f451Sopenharmony_ci * avoid writing a '\0' to the end of the destination buffer.
14670f66f451Sopenharmony_ci */
14680f66f451Sopenharmony_cistatic inline uint32_t dict_get(const struct dictionary *dict, uint32_t dist)
14690f66f451Sopenharmony_ci{
14700f66f451Sopenharmony_ci  size_t offset = dict->pos - dist - 1;
14710f66f451Sopenharmony_ci
14720f66f451Sopenharmony_ci  if (dist >= dict->pos)
14730f66f451Sopenharmony_ci    offset += dict->end;
14740f66f451Sopenharmony_ci
14750f66f451Sopenharmony_ci  return dict->full > 0 ? dict->buf[offset] : 0;
14760f66f451Sopenharmony_ci}
14770f66f451Sopenharmony_ci
14780f66f451Sopenharmony_ci/*
14790f66f451Sopenharmony_ci * Put one byte into the dictionary. It is assumed that there is space for it.
14800f66f451Sopenharmony_ci */
14810f66f451Sopenharmony_cistatic inline void dict_put(struct dictionary *dict, uint8_t byte)
14820f66f451Sopenharmony_ci{
14830f66f451Sopenharmony_ci  dict->buf[dict->pos++] = byte;
14840f66f451Sopenharmony_ci
14850f66f451Sopenharmony_ci  if (dict->full < dict->pos)
14860f66f451Sopenharmony_ci    dict->full = dict->pos;
14870f66f451Sopenharmony_ci}
14880f66f451Sopenharmony_ci
14890f66f451Sopenharmony_ci/*
14900f66f451Sopenharmony_ci * Repeat given number of bytes from the given distance. If the distance is
14910f66f451Sopenharmony_ci * invalid, false is returned. On success, true is returned and *len is
14920f66f451Sopenharmony_ci * updated to indicate how many bytes were left to be repeated.
14930f66f451Sopenharmony_ci */
14940f66f451Sopenharmony_cistatic int dict_repeat(struct dictionary *dict, uint32_t *len, uint32_t dist)
14950f66f451Sopenharmony_ci{
14960f66f451Sopenharmony_ci  size_t back;
14970f66f451Sopenharmony_ci  uint32_t left;
14980f66f451Sopenharmony_ci
14990f66f451Sopenharmony_ci  if (dist >= dict->full || dist >= dict->size) return 0;
15000f66f451Sopenharmony_ci
15010f66f451Sopenharmony_ci  left = minof(dict->limit - dict->pos, *len);
15020f66f451Sopenharmony_ci  *len -= left;
15030f66f451Sopenharmony_ci
15040f66f451Sopenharmony_ci  back = dict->pos - dist - 1;
15050f66f451Sopenharmony_ci  if (dist >= dict->pos)
15060f66f451Sopenharmony_ci    back += dict->end;
15070f66f451Sopenharmony_ci
15080f66f451Sopenharmony_ci  do {
15090f66f451Sopenharmony_ci    dict->buf[dict->pos++] = dict->buf[back++];
15100f66f451Sopenharmony_ci    if (back == dict->end)
15110f66f451Sopenharmony_ci      back = 0;
15120f66f451Sopenharmony_ci  } while (--left > 0);
15130f66f451Sopenharmony_ci
15140f66f451Sopenharmony_ci  if (dict->full < dict->pos)
15150f66f451Sopenharmony_ci    dict->full = dict->pos;
15160f66f451Sopenharmony_ci
15170f66f451Sopenharmony_ci  return 1;
15180f66f451Sopenharmony_ci}
15190f66f451Sopenharmony_ci
15200f66f451Sopenharmony_ci/* Copy uncompressed data as is from input to dictionary and output buffers. */
15210f66f451Sopenharmony_cistatic void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
15220f66f451Sopenharmony_ci            uint32_t *left)
15230f66f451Sopenharmony_ci{
15240f66f451Sopenharmony_ci  size_t copy_size;
15250f66f451Sopenharmony_ci
15260f66f451Sopenharmony_ci  while (*left > 0 && b->in_pos < b->in_size
15270f66f451Sopenharmony_ci      && b->out_pos < b->out_size) {
15280f66f451Sopenharmony_ci    copy_size = minof(b->in_size - b->in_pos,
15290f66f451Sopenharmony_ci        b->out_size - b->out_pos);
15300f66f451Sopenharmony_ci    if (copy_size > dict->end - dict->pos)
15310f66f451Sopenharmony_ci      copy_size = dict->end - dict->pos;
15320f66f451Sopenharmony_ci    if (copy_size > *left)
15330f66f451Sopenharmony_ci      copy_size = *left;
15340f66f451Sopenharmony_ci
15350f66f451Sopenharmony_ci    *left -= copy_size;
15360f66f451Sopenharmony_ci
15370f66f451Sopenharmony_ci    memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
15380f66f451Sopenharmony_ci    dict->pos += copy_size;
15390f66f451Sopenharmony_ci
15400f66f451Sopenharmony_ci    if (dict->full < dict->pos)
15410f66f451Sopenharmony_ci      dict->full = dict->pos;
15420f66f451Sopenharmony_ci
15430f66f451Sopenharmony_ci    if (dict->pos == dict->end)
15440f66f451Sopenharmony_ci      dict->pos = 0;
15450f66f451Sopenharmony_ci
15460f66f451Sopenharmony_ci    memcpy(b->out + b->out_pos, b->in + b->in_pos,
15470f66f451Sopenharmony_ci        copy_size);
15480f66f451Sopenharmony_ci
15490f66f451Sopenharmony_ci    dict->start = dict->pos;
15500f66f451Sopenharmony_ci
15510f66f451Sopenharmony_ci    b->out_pos += copy_size;
15520f66f451Sopenharmony_ci    b->in_pos += copy_size;
15530f66f451Sopenharmony_ci  }
15540f66f451Sopenharmony_ci}
15550f66f451Sopenharmony_ci
15560f66f451Sopenharmony_ci/*
15570f66f451Sopenharmony_ci * Flush pending data from dictionary to b->out. It is assumed that there is
15580f66f451Sopenharmony_ci * enough space in b->out. This is guaranteed because caller uses dict_limit()
15590f66f451Sopenharmony_ci * before decoding data into the dictionary.
15600f66f451Sopenharmony_ci */
15610f66f451Sopenharmony_cistatic uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
15620f66f451Sopenharmony_ci{
15630f66f451Sopenharmony_ci  size_t copy_size = dict->pos - dict->start;
15640f66f451Sopenharmony_ci
15650f66f451Sopenharmony_ci  if (dict->pos == dict->end)
15660f66f451Sopenharmony_ci    dict->pos = 0;
15670f66f451Sopenharmony_ci
15680f66f451Sopenharmony_ci  memcpy(b->out + b->out_pos, dict->buf + dict->start,
15690f66f451Sopenharmony_ci      copy_size);
15700f66f451Sopenharmony_ci
15710f66f451Sopenharmony_ci  dict->start = dict->pos;
15720f66f451Sopenharmony_ci  b->out_pos += copy_size;
15730f66f451Sopenharmony_ci  return copy_size;
15740f66f451Sopenharmony_ci}
15750f66f451Sopenharmony_ci
15760f66f451Sopenharmony_ci/*****************
15770f66f451Sopenharmony_ci * Range decoder *
15780f66f451Sopenharmony_ci *****************/
15790f66f451Sopenharmony_ci
15800f66f451Sopenharmony_ci/* Reset the range decoder. */
15810f66f451Sopenharmony_cistatic void rc_reset(struct rc_dec *rc)
15820f66f451Sopenharmony_ci{
15830f66f451Sopenharmony_ci  rc->range = (uint32_t)-1;
15840f66f451Sopenharmony_ci  rc->code = 0;
15850f66f451Sopenharmony_ci  rc->init_bytes_left = RC_INIT_BYTES;
15860f66f451Sopenharmony_ci}
15870f66f451Sopenharmony_ci
15880f66f451Sopenharmony_ci/*
15890f66f451Sopenharmony_ci * Read the first five initial bytes into rc->code if they haven't been
15900f66f451Sopenharmony_ci * read already. (Yes, the first byte gets completely ignored.)
15910f66f451Sopenharmony_ci */
15920f66f451Sopenharmony_cistatic int rc_read_init(struct rc_dec *rc, struct xz_buf *b)
15930f66f451Sopenharmony_ci{
15940f66f451Sopenharmony_ci  while (rc->init_bytes_left > 0) {
15950f66f451Sopenharmony_ci    if (b->in_pos == b->in_size) return 0;
15960f66f451Sopenharmony_ci
15970f66f451Sopenharmony_ci    rc->code = (rc->code << 8) + b->in[b->in_pos++];
15980f66f451Sopenharmony_ci    --rc->init_bytes_left;
15990f66f451Sopenharmony_ci  }
16000f66f451Sopenharmony_ci
16010f66f451Sopenharmony_ci  return 1;
16020f66f451Sopenharmony_ci}
16030f66f451Sopenharmony_ci
16040f66f451Sopenharmony_ci/* Return true if there may not be enough input for the next decoding loop. */
16050f66f451Sopenharmony_cistatic inline int rc_limit_exceeded(const struct rc_dec *rc)
16060f66f451Sopenharmony_ci{
16070f66f451Sopenharmony_ci  return rc->in_pos > rc->in_limit;
16080f66f451Sopenharmony_ci}
16090f66f451Sopenharmony_ci
16100f66f451Sopenharmony_ci/*
16110f66f451Sopenharmony_ci * Return true if it is possible (from point of view of range decoder) that
16120f66f451Sopenharmony_ci * we have reached the end of the LZMA chunk.
16130f66f451Sopenharmony_ci */
16140f66f451Sopenharmony_cistatic inline int rc_is_finished(const struct rc_dec *rc)
16150f66f451Sopenharmony_ci{
16160f66f451Sopenharmony_ci  return rc->code == 0;
16170f66f451Sopenharmony_ci}
16180f66f451Sopenharmony_ci
16190f66f451Sopenharmony_ci/* Read the next input byte if needed. */
16200f66f451Sopenharmony_cistatic inline void rc_normalize(struct rc_dec *rc)
16210f66f451Sopenharmony_ci{
16220f66f451Sopenharmony_ci  if (rc->range < RC_TOP_VALUE) {
16230f66f451Sopenharmony_ci    rc->range <<= RC_SHIFT_BITS;
16240f66f451Sopenharmony_ci    rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
16250f66f451Sopenharmony_ci  }
16260f66f451Sopenharmony_ci}
16270f66f451Sopenharmony_ci
16280f66f451Sopenharmony_ci/*
16290f66f451Sopenharmony_ci * Decode one bit. In some versions, this function has been splitted in three
16300f66f451Sopenharmony_ci * functions so that the compiler is supposed to be able to more easily avoid
16310f66f451Sopenharmony_ci * an extra branch. In this particular version of the LZMA decoder, this
16320f66f451Sopenharmony_ci * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3
16330f66f451Sopenharmony_ci * on x86). Using a non-splitted version results in nicer looking code too.
16340f66f451Sopenharmony_ci *
16350f66f451Sopenharmony_ci * NOTE: This must return an int. Do not make it return a bool or the speed
16360f66f451Sopenharmony_ci * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care,
16370f66f451Sopenharmony_ci * and it generates 10-20 % faster code than GCC 3.x from this file anyway.)
16380f66f451Sopenharmony_ci */
16390f66f451Sopenharmony_cistatic inline int rc_bit(struct rc_dec *rc, uint16_t *prob)
16400f66f451Sopenharmony_ci{
16410f66f451Sopenharmony_ci  uint32_t bound;
16420f66f451Sopenharmony_ci  int bit;
16430f66f451Sopenharmony_ci
16440f66f451Sopenharmony_ci  rc_normalize(rc);
16450f66f451Sopenharmony_ci  bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
16460f66f451Sopenharmony_ci  if (rc->code < bound) {
16470f66f451Sopenharmony_ci    rc->range = bound;
16480f66f451Sopenharmony_ci    *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
16490f66f451Sopenharmony_ci    bit = 0;
16500f66f451Sopenharmony_ci  } else {
16510f66f451Sopenharmony_ci    rc->range -= bound;
16520f66f451Sopenharmony_ci    rc->code -= bound;
16530f66f451Sopenharmony_ci    *prob -= *prob >> RC_MOVE_BITS;
16540f66f451Sopenharmony_ci    bit = 1;
16550f66f451Sopenharmony_ci  }
16560f66f451Sopenharmony_ci
16570f66f451Sopenharmony_ci  return bit;
16580f66f451Sopenharmony_ci}
16590f66f451Sopenharmony_ci
16600f66f451Sopenharmony_ci/* Decode a bittree starting from the most significant bit. */
16610f66f451Sopenharmony_cistatic inline uint32_t rc_bittree(struct rc_dec *rc,
16620f66f451Sopenharmony_ci             uint16_t *probs, uint32_t limit)
16630f66f451Sopenharmony_ci{
16640f66f451Sopenharmony_ci  uint32_t symbol = 1;
16650f66f451Sopenharmony_ci
16660f66f451Sopenharmony_ci  do {
16670f66f451Sopenharmony_ci    if (rc_bit(rc, &probs[symbol]))
16680f66f451Sopenharmony_ci      symbol = (symbol << 1) + 1;
16690f66f451Sopenharmony_ci    else
16700f66f451Sopenharmony_ci      symbol <<= 1;
16710f66f451Sopenharmony_ci  } while (symbol < limit);
16720f66f451Sopenharmony_ci
16730f66f451Sopenharmony_ci  return symbol;
16740f66f451Sopenharmony_ci}
16750f66f451Sopenharmony_ci
16760f66f451Sopenharmony_ci/* Decode a bittree starting from the least significant bit. */
16770f66f451Sopenharmony_cistatic inline void rc_bittree_reverse(struct rc_dec *rc,
16780f66f451Sopenharmony_ci                 uint16_t *probs,
16790f66f451Sopenharmony_ci                 uint32_t *dest, uint32_t limit)
16800f66f451Sopenharmony_ci{
16810f66f451Sopenharmony_ci  uint32_t symbol = 1;
16820f66f451Sopenharmony_ci  uint32_t i = 0;
16830f66f451Sopenharmony_ci
16840f66f451Sopenharmony_ci  do {
16850f66f451Sopenharmony_ci    if (rc_bit(rc, &probs[symbol])) {
16860f66f451Sopenharmony_ci      symbol = (symbol << 1) + 1;
16870f66f451Sopenharmony_ci      *dest += 1 << i;
16880f66f451Sopenharmony_ci    } else {
16890f66f451Sopenharmony_ci      symbol <<= 1;
16900f66f451Sopenharmony_ci    }
16910f66f451Sopenharmony_ci  } while (++i < limit);
16920f66f451Sopenharmony_ci}
16930f66f451Sopenharmony_ci
16940f66f451Sopenharmony_ci/* Decode direct bits (fixed fifty-fifty probability) */
16950f66f451Sopenharmony_cistatic inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit)
16960f66f451Sopenharmony_ci{
16970f66f451Sopenharmony_ci  uint32_t mask;
16980f66f451Sopenharmony_ci
16990f66f451Sopenharmony_ci  do {
17000f66f451Sopenharmony_ci    rc_normalize(rc);
17010f66f451Sopenharmony_ci    rc->range >>= 1;
17020f66f451Sopenharmony_ci    rc->code -= rc->range;
17030f66f451Sopenharmony_ci    mask = (uint32_t)0 - (rc->code >> 31);
17040f66f451Sopenharmony_ci    rc->code += rc->range & mask;
17050f66f451Sopenharmony_ci    *dest = (*dest << 1) + (mask + 1);
17060f66f451Sopenharmony_ci  } while (--limit > 0);
17070f66f451Sopenharmony_ci}
17080f66f451Sopenharmony_ci
17090f66f451Sopenharmony_ci/********
17100f66f451Sopenharmony_ci * LZMA *
17110f66f451Sopenharmony_ci ********/
17120f66f451Sopenharmony_ci
17130f66f451Sopenharmony_ci/* Get pointer to literal coder probability array. */
17140f66f451Sopenharmony_cistatic uint16_t *lzma_literal_probs(struct xz_dec_lzma2 *s)
17150f66f451Sopenharmony_ci{
17160f66f451Sopenharmony_ci  uint32_t prev_byte = dict_get(&s->dict, 0);
17170f66f451Sopenharmony_ci  uint32_t low = prev_byte >> (8 - s->lzma.lc);
17180f66f451Sopenharmony_ci  uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc;
17190f66f451Sopenharmony_ci  return s->lzma.literal[low + high];
17200f66f451Sopenharmony_ci}
17210f66f451Sopenharmony_ci
17220f66f451Sopenharmony_ci/* Decode a literal (one 8-bit byte) */
17230f66f451Sopenharmony_cistatic void lzma_literal(struct xz_dec_lzma2 *s)
17240f66f451Sopenharmony_ci{
17250f66f451Sopenharmony_ci  uint16_t *probs;
17260f66f451Sopenharmony_ci  uint32_t symbol;
17270f66f451Sopenharmony_ci  uint32_t match_byte;
17280f66f451Sopenharmony_ci  uint32_t match_bit;
17290f66f451Sopenharmony_ci  uint32_t offset;
17300f66f451Sopenharmony_ci  uint32_t i;
17310f66f451Sopenharmony_ci
17320f66f451Sopenharmony_ci  probs = lzma_literal_probs(s);
17330f66f451Sopenharmony_ci
17340f66f451Sopenharmony_ci  if (lzma_state_is_literal(s->lzma.state)) {
17350f66f451Sopenharmony_ci    symbol = rc_bittree(&s->rc, probs, 0x100);
17360f66f451Sopenharmony_ci  } else {
17370f66f451Sopenharmony_ci    symbol = 1;
17380f66f451Sopenharmony_ci    match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
17390f66f451Sopenharmony_ci    offset = 0x100;
17400f66f451Sopenharmony_ci
17410f66f451Sopenharmony_ci    do {
17420f66f451Sopenharmony_ci      match_bit = match_byte & offset;
17430f66f451Sopenharmony_ci      match_byte <<= 1;
17440f66f451Sopenharmony_ci      i = offset + match_bit + symbol;
17450f66f451Sopenharmony_ci
17460f66f451Sopenharmony_ci      if (rc_bit(&s->rc, &probs[i])) {
17470f66f451Sopenharmony_ci        symbol = (symbol << 1) + 1;
17480f66f451Sopenharmony_ci        offset &= match_bit;
17490f66f451Sopenharmony_ci      } else {
17500f66f451Sopenharmony_ci        symbol <<= 1;
17510f66f451Sopenharmony_ci        offset &= ~match_bit;
17520f66f451Sopenharmony_ci      }
17530f66f451Sopenharmony_ci    } while (symbol < 0x100);
17540f66f451Sopenharmony_ci  }
17550f66f451Sopenharmony_ci
17560f66f451Sopenharmony_ci  dict_put(&s->dict, (uint8_t)symbol);
17570f66f451Sopenharmony_ci  lzma_state_literal(&s->lzma.state);
17580f66f451Sopenharmony_ci}
17590f66f451Sopenharmony_ci
17600f66f451Sopenharmony_ci/* Decode the length of the match into s->lzma.len. */
17610f66f451Sopenharmony_cistatic void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l,
17620f66f451Sopenharmony_ci         uint32_t pos_state)
17630f66f451Sopenharmony_ci{
17640f66f451Sopenharmony_ci  uint16_t *probs;
17650f66f451Sopenharmony_ci  uint32_t limit;
17660f66f451Sopenharmony_ci
17670f66f451Sopenharmony_ci  if (!rc_bit(&s->rc, &l->choice)) {
17680f66f451Sopenharmony_ci    probs = l->low[pos_state];
17690f66f451Sopenharmony_ci    limit = LEN_LOW_SYMBOLS;
17700f66f451Sopenharmony_ci    s->lzma.len = MATCH_LEN_MIN;
17710f66f451Sopenharmony_ci  } else {
17720f66f451Sopenharmony_ci    if (!rc_bit(&s->rc, &l->choice2)) {
17730f66f451Sopenharmony_ci      probs = l->mid[pos_state];
17740f66f451Sopenharmony_ci      limit = LEN_MID_SYMBOLS;
17750f66f451Sopenharmony_ci      s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
17760f66f451Sopenharmony_ci    } else {
17770f66f451Sopenharmony_ci      probs = l->high;
17780f66f451Sopenharmony_ci      limit = LEN_HIGH_SYMBOLS;
17790f66f451Sopenharmony_ci      s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS
17800f66f451Sopenharmony_ci          + LEN_MID_SYMBOLS;
17810f66f451Sopenharmony_ci    }
17820f66f451Sopenharmony_ci  }
17830f66f451Sopenharmony_ci
17840f66f451Sopenharmony_ci  s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit;
17850f66f451Sopenharmony_ci}
17860f66f451Sopenharmony_ci
17870f66f451Sopenharmony_ci/* Decode a match. The distance will be stored in s->lzma.rep0. */
17880f66f451Sopenharmony_cistatic void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
17890f66f451Sopenharmony_ci{
17900f66f451Sopenharmony_ci  uint16_t *probs;
17910f66f451Sopenharmony_ci  uint32_t dist_slot;
17920f66f451Sopenharmony_ci  uint32_t limit;
17930f66f451Sopenharmony_ci
17940f66f451Sopenharmony_ci  lzma_state_match(&s->lzma.state);
17950f66f451Sopenharmony_ci
17960f66f451Sopenharmony_ci  s->lzma.rep3 = s->lzma.rep2;
17970f66f451Sopenharmony_ci  s->lzma.rep2 = s->lzma.rep1;
17980f66f451Sopenharmony_ci  s->lzma.rep1 = s->lzma.rep0;
17990f66f451Sopenharmony_ci
18000f66f451Sopenharmony_ci  lzma_len(s, &s->lzma.match_len_dec, pos_state);
18010f66f451Sopenharmony_ci
18020f66f451Sopenharmony_ci  probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
18030f66f451Sopenharmony_ci  dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
18040f66f451Sopenharmony_ci
18050f66f451Sopenharmony_ci  if (dist_slot < DIST_MODEL_START) {
18060f66f451Sopenharmony_ci    s->lzma.rep0 = dist_slot;
18070f66f451Sopenharmony_ci  } else {
18080f66f451Sopenharmony_ci    limit = (dist_slot >> 1) - 1;
18090f66f451Sopenharmony_ci    s->lzma.rep0 = 2 + (dist_slot & 1);
18100f66f451Sopenharmony_ci
18110f66f451Sopenharmony_ci    if (dist_slot < DIST_MODEL_END) {
18120f66f451Sopenharmony_ci      s->lzma.rep0 <<= limit;
18130f66f451Sopenharmony_ci      probs = s->lzma.dist_special + s->lzma.rep0
18140f66f451Sopenharmony_ci          - dist_slot - 1;
18150f66f451Sopenharmony_ci      rc_bittree_reverse(&s->rc, probs,
18160f66f451Sopenharmony_ci          &s->lzma.rep0, limit);
18170f66f451Sopenharmony_ci    } else {
18180f66f451Sopenharmony_ci      rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
18190f66f451Sopenharmony_ci      s->lzma.rep0 <<= ALIGN_BITS;
18200f66f451Sopenharmony_ci      rc_bittree_reverse(&s->rc, s->lzma.dist_align,
18210f66f451Sopenharmony_ci          &s->lzma.rep0, ALIGN_BITS);
18220f66f451Sopenharmony_ci    }
18230f66f451Sopenharmony_ci  }
18240f66f451Sopenharmony_ci}
18250f66f451Sopenharmony_ci
18260f66f451Sopenharmony_ci/*
18270f66f451Sopenharmony_ci * Decode a repeated match. The distance is one of the four most recently
18280f66f451Sopenharmony_ci * seen matches. The distance will be stored in s->lzma.rep0.
18290f66f451Sopenharmony_ci */
18300f66f451Sopenharmony_cistatic void lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
18310f66f451Sopenharmony_ci{
18320f66f451Sopenharmony_ci  uint32_t tmp;
18330f66f451Sopenharmony_ci
18340f66f451Sopenharmony_ci  if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) {
18350f66f451Sopenharmony_ci    if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[
18360f66f451Sopenharmony_ci        s->lzma.state][pos_state])) {
18370f66f451Sopenharmony_ci      lzma_state_short_rep(&s->lzma.state);
18380f66f451Sopenharmony_ci      s->lzma.len = 1;
18390f66f451Sopenharmony_ci      return;
18400f66f451Sopenharmony_ci    }
18410f66f451Sopenharmony_ci  } else {
18420f66f451Sopenharmony_ci    if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) {
18430f66f451Sopenharmony_ci      tmp = s->lzma.rep1;
18440f66f451Sopenharmony_ci    } else {
18450f66f451Sopenharmony_ci      if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) {
18460f66f451Sopenharmony_ci        tmp = s->lzma.rep2;
18470f66f451Sopenharmony_ci      } else {
18480f66f451Sopenharmony_ci        tmp = s->lzma.rep3;
18490f66f451Sopenharmony_ci        s->lzma.rep3 = s->lzma.rep2;
18500f66f451Sopenharmony_ci      }
18510f66f451Sopenharmony_ci
18520f66f451Sopenharmony_ci      s->lzma.rep2 = s->lzma.rep1;
18530f66f451Sopenharmony_ci    }
18540f66f451Sopenharmony_ci
18550f66f451Sopenharmony_ci    s->lzma.rep1 = s->lzma.rep0;
18560f66f451Sopenharmony_ci    s->lzma.rep0 = tmp;
18570f66f451Sopenharmony_ci  }
18580f66f451Sopenharmony_ci
18590f66f451Sopenharmony_ci  lzma_state_long_rep(&s->lzma.state);
18600f66f451Sopenharmony_ci  lzma_len(s, &s->lzma.rep_len_dec, pos_state);
18610f66f451Sopenharmony_ci}
18620f66f451Sopenharmony_ci
18630f66f451Sopenharmony_ci/* LZMA decoder core */
18640f66f451Sopenharmony_cistatic int lzma_main(struct xz_dec_lzma2 *s)
18650f66f451Sopenharmony_ci{
18660f66f451Sopenharmony_ci  uint32_t pos_state;
18670f66f451Sopenharmony_ci
18680f66f451Sopenharmony_ci  /*
18690f66f451Sopenharmony_ci   * If the dictionary was reached during the previous call, try to
18700f66f451Sopenharmony_ci   * finish the possibly pending repeat in the dictionary.
18710f66f451Sopenharmony_ci   */
18720f66f451Sopenharmony_ci  if (dict_has_space(&s->dict) && s->lzma.len > 0)
18730f66f451Sopenharmony_ci    dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0);
18740f66f451Sopenharmony_ci
18750f66f451Sopenharmony_ci  /*
18760f66f451Sopenharmony_ci   * Decode more LZMA symbols. One iteration may consume up to
18770f66f451Sopenharmony_ci   * LZMA_IN_REQUIRED - 1 bytes.
18780f66f451Sopenharmony_ci   */
18790f66f451Sopenharmony_ci  while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) {
18800f66f451Sopenharmony_ci    pos_state = s->dict.pos & s->lzma.pos_mask;
18810f66f451Sopenharmony_ci
18820f66f451Sopenharmony_ci    if (!rc_bit(&s->rc, &s->lzma.is_match[
18830f66f451Sopenharmony_ci        s->lzma.state][pos_state])) {
18840f66f451Sopenharmony_ci      lzma_literal(s);
18850f66f451Sopenharmony_ci    } else {
18860f66f451Sopenharmony_ci      if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
18870f66f451Sopenharmony_ci        lzma_rep_match(s, pos_state);
18880f66f451Sopenharmony_ci      else
18890f66f451Sopenharmony_ci        lzma_match(s, pos_state);
18900f66f451Sopenharmony_ci
18910f66f451Sopenharmony_ci      if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0))
18920f66f451Sopenharmony_ci        return 0;
18930f66f451Sopenharmony_ci    }
18940f66f451Sopenharmony_ci  }
18950f66f451Sopenharmony_ci
18960f66f451Sopenharmony_ci  /*
18970f66f451Sopenharmony_ci   * Having the range decoder always normalized when we are outside
18980f66f451Sopenharmony_ci   * this function makes it easier to correctly handle end of the chunk.
18990f66f451Sopenharmony_ci   */
19000f66f451Sopenharmony_ci  rc_normalize(&s->rc);
19010f66f451Sopenharmony_ci
19020f66f451Sopenharmony_ci  return 1;
19030f66f451Sopenharmony_ci}
19040f66f451Sopenharmony_ci
19050f66f451Sopenharmony_ci/*
19060f66f451Sopenharmony_ci * Reset the LZMA decoder and range decoder state. Dictionary is nore reset
19070f66f451Sopenharmony_ci * here, because LZMA state may be reset without resetting the dictionary.
19080f66f451Sopenharmony_ci */
19090f66f451Sopenharmony_cistatic void lzma_reset(struct xz_dec_lzma2 *s)
19100f66f451Sopenharmony_ci{
19110f66f451Sopenharmony_ci  uint16_t *probs;
19120f66f451Sopenharmony_ci  size_t i;
19130f66f451Sopenharmony_ci
19140f66f451Sopenharmony_ci  s->lzma.state = STATE_LIT_LIT;
19150f66f451Sopenharmony_ci  s->lzma.rep0 = 0;
19160f66f451Sopenharmony_ci  s->lzma.rep1 = 0;
19170f66f451Sopenharmony_ci  s->lzma.rep2 = 0;
19180f66f451Sopenharmony_ci  s->lzma.rep3 = 0;
19190f66f451Sopenharmony_ci
19200f66f451Sopenharmony_ci  /*
19210f66f451Sopenharmony_ci   * All probabilities are initialized to the same value. This hack
19220f66f451Sopenharmony_ci   * makes the code smaller by avoiding a separate loop for each
19230f66f451Sopenharmony_ci   * probability array.
19240f66f451Sopenharmony_ci   *
19250f66f451Sopenharmony_ci   * This could be optimized so that only that part of literal
19260f66f451Sopenharmony_ci   * probabilities that are actually required. In the common case
19270f66f451Sopenharmony_ci   * we would write 12 KiB less.
19280f66f451Sopenharmony_ci   */
19290f66f451Sopenharmony_ci  probs = s->lzma.is_match[0];
19300f66f451Sopenharmony_ci  for (i = 0; i < PROBS_TOTAL; ++i)
19310f66f451Sopenharmony_ci    probs[i] = RC_BIT_MODEL_TOTAL / 2;
19320f66f451Sopenharmony_ci
19330f66f451Sopenharmony_ci  rc_reset(&s->rc);
19340f66f451Sopenharmony_ci}
19350f66f451Sopenharmony_ci
19360f66f451Sopenharmony_ci/*
19370f66f451Sopenharmony_ci * Decode and validate LZMA properties (lc/lp/pb) and calculate the bit masks
19380f66f451Sopenharmony_ci * from the decoded lp and pb values. On success, the LZMA decoder state is
19390f66f451Sopenharmony_ci * reset and true is returned.
19400f66f451Sopenharmony_ci */
19410f66f451Sopenharmony_cistatic int lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
19420f66f451Sopenharmony_ci{
19430f66f451Sopenharmony_ci  if (props > (4 * 5 + 4) * 9 + 8)
19440f66f451Sopenharmony_ci    return 0;
19450f66f451Sopenharmony_ci
19460f66f451Sopenharmony_ci  s->lzma.pos_mask = 0;
19470f66f451Sopenharmony_ci  while (props >= 9 * 5) {
19480f66f451Sopenharmony_ci    props -= 9 * 5;
19490f66f451Sopenharmony_ci    ++s->lzma.pos_mask;
19500f66f451Sopenharmony_ci  }
19510f66f451Sopenharmony_ci
19520f66f451Sopenharmony_ci  s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
19530f66f451Sopenharmony_ci
19540f66f451Sopenharmony_ci  s->lzma.literal_pos_mask = 0;
19550f66f451Sopenharmony_ci  while (props >= 9) {
19560f66f451Sopenharmony_ci    props -= 9;
19570f66f451Sopenharmony_ci    ++s->lzma.literal_pos_mask;
19580f66f451Sopenharmony_ci  }
19590f66f451Sopenharmony_ci
19600f66f451Sopenharmony_ci  s->lzma.lc = props;
19610f66f451Sopenharmony_ci
19620f66f451Sopenharmony_ci  if (s->lzma.lc + s->lzma.literal_pos_mask > 4)
19630f66f451Sopenharmony_ci    return 0;
19640f66f451Sopenharmony_ci
19650f66f451Sopenharmony_ci  s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1;
19660f66f451Sopenharmony_ci
19670f66f451Sopenharmony_ci  lzma_reset(s);
19680f66f451Sopenharmony_ci
19690f66f451Sopenharmony_ci  return 1;
19700f66f451Sopenharmony_ci}
19710f66f451Sopenharmony_ci
19720f66f451Sopenharmony_ci/*********
19730f66f451Sopenharmony_ci * LZMA2 *
19740f66f451Sopenharmony_ci *********/
19750f66f451Sopenharmony_ci
19760f66f451Sopenharmony_ci/*
19770f66f451Sopenharmony_ci * The LZMA decoder assumes that if the input limit (s->rc.in_limit) hasn't
19780f66f451Sopenharmony_ci * been exceeded, it is safe to read up to LZMA_IN_REQUIRED bytes. This
19790f66f451Sopenharmony_ci * wrapper function takes care of making the LZMA decoder's assumption safe.
19800f66f451Sopenharmony_ci *
19810f66f451Sopenharmony_ci * As long as there is plenty of input left to be decoded in the current LZMA
19820f66f451Sopenharmony_ci * chunk, we decode directly from the caller-supplied input buffer until
19830f66f451Sopenharmony_ci * there's LZMA_IN_REQUIRED bytes left. Those remaining bytes are copied into
19840f66f451Sopenharmony_ci * s->temp.buf, which (hopefully) gets filled on the next call to this
19850f66f451Sopenharmony_ci * function. We decode a few bytes from the temporary buffer so that we can
19860f66f451Sopenharmony_ci * continue decoding from the caller-supplied input buffer again.
19870f66f451Sopenharmony_ci */
19880f66f451Sopenharmony_cistatic int lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
19890f66f451Sopenharmony_ci{
19900f66f451Sopenharmony_ci  size_t in_avail;
19910f66f451Sopenharmony_ci  uint32_t tmp;
19920f66f451Sopenharmony_ci
19930f66f451Sopenharmony_ci  in_avail = b->in_size - b->in_pos;
19940f66f451Sopenharmony_ci  if (s->temp.size > 0 || s->lzma2.compressed == 0) {
19950f66f451Sopenharmony_ci    tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
19960f66f451Sopenharmony_ci    if (tmp > s->lzma2.compressed - s->temp.size)
19970f66f451Sopenharmony_ci      tmp = s->lzma2.compressed - s->temp.size;
19980f66f451Sopenharmony_ci    if (tmp > in_avail)
19990f66f451Sopenharmony_ci      tmp = in_avail;
20000f66f451Sopenharmony_ci
20010f66f451Sopenharmony_ci    memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
20020f66f451Sopenharmony_ci
20030f66f451Sopenharmony_ci    if (s->temp.size + tmp == s->lzma2.compressed) {
20040f66f451Sopenharmony_ci      memset(s->temp.buf + s->temp.size + tmp, 0,
20050f66f451Sopenharmony_ci          sizeof(s->temp.buf)
20060f66f451Sopenharmony_ci            - s->temp.size - tmp);
20070f66f451Sopenharmony_ci      s->rc.in_limit = s->temp.size + tmp;
20080f66f451Sopenharmony_ci    } else if (s->temp.size + tmp < LZMA_IN_REQUIRED) {
20090f66f451Sopenharmony_ci      s->temp.size += tmp;
20100f66f451Sopenharmony_ci      b->in_pos += tmp;
20110f66f451Sopenharmony_ci      return 1;
20120f66f451Sopenharmony_ci    } else {
20130f66f451Sopenharmony_ci      s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
20140f66f451Sopenharmony_ci    }
20150f66f451Sopenharmony_ci
20160f66f451Sopenharmony_ci    s->rc.in = s->temp.buf;
20170f66f451Sopenharmony_ci    s->rc.in_pos = 0;
20180f66f451Sopenharmony_ci
20190f66f451Sopenharmony_ci    if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp)
20200f66f451Sopenharmony_ci      return 0;
20210f66f451Sopenharmony_ci
20220f66f451Sopenharmony_ci    s->lzma2.compressed -= s->rc.in_pos;
20230f66f451Sopenharmony_ci
20240f66f451Sopenharmony_ci    if (s->rc.in_pos < s->temp.size) {
20250f66f451Sopenharmony_ci      s->temp.size -= s->rc.in_pos;
20260f66f451Sopenharmony_ci      memmove(s->temp.buf, s->temp.buf + s->rc.in_pos,
20270f66f451Sopenharmony_ci          s->temp.size);
20280f66f451Sopenharmony_ci      return 1;
20290f66f451Sopenharmony_ci    }
20300f66f451Sopenharmony_ci
20310f66f451Sopenharmony_ci    b->in_pos += s->rc.in_pos - s->temp.size;
20320f66f451Sopenharmony_ci    s->temp.size = 0;
20330f66f451Sopenharmony_ci  }
20340f66f451Sopenharmony_ci
20350f66f451Sopenharmony_ci  in_avail = b->in_size - b->in_pos;
20360f66f451Sopenharmony_ci  if (in_avail >= LZMA_IN_REQUIRED) {
20370f66f451Sopenharmony_ci    s->rc.in = b->in;
20380f66f451Sopenharmony_ci    s->rc.in_pos = b->in_pos;
20390f66f451Sopenharmony_ci
20400f66f451Sopenharmony_ci    if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED)
20410f66f451Sopenharmony_ci      s->rc.in_limit = b->in_pos + s->lzma2.compressed;
20420f66f451Sopenharmony_ci    else
20430f66f451Sopenharmony_ci      s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED;
20440f66f451Sopenharmony_ci
20450f66f451Sopenharmony_ci    if (!lzma_main(s))
20460f66f451Sopenharmony_ci      return 0;
20470f66f451Sopenharmony_ci
20480f66f451Sopenharmony_ci    in_avail = s->rc.in_pos - b->in_pos;
20490f66f451Sopenharmony_ci    if (in_avail > s->lzma2.compressed) return 0;
20500f66f451Sopenharmony_ci
20510f66f451Sopenharmony_ci    s->lzma2.compressed -= in_avail;
20520f66f451Sopenharmony_ci    b->in_pos = s->rc.in_pos;
20530f66f451Sopenharmony_ci  }
20540f66f451Sopenharmony_ci
20550f66f451Sopenharmony_ci  in_avail = b->in_size - b->in_pos;
20560f66f451Sopenharmony_ci  if (in_avail < LZMA_IN_REQUIRED) {
20570f66f451Sopenharmony_ci    if (in_avail > s->lzma2.compressed)
20580f66f451Sopenharmony_ci      in_avail = s->lzma2.compressed;
20590f66f451Sopenharmony_ci
20600f66f451Sopenharmony_ci    memcpy(s->temp.buf, b->in + b->in_pos, in_avail);
20610f66f451Sopenharmony_ci    s->temp.size = in_avail;
20620f66f451Sopenharmony_ci    b->in_pos += in_avail;
20630f66f451Sopenharmony_ci  }
20640f66f451Sopenharmony_ci
20650f66f451Sopenharmony_ci  return 1;
20660f66f451Sopenharmony_ci}
20670f66f451Sopenharmony_ci
20680f66f451Sopenharmony_ci/*
20690f66f451Sopenharmony_ci * Take care of the LZMA2 control layer, and forward the job of actual LZMA
20700f66f451Sopenharmony_ci * decoding or copying of uncompressed chunks to other functions.
20710f66f451Sopenharmony_ci */
20720f66f451Sopenharmony_cienum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
20730f66f451Sopenharmony_ci               struct xz_buf *b)
20740f66f451Sopenharmony_ci{
20750f66f451Sopenharmony_ci  uint32_t tmp;
20760f66f451Sopenharmony_ci
20770f66f451Sopenharmony_ci  while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) {
20780f66f451Sopenharmony_ci    switch (s->lzma2.sequence) {
20790f66f451Sopenharmony_ci    case SEQ_CONTROL:
20800f66f451Sopenharmony_ci      /*
20810f66f451Sopenharmony_ci       * LZMA2 control byte
20820f66f451Sopenharmony_ci       *
20830f66f451Sopenharmony_ci       * Exact values:
20840f66f451Sopenharmony_ci       *   0x00   End marker
20850f66f451Sopenharmony_ci       *   0x01   Dictionary reset followed by
20860f66f451Sopenharmony_ci       *          an uncompressed chunk
20870f66f451Sopenharmony_ci       *   0x02   Uncompressed chunk (no dictionary reset)
20880f66f451Sopenharmony_ci       *
20890f66f451Sopenharmony_ci       * Highest three bits (s->control & 0xE0):
20900f66f451Sopenharmony_ci       *   0xE0   Dictionary reset, new properties and state
20910f66f451Sopenharmony_ci       *          reset, followed by LZMA compressed chunk
20920f66f451Sopenharmony_ci       *   0xC0   New properties and state reset, followed
20930f66f451Sopenharmony_ci       *          by LZMA compressed chunk (no dictionary
20940f66f451Sopenharmony_ci       *          reset)
20950f66f451Sopenharmony_ci       *   0xA0   State reset using old properties,
20960f66f451Sopenharmony_ci       *          followed by LZMA compressed chunk (no
20970f66f451Sopenharmony_ci       *          dictionary reset)
20980f66f451Sopenharmony_ci       *   0x80   LZMA chunk (no dictionary or state reset)
20990f66f451Sopenharmony_ci       *
21000f66f451Sopenharmony_ci       * For LZMA compressed chunks, the lowest five bits
21010f66f451Sopenharmony_ci       * (s->control & 1F) are the highest bits of the
21020f66f451Sopenharmony_ci       * uncompressed size (bits 16-20).
21030f66f451Sopenharmony_ci       *
21040f66f451Sopenharmony_ci       * A new LZMA2 stream must begin with a dictionary
21050f66f451Sopenharmony_ci       * reset. The first LZMA chunk must set new
21060f66f451Sopenharmony_ci       * properties and reset the LZMA state.
21070f66f451Sopenharmony_ci       *
21080f66f451Sopenharmony_ci       * Values that don't match anything described above
21090f66f451Sopenharmony_ci       * are invalid and we return XZ_DATA_ERROR.
21100f66f451Sopenharmony_ci       */
21110f66f451Sopenharmony_ci      tmp = b->in[b->in_pos++];
21120f66f451Sopenharmony_ci
21130f66f451Sopenharmony_ci      if (tmp == 0x00)
21140f66f451Sopenharmony_ci        return XZ_STREAM_END;
21150f66f451Sopenharmony_ci
21160f66f451Sopenharmony_ci      if (tmp >= 0xE0 || tmp == 0x01) {
21170f66f451Sopenharmony_ci        s->lzma2.need_props = 1;
21180f66f451Sopenharmony_ci        s->lzma2.need_dict_reset = 0;
21190f66f451Sopenharmony_ci        dict_reset(&s->dict);
21200f66f451Sopenharmony_ci      } else if (s->lzma2.need_dict_reset) {
21210f66f451Sopenharmony_ci        return XZ_DATA_ERROR;
21220f66f451Sopenharmony_ci      }
21230f66f451Sopenharmony_ci
21240f66f451Sopenharmony_ci      if (tmp >= 0x80) {
21250f66f451Sopenharmony_ci        s->lzma2.uncompressed = (tmp & 0x1F) << 16;
21260f66f451Sopenharmony_ci        s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
21270f66f451Sopenharmony_ci
21280f66f451Sopenharmony_ci        if (tmp >= 0xC0) {
21290f66f451Sopenharmony_ci          /*
21300f66f451Sopenharmony_ci           * When there are new properties,
21310f66f451Sopenharmony_ci           * state reset is done at
21320f66f451Sopenharmony_ci           * SEQ_PROPERTIES.
21330f66f451Sopenharmony_ci           */
21340f66f451Sopenharmony_ci          s->lzma2.need_props = 0;
21350f66f451Sopenharmony_ci          s->lzma2.next_sequence
21360f66f451Sopenharmony_ci              = SEQ_PROPERTIES;
21370f66f451Sopenharmony_ci
21380f66f451Sopenharmony_ci        } else if (s->lzma2.need_props) {
21390f66f451Sopenharmony_ci          return XZ_DATA_ERROR;
21400f66f451Sopenharmony_ci
21410f66f451Sopenharmony_ci        } else {
21420f66f451Sopenharmony_ci          s->lzma2.next_sequence
21430f66f451Sopenharmony_ci              = SEQ_LZMA_PREPARE;
21440f66f451Sopenharmony_ci          if (tmp >= 0xA0)
21450f66f451Sopenharmony_ci            lzma_reset(s);
21460f66f451Sopenharmony_ci        }
21470f66f451Sopenharmony_ci      } else {
21480f66f451Sopenharmony_ci        if (tmp > 0x02)
21490f66f451Sopenharmony_ci          return XZ_DATA_ERROR;
21500f66f451Sopenharmony_ci
21510f66f451Sopenharmony_ci        s->lzma2.sequence = SEQ_COMPRESSED_0;
21520f66f451Sopenharmony_ci        s->lzma2.next_sequence = SEQ_COPY;
21530f66f451Sopenharmony_ci      }
21540f66f451Sopenharmony_ci
21550f66f451Sopenharmony_ci      break;
21560f66f451Sopenharmony_ci
21570f66f451Sopenharmony_ci    case SEQ_UNCOMPRESSED_1:
21580f66f451Sopenharmony_ci      s->lzma2.uncompressed
21590f66f451Sopenharmony_ci          += (uint32_t)b->in[b->in_pos++] << 8;
21600f66f451Sopenharmony_ci      s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
21610f66f451Sopenharmony_ci      break;
21620f66f451Sopenharmony_ci
21630f66f451Sopenharmony_ci    case SEQ_UNCOMPRESSED_2:
21640f66f451Sopenharmony_ci      s->lzma2.uncompressed
21650f66f451Sopenharmony_ci          += (uint32_t)b->in[b->in_pos++] + 1;
21660f66f451Sopenharmony_ci      s->lzma2.sequence = SEQ_COMPRESSED_0;
21670f66f451Sopenharmony_ci      break;
21680f66f451Sopenharmony_ci
21690f66f451Sopenharmony_ci    case SEQ_COMPRESSED_0:
21700f66f451Sopenharmony_ci      s->lzma2.compressed
21710f66f451Sopenharmony_ci          = (uint32_t)b->in[b->in_pos++] << 8;
21720f66f451Sopenharmony_ci      s->lzma2.sequence = SEQ_COMPRESSED_1;
21730f66f451Sopenharmony_ci      break;
21740f66f451Sopenharmony_ci
21750f66f451Sopenharmony_ci    case SEQ_COMPRESSED_1:
21760f66f451Sopenharmony_ci      s->lzma2.compressed
21770f66f451Sopenharmony_ci          += (uint32_t)b->in[b->in_pos++] + 1;
21780f66f451Sopenharmony_ci      s->lzma2.sequence = s->lzma2.next_sequence;
21790f66f451Sopenharmony_ci      break;
21800f66f451Sopenharmony_ci
21810f66f451Sopenharmony_ci    case SEQ_PROPERTIES:
21820f66f451Sopenharmony_ci      if (!lzma_props(s, b->in[b->in_pos++]))
21830f66f451Sopenharmony_ci        return XZ_DATA_ERROR;
21840f66f451Sopenharmony_ci
21850f66f451Sopenharmony_ci      s->lzma2.sequence = SEQ_LZMA_PREPARE;
21860f66f451Sopenharmony_ci
21870f66f451Sopenharmony_ci    case SEQ_LZMA_PREPARE:
21880f66f451Sopenharmony_ci      if (s->lzma2.compressed < RC_INIT_BYTES)
21890f66f451Sopenharmony_ci        return XZ_DATA_ERROR;
21900f66f451Sopenharmony_ci
21910f66f451Sopenharmony_ci      if (!rc_read_init(&s->rc, b))
21920f66f451Sopenharmony_ci        return XZ_OK;
21930f66f451Sopenharmony_ci
21940f66f451Sopenharmony_ci      s->lzma2.compressed -= RC_INIT_BYTES;
21950f66f451Sopenharmony_ci      s->lzma2.sequence = SEQ_LZMA_RUN;
21960f66f451Sopenharmony_ci
21970f66f451Sopenharmony_ci    case SEQ_LZMA_RUN:
21980f66f451Sopenharmony_ci      /*
21990f66f451Sopenharmony_ci       * Set dictionary limit to indicate how much we want
22000f66f451Sopenharmony_ci       * to be encoded at maximum. Decode new data into the
22010f66f451Sopenharmony_ci       * dictionary. Flush the new data from dictionary to
22020f66f451Sopenharmony_ci       * b->out. Check if we finished decoding this chunk.
22030f66f451Sopenharmony_ci       * In case the dictionary got full but we didn't fill
22040f66f451Sopenharmony_ci       * the output buffer yet, we may run this loop
22050f66f451Sopenharmony_ci       * multiple times without changing s->lzma2.sequence.
22060f66f451Sopenharmony_ci       */
22070f66f451Sopenharmony_ci      dict_limit(&s->dict, minof(b->out_size - b->out_pos,
22080f66f451Sopenharmony_ci          s->lzma2.uncompressed));
22090f66f451Sopenharmony_ci      if (!lzma2_lzma(s, b))
22100f66f451Sopenharmony_ci        return XZ_DATA_ERROR;
22110f66f451Sopenharmony_ci
22120f66f451Sopenharmony_ci      s->lzma2.uncompressed -= dict_flush(&s->dict, b);
22130f66f451Sopenharmony_ci
22140f66f451Sopenharmony_ci      if (s->lzma2.uncompressed == 0) {
22150f66f451Sopenharmony_ci        if (s->lzma2.compressed > 0 || s->lzma.len > 0
22160f66f451Sopenharmony_ci            || !rc_is_finished(&s->rc))
22170f66f451Sopenharmony_ci          return XZ_DATA_ERROR;
22180f66f451Sopenharmony_ci
22190f66f451Sopenharmony_ci        rc_reset(&s->rc);
22200f66f451Sopenharmony_ci        s->lzma2.sequence = SEQ_CONTROL;
22210f66f451Sopenharmony_ci
22220f66f451Sopenharmony_ci      } else if (b->out_pos == b->out_size
22230f66f451Sopenharmony_ci          || (b->in_pos == b->in_size
22240f66f451Sopenharmony_ci            && s->temp.size
22250f66f451Sopenharmony_ci            < s->lzma2.compressed)) {
22260f66f451Sopenharmony_ci        return XZ_OK;
22270f66f451Sopenharmony_ci      }
22280f66f451Sopenharmony_ci
22290f66f451Sopenharmony_ci      break;
22300f66f451Sopenharmony_ci
22310f66f451Sopenharmony_ci    case SEQ_COPY:
22320f66f451Sopenharmony_ci      dict_uncompressed(&s->dict, b, &s->lzma2.compressed);
22330f66f451Sopenharmony_ci      if (s->lzma2.compressed > 0)
22340f66f451Sopenharmony_ci        return XZ_OK;
22350f66f451Sopenharmony_ci
22360f66f451Sopenharmony_ci      s->lzma2.sequence = SEQ_CONTROL;
22370f66f451Sopenharmony_ci      break;
22380f66f451Sopenharmony_ci    }
22390f66f451Sopenharmony_ci  }
22400f66f451Sopenharmony_ci
22410f66f451Sopenharmony_ci  return XZ_OK;
22420f66f451Sopenharmony_ci}
22430f66f451Sopenharmony_ci
22440f66f451Sopenharmony_cistruct xz_dec_lzma2 *xz_dec_lzma2_create(uint32_t dict_max)
22450f66f451Sopenharmony_ci{
22460f66f451Sopenharmony_ci  struct xz_dec_lzma2 *s = malloc(sizeof(*s));
22470f66f451Sopenharmony_ci  if (s == NULL)
22480f66f451Sopenharmony_ci    return NULL;
22490f66f451Sopenharmony_ci
22500f66f451Sopenharmony_ci  s->dict.size_max = dict_max;
22510f66f451Sopenharmony_ci  s->dict.buf = NULL;
22520f66f451Sopenharmony_ci  s->dict.allocated = 0;
22530f66f451Sopenharmony_ci
22540f66f451Sopenharmony_ci  return s;
22550f66f451Sopenharmony_ci}
22560f66f451Sopenharmony_ci
22570f66f451Sopenharmony_cienum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props)
22580f66f451Sopenharmony_ci{
22590f66f451Sopenharmony_ci  /* This limits dictionary size to 3 GiB to keep parsing simpler. */
22600f66f451Sopenharmony_ci  if (props > 39)
22610f66f451Sopenharmony_ci    return XZ_OPTIONS_ERROR;
22620f66f451Sopenharmony_ci
22630f66f451Sopenharmony_ci  s->dict.size = 2 + (props & 1);
22640f66f451Sopenharmony_ci  s->dict.size <<= (props >> 1) + 11;
22650f66f451Sopenharmony_ci
22660f66f451Sopenharmony_ci  if (s->dict.size > s->dict.size_max)
22670f66f451Sopenharmony_ci    return XZ_MEMLIMIT_ERROR;
22680f66f451Sopenharmony_ci
22690f66f451Sopenharmony_ci  s->dict.end = s->dict.size;
22700f66f451Sopenharmony_ci
22710f66f451Sopenharmony_ci  if (s->dict.allocated < s->dict.size) {
22720f66f451Sopenharmony_ci    free(s->dict.buf);
22730f66f451Sopenharmony_ci    s->dict.buf = malloc(s->dict.size);
22740f66f451Sopenharmony_ci    if (s->dict.buf == NULL) {
22750f66f451Sopenharmony_ci      s->dict.allocated = 0;
22760f66f451Sopenharmony_ci      return XZ_MEM_ERROR;
22770f66f451Sopenharmony_ci    }
22780f66f451Sopenharmony_ci  }
22790f66f451Sopenharmony_ci
22800f66f451Sopenharmony_ci  s->lzma.len = 0;
22810f66f451Sopenharmony_ci
22820f66f451Sopenharmony_ci  s->lzma2.sequence = SEQ_CONTROL;
22830f66f451Sopenharmony_ci  s->lzma2.need_dict_reset = 1;
22840f66f451Sopenharmony_ci
22850f66f451Sopenharmony_ci  s->temp.size = 0;
22860f66f451Sopenharmony_ci
22870f66f451Sopenharmony_ci  return XZ_OK;
22880f66f451Sopenharmony_ci}
22890f66f451Sopenharmony_ci
22900f66f451Sopenharmony_ci/*
22910f66f451Sopenharmony_ci * .xz Stream decoder
22920f66f451Sopenharmony_ci */
22930f66f451Sopenharmony_ci
22940f66f451Sopenharmony_ci
22950f66f451Sopenharmony_ci// BEGIN xz_stream.h
22960f66f451Sopenharmony_ci/*
22970f66f451Sopenharmony_ci * Definitions for handling the .xz file format
22980f66f451Sopenharmony_ci */
22990f66f451Sopenharmony_ci
23000f66f451Sopenharmony_ci/*
23010f66f451Sopenharmony_ci * See the .xz file format specification at
23020f66f451Sopenharmony_ci * http://tukaani.org/xz/xz-file-format.txt
23030f66f451Sopenharmony_ci * to understand the container format.
23040f66f451Sopenharmony_ci */
23050f66f451Sopenharmony_ci
23060f66f451Sopenharmony_ci#define STREAM_HEADER_SIZE 12
23070f66f451Sopenharmony_ci
23080f66f451Sopenharmony_ci#define HEADER_MAGIC "\3757zXZ"
23090f66f451Sopenharmony_ci#define HEADER_MAGIC_SIZE 6
23100f66f451Sopenharmony_ci
23110f66f451Sopenharmony_ci#define FOOTER_MAGIC "YZ"
23120f66f451Sopenharmony_ci#define FOOTER_MAGIC_SIZE 2
23130f66f451Sopenharmony_ci
23140f66f451Sopenharmony_ci/*
23150f66f451Sopenharmony_ci * Variable-length integer can hold a 63-bit unsigned integer or a special
23160f66f451Sopenharmony_ci * value indicating that the value is unknown.
23170f66f451Sopenharmony_ci *
23180f66f451Sopenharmony_ci * Experimental: vli_type can be defined to uint32_t to save a few bytes
23190f66f451Sopenharmony_ci * in code size (no effect on speed). Doing so limits the uncompressed and
23200f66f451Sopenharmony_ci * compressed size of the file to less than 256 MiB and may also weaken
23210f66f451Sopenharmony_ci * error detection slightly.
23220f66f451Sopenharmony_ci */
23230f66f451Sopenharmony_citypedef uint64_t vli_type;
23240f66f451Sopenharmony_ci
23250f66f451Sopenharmony_ci#define VLI_MAX ((vli_type)-1 / 2)
23260f66f451Sopenharmony_ci#define VLI_UNKNOWN ((vli_type)-1)
23270f66f451Sopenharmony_ci
23280f66f451Sopenharmony_ci/* Maximum encoded size of a VLI */
23290f66f451Sopenharmony_ci#define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7)
23300f66f451Sopenharmony_ci
23310f66f451Sopenharmony_ci/* Integrity Check types */
23320f66f451Sopenharmony_cienum xz_check {
23330f66f451Sopenharmony_ci  XZ_CHECK_NONE = 0,
23340f66f451Sopenharmony_ci  XZ_CHECK_CRC32 = 1,
23350f66f451Sopenharmony_ci  XZ_CHECK_CRC64 = 4,
23360f66f451Sopenharmony_ci  XZ_CHECK_SHA256 = 10
23370f66f451Sopenharmony_ci};
23380f66f451Sopenharmony_ci
23390f66f451Sopenharmony_ci/* Maximum possible Check ID */
23400f66f451Sopenharmony_ci#define XZ_CHECK_MAX 15
23410f66f451Sopenharmony_ci// END xz_stream.h
23420f66f451Sopenharmony_ci
23430f66f451Sopenharmony_ci#define IS_CRC64(check_type) ((check_type) == XZ_CHECK_CRC64)
23440f66f451Sopenharmony_ci
23450f66f451Sopenharmony_ci/* Hash used to validate the Index field */
23460f66f451Sopenharmony_cistruct xz_dec_hash {
23470f66f451Sopenharmony_ci  vli_type unpadded;
23480f66f451Sopenharmony_ci  vli_type uncompressed;
23490f66f451Sopenharmony_ci  uint32_t crc32;
23500f66f451Sopenharmony_ci};
23510f66f451Sopenharmony_ci
23520f66f451Sopenharmony_cistruct xz_dec {
23530f66f451Sopenharmony_ci  /* Position in dec_main() */
23540f66f451Sopenharmony_ci  enum {
23550f66f451Sopenharmony_ci    SEQ_STREAM_HEADER,
23560f66f451Sopenharmony_ci    SEQ_BLOCK_START,
23570f66f451Sopenharmony_ci    SEQ_BLOCK_HEADER,
23580f66f451Sopenharmony_ci    SEQ_BLOCK_UNCOMPRESS,
23590f66f451Sopenharmony_ci    SEQ_BLOCK_PADDING,
23600f66f451Sopenharmony_ci    SEQ_BLOCK_CHECK,
23610f66f451Sopenharmony_ci    SEQ_INDEX,
23620f66f451Sopenharmony_ci    SEQ_INDEX_PADDING,
23630f66f451Sopenharmony_ci    SEQ_INDEX_CRC32,
23640f66f451Sopenharmony_ci    SEQ_STREAM_FOOTER
23650f66f451Sopenharmony_ci  } sequence;
23660f66f451Sopenharmony_ci
23670f66f451Sopenharmony_ci  /* Position in variable-length integers and Check fields */
23680f66f451Sopenharmony_ci  uint32_t pos;
23690f66f451Sopenharmony_ci
23700f66f451Sopenharmony_ci  /* Variable-length integer decoded by dec_vli() */
23710f66f451Sopenharmony_ci  vli_type vli;
23720f66f451Sopenharmony_ci
23730f66f451Sopenharmony_ci  /* Saved in_pos and out_pos */
23740f66f451Sopenharmony_ci  size_t in_start;
23750f66f451Sopenharmony_ci  size_t out_start;
23760f66f451Sopenharmony_ci
23770f66f451Sopenharmony_ci  /* CRC32 or CRC64 value in Block or CRC32 value in Index */
23780f66f451Sopenharmony_ci  uint64_t crc;
23790f66f451Sopenharmony_ci
23800f66f451Sopenharmony_ci  /* Type of the integrity check calculated from uncompressed data */
23810f66f451Sopenharmony_ci  enum xz_check check_type;
23820f66f451Sopenharmony_ci
23830f66f451Sopenharmony_ci  /*
23840f66f451Sopenharmony_ci   * True if the next call to xz_dec_run() is allowed to return
23850f66f451Sopenharmony_ci   * XZ_BUF_ERROR.
23860f66f451Sopenharmony_ci   */
23870f66f451Sopenharmony_ci  int allow_buf_error;
23880f66f451Sopenharmony_ci
23890f66f451Sopenharmony_ci  /* Information stored in Block Header */
23900f66f451Sopenharmony_ci  struct {
23910f66f451Sopenharmony_ci    /*
23920f66f451Sopenharmony_ci     * Value stored in the Compressed Size field, or
23930f66f451Sopenharmony_ci     * VLI_UNKNOWN if Compressed Size is not present.
23940f66f451Sopenharmony_ci     */
23950f66f451Sopenharmony_ci    vli_type compressed;
23960f66f451Sopenharmony_ci
23970f66f451Sopenharmony_ci    /*
23980f66f451Sopenharmony_ci     * Value stored in the Uncompressed Size field, or
23990f66f451Sopenharmony_ci     * VLI_UNKNOWN if Uncompressed Size is not present.
24000f66f451Sopenharmony_ci     */
24010f66f451Sopenharmony_ci    vli_type uncompressed;
24020f66f451Sopenharmony_ci
24030f66f451Sopenharmony_ci    /* Size of the Block Header field */
24040f66f451Sopenharmony_ci    uint32_t size;
24050f66f451Sopenharmony_ci  } block_header;
24060f66f451Sopenharmony_ci
24070f66f451Sopenharmony_ci  /* Information collected when decoding Blocks */
24080f66f451Sopenharmony_ci  struct {
24090f66f451Sopenharmony_ci    /* Observed compressed size of the current Block */
24100f66f451Sopenharmony_ci    vli_type compressed;
24110f66f451Sopenharmony_ci
24120f66f451Sopenharmony_ci    /* Observed uncompressed size of the current Block */
24130f66f451Sopenharmony_ci    vli_type uncompressed;
24140f66f451Sopenharmony_ci
24150f66f451Sopenharmony_ci    /* Number of Blocks decoded so far */
24160f66f451Sopenharmony_ci    vli_type count;
24170f66f451Sopenharmony_ci
24180f66f451Sopenharmony_ci    /*
24190f66f451Sopenharmony_ci     * Hash calculated from the Block sizes. This is used to
24200f66f451Sopenharmony_ci     * validate the Index field.
24210f66f451Sopenharmony_ci     */
24220f66f451Sopenharmony_ci    struct xz_dec_hash hash;
24230f66f451Sopenharmony_ci  } block;
24240f66f451Sopenharmony_ci
24250f66f451Sopenharmony_ci  /* Variables needed when verifying the Index field */
24260f66f451Sopenharmony_ci  struct {
24270f66f451Sopenharmony_ci    /* Position in dec_index() */
24280f66f451Sopenharmony_ci    enum {
24290f66f451Sopenharmony_ci      SEQ_INDEX_COUNT,
24300f66f451Sopenharmony_ci      SEQ_INDEX_UNPADDED,
24310f66f451Sopenharmony_ci      SEQ_INDEX_UNCOMPRESSED
24320f66f451Sopenharmony_ci    } sequence;
24330f66f451Sopenharmony_ci
24340f66f451Sopenharmony_ci    /* Size of the Index in bytes */
24350f66f451Sopenharmony_ci    vli_type size;
24360f66f451Sopenharmony_ci
24370f66f451Sopenharmony_ci    /* Number of Records (matches block.count in valid files) */
24380f66f451Sopenharmony_ci    vli_type count;
24390f66f451Sopenharmony_ci
24400f66f451Sopenharmony_ci    /*
24410f66f451Sopenharmony_ci     * Hash calculated from the Records (matches block.hash in
24420f66f451Sopenharmony_ci     * valid files).
24430f66f451Sopenharmony_ci     */
24440f66f451Sopenharmony_ci    struct xz_dec_hash hash;
24450f66f451Sopenharmony_ci  } index;
24460f66f451Sopenharmony_ci
24470f66f451Sopenharmony_ci  /*
24480f66f451Sopenharmony_ci   * Temporary buffer needed to hold Stream Header, Block Header,
24490f66f451Sopenharmony_ci   * and Stream Footer. The Block Header is the biggest (1 KiB)
24500f66f451Sopenharmony_ci   * so we reserve space according to that. buf[] has to be aligned
24510f66f451Sopenharmony_ci   * to a multiple of four bytes; the size_t variables before it
24520f66f451Sopenharmony_ci   * should guarantee this.
24530f66f451Sopenharmony_ci   */
24540f66f451Sopenharmony_ci  struct {
24550f66f451Sopenharmony_ci    size_t pos;
24560f66f451Sopenharmony_ci    size_t size;
24570f66f451Sopenharmony_ci    uint8_t buf[1024];
24580f66f451Sopenharmony_ci  } temp;
24590f66f451Sopenharmony_ci
24600f66f451Sopenharmony_ci  struct xz_dec_lzma2 *lzma2;
24610f66f451Sopenharmony_ci
24620f66f451Sopenharmony_ci#ifdef XZ_DEC_BCJ
24630f66f451Sopenharmony_ci  struct xz_dec_bcj *bcj;
24640f66f451Sopenharmony_ci  int bcj_active;
24650f66f451Sopenharmony_ci#endif
24660f66f451Sopenharmony_ci};
24670f66f451Sopenharmony_ci
24680f66f451Sopenharmony_ci/* Sizes of the Check field with different Check IDs */
24690f66f451Sopenharmony_cistatic const uint8_t check_sizes[16] = {
24700f66f451Sopenharmony_ci  0,
24710f66f451Sopenharmony_ci  4, 4, 4,
24720f66f451Sopenharmony_ci  8, 8, 8,
24730f66f451Sopenharmony_ci  16, 16, 16,
24740f66f451Sopenharmony_ci  32, 32, 32,
24750f66f451Sopenharmony_ci  64, 64, 64
24760f66f451Sopenharmony_ci};
24770f66f451Sopenharmony_ci
24780f66f451Sopenharmony_ci/*
24790f66f451Sopenharmony_ci * Fill s->temp by copying data starting from b->in[b->in_pos]. Caller
24800f66f451Sopenharmony_ci * must have set s->temp.pos to indicate how much data we are supposed
24810f66f451Sopenharmony_ci * to copy into s->temp.buf. Return true once s->temp.pos has reached
24820f66f451Sopenharmony_ci * s->temp.size.
24830f66f451Sopenharmony_ci */
24840f66f451Sopenharmony_cistatic int fill_temp(struct xz_dec *s, struct xz_buf *b)
24850f66f451Sopenharmony_ci{
24860f66f451Sopenharmony_ci  size_t copy_size = minof(b->in_size - b->in_pos, s->temp.size - s->temp.pos);
24870f66f451Sopenharmony_ci
24880f66f451Sopenharmony_ci  memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
24890f66f451Sopenharmony_ci  b->in_pos += copy_size;
24900f66f451Sopenharmony_ci  s->temp.pos += copy_size;
24910f66f451Sopenharmony_ci
24920f66f451Sopenharmony_ci  if (s->temp.pos == s->temp.size) {
24930f66f451Sopenharmony_ci    s->temp.pos = 0;
24940f66f451Sopenharmony_ci    return 1;
24950f66f451Sopenharmony_ci  }
24960f66f451Sopenharmony_ci
24970f66f451Sopenharmony_ci  return 0;
24980f66f451Sopenharmony_ci}
24990f66f451Sopenharmony_ci
25000f66f451Sopenharmony_ci/* Decode a variable-length integer (little-endian base-128 encoding) */
25010f66f451Sopenharmony_cistatic enum xz_ret dec_vli(struct xz_dec *s, const uint8_t *in,
25020f66f451Sopenharmony_ci         size_t *in_pos, size_t in_size)
25030f66f451Sopenharmony_ci{
25040f66f451Sopenharmony_ci  uint8_t byte;
25050f66f451Sopenharmony_ci
25060f66f451Sopenharmony_ci  if (s->pos == 0)
25070f66f451Sopenharmony_ci    s->vli = 0;
25080f66f451Sopenharmony_ci
25090f66f451Sopenharmony_ci  while (*in_pos < in_size) {
25100f66f451Sopenharmony_ci    byte = in[*in_pos];
25110f66f451Sopenharmony_ci    ++*in_pos;
25120f66f451Sopenharmony_ci
25130f66f451Sopenharmony_ci    s->vli |= (vli_type)(byte & 0x7F) << s->pos;
25140f66f451Sopenharmony_ci
25150f66f451Sopenharmony_ci    if ((byte & 0x80) == 0) {
25160f66f451Sopenharmony_ci      /* Don't allow non-minimal encodings. */
25170f66f451Sopenharmony_ci      if (byte == 0 && s->pos != 0)
25180f66f451Sopenharmony_ci        return XZ_DATA_ERROR;
25190f66f451Sopenharmony_ci
25200f66f451Sopenharmony_ci      s->pos = 0;
25210f66f451Sopenharmony_ci      return XZ_STREAM_END;
25220f66f451Sopenharmony_ci    }
25230f66f451Sopenharmony_ci
25240f66f451Sopenharmony_ci    s->pos += 7;
25250f66f451Sopenharmony_ci    if (s->pos == 7 * VLI_BYTES_MAX)
25260f66f451Sopenharmony_ci      return XZ_DATA_ERROR;
25270f66f451Sopenharmony_ci  }
25280f66f451Sopenharmony_ci
25290f66f451Sopenharmony_ci  return XZ_OK;
25300f66f451Sopenharmony_ci}
25310f66f451Sopenharmony_ci
25320f66f451Sopenharmony_ci/*
25330f66f451Sopenharmony_ci * Decode the Compressed Data field from a Block. Update and validate
25340f66f451Sopenharmony_ci * the observed compressed and uncompressed sizes of the Block so that
25350f66f451Sopenharmony_ci * they don't exceed the values possibly stored in the Block Header
25360f66f451Sopenharmony_ci * (validation assumes that no integer overflow occurs, since vli_type
25370f66f451Sopenharmony_ci * is normally uint64_t). Update the CRC32 or CRC64 value if presence of
25380f66f451Sopenharmony_ci * the CRC32 or CRC64 field was indicated in Stream Header.
25390f66f451Sopenharmony_ci *
25400f66f451Sopenharmony_ci * Once the decoding is finished, validate that the observed sizes match
25410f66f451Sopenharmony_ci * the sizes possibly stored in the Block Header. Update the hash and
25420f66f451Sopenharmony_ci * Block count, which are later used to validate the Index field.
25430f66f451Sopenharmony_ci */
25440f66f451Sopenharmony_cistatic enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
25450f66f451Sopenharmony_ci{
25460f66f451Sopenharmony_ci  enum xz_ret ret;
25470f66f451Sopenharmony_ci
25480f66f451Sopenharmony_ci  s->in_start = b->in_pos;
25490f66f451Sopenharmony_ci  s->out_start = b->out_pos;
25500f66f451Sopenharmony_ci
25510f66f451Sopenharmony_ci#ifdef XZ_DEC_BCJ
25520f66f451Sopenharmony_ci  if (s->bcj_active)
25530f66f451Sopenharmony_ci    ret = xz_dec_bcj_run(s->bcj, s->lzma2, b);
25540f66f451Sopenharmony_ci  else
25550f66f451Sopenharmony_ci#endif
25560f66f451Sopenharmony_ci    ret = xz_dec_lzma2_run(s->lzma2, b);
25570f66f451Sopenharmony_ci
25580f66f451Sopenharmony_ci  s->block.compressed += b->in_pos - s->in_start;
25590f66f451Sopenharmony_ci  s->block.uncompressed += b->out_pos - s->out_start;
25600f66f451Sopenharmony_ci
25610f66f451Sopenharmony_ci  /*
25620f66f451Sopenharmony_ci   * There is no need to separately check for VLI_UNKNOWN, since
25630f66f451Sopenharmony_ci   * the observed sizes are always smaller than VLI_UNKNOWN.
25640f66f451Sopenharmony_ci   */
25650f66f451Sopenharmony_ci  if (s->block.compressed > s->block_header.compressed
25660f66f451Sopenharmony_ci      || s->block.uncompressed
25670f66f451Sopenharmony_ci        > s->block_header.uncompressed)
25680f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
25690f66f451Sopenharmony_ci
25700f66f451Sopenharmony_ci  if (s->check_type == XZ_CHECK_CRC32)
25710f66f451Sopenharmony_ci    s->crc = xz_crc32(b->out + s->out_start,
25720f66f451Sopenharmony_ci        b->out_pos - s->out_start, s->crc);
25730f66f451Sopenharmony_ci  else if (s->check_type == XZ_CHECK_CRC64) {
25740f66f451Sopenharmony_ci    s->crc = ~(s->crc);
25750f66f451Sopenharmony_ci    size_t size = b->out_pos - s->out_start;
25760f66f451Sopenharmony_ci    uint8_t *buf = b->out + s->out_start;
25770f66f451Sopenharmony_ci    while (size) {
25780f66f451Sopenharmony_ci      s->crc = xz_crc64_table[*buf++ ^ (s->crc & 0xFF)] ^ (s->crc >> 8);
25790f66f451Sopenharmony_ci      --size;
25800f66f451Sopenharmony_ci    }
25810f66f451Sopenharmony_ci    s->crc=~(s->crc);
25820f66f451Sopenharmony_ci  }
25830f66f451Sopenharmony_ci
25840f66f451Sopenharmony_ci  if (ret == XZ_STREAM_END) {
25850f66f451Sopenharmony_ci    if (s->block_header.compressed != VLI_UNKNOWN
25860f66f451Sopenharmony_ci        && s->block_header.compressed
25870f66f451Sopenharmony_ci          != s->block.compressed)
25880f66f451Sopenharmony_ci      return XZ_DATA_ERROR;
25890f66f451Sopenharmony_ci
25900f66f451Sopenharmony_ci    if (s->block_header.uncompressed != VLI_UNKNOWN
25910f66f451Sopenharmony_ci        && s->block_header.uncompressed
25920f66f451Sopenharmony_ci          != s->block.uncompressed)
25930f66f451Sopenharmony_ci      return XZ_DATA_ERROR;
25940f66f451Sopenharmony_ci
25950f66f451Sopenharmony_ci    s->block.hash.unpadded += s->block_header.size
25960f66f451Sopenharmony_ci        + s->block.compressed;
25970f66f451Sopenharmony_ci
25980f66f451Sopenharmony_ci    s->block.hash.unpadded += check_sizes[s->check_type];
25990f66f451Sopenharmony_ci
26000f66f451Sopenharmony_ci    s->block.hash.uncompressed += s->block.uncompressed;
26010f66f451Sopenharmony_ci    s->block.hash.crc32 = xz_crc32(
26020f66f451Sopenharmony_ci        (const uint8_t *)&s->block.hash,
26030f66f451Sopenharmony_ci        sizeof(s->block.hash), s->block.hash.crc32);
26040f66f451Sopenharmony_ci
26050f66f451Sopenharmony_ci    ++s->block.count;
26060f66f451Sopenharmony_ci  }
26070f66f451Sopenharmony_ci
26080f66f451Sopenharmony_ci  return ret;
26090f66f451Sopenharmony_ci}
26100f66f451Sopenharmony_ci
26110f66f451Sopenharmony_ci/* Update the Index size and the CRC32 value. */
26120f66f451Sopenharmony_cistatic void index_update(struct xz_dec *s, const struct xz_buf *b)
26130f66f451Sopenharmony_ci{
26140f66f451Sopenharmony_ci  size_t in_used = b->in_pos - s->in_start;
26150f66f451Sopenharmony_ci  s->index.size += in_used;
26160f66f451Sopenharmony_ci  s->crc = xz_crc32(b->in + s->in_start, in_used, s->crc);
26170f66f451Sopenharmony_ci}
26180f66f451Sopenharmony_ci
26190f66f451Sopenharmony_ci/*
26200f66f451Sopenharmony_ci * Decode the Number of Records, Unpadded Size, and Uncompressed Size
26210f66f451Sopenharmony_ci * fields from the Index field. That is, Index Padding and CRC32 are not
26220f66f451Sopenharmony_ci * decoded by this function.
26230f66f451Sopenharmony_ci *
26240f66f451Sopenharmony_ci * This can return XZ_OK (more input needed), XZ_STREAM_END (everything
26250f66f451Sopenharmony_ci * successfully decoded), or XZ_DATA_ERROR (input is corrupt).
26260f66f451Sopenharmony_ci */
26270f66f451Sopenharmony_cistatic enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
26280f66f451Sopenharmony_ci{
26290f66f451Sopenharmony_ci  enum xz_ret ret;
26300f66f451Sopenharmony_ci
26310f66f451Sopenharmony_ci  do {
26320f66f451Sopenharmony_ci    ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
26330f66f451Sopenharmony_ci    if (ret != XZ_STREAM_END) {
26340f66f451Sopenharmony_ci      index_update(s, b);
26350f66f451Sopenharmony_ci      return ret;
26360f66f451Sopenharmony_ci    }
26370f66f451Sopenharmony_ci
26380f66f451Sopenharmony_ci    switch (s->index.sequence) {
26390f66f451Sopenharmony_ci    case SEQ_INDEX_COUNT:
26400f66f451Sopenharmony_ci      s->index.count = s->vli;
26410f66f451Sopenharmony_ci
26420f66f451Sopenharmony_ci      /*
26430f66f451Sopenharmony_ci       * Validate that the Number of Records field
26440f66f451Sopenharmony_ci       * indicates the same number of Records as
26450f66f451Sopenharmony_ci       * there were Blocks in the Stream.
26460f66f451Sopenharmony_ci       */
26470f66f451Sopenharmony_ci      if (s->index.count != s->block.count)
26480f66f451Sopenharmony_ci        return XZ_DATA_ERROR;
26490f66f451Sopenharmony_ci
26500f66f451Sopenharmony_ci      s->index.sequence = SEQ_INDEX_UNPADDED;
26510f66f451Sopenharmony_ci      break;
26520f66f451Sopenharmony_ci
26530f66f451Sopenharmony_ci    case SEQ_INDEX_UNPADDED:
26540f66f451Sopenharmony_ci      s->index.hash.unpadded += s->vli;
26550f66f451Sopenharmony_ci      s->index.sequence = SEQ_INDEX_UNCOMPRESSED;
26560f66f451Sopenharmony_ci      break;
26570f66f451Sopenharmony_ci
26580f66f451Sopenharmony_ci    case SEQ_INDEX_UNCOMPRESSED:
26590f66f451Sopenharmony_ci      s->index.hash.uncompressed += s->vli;
26600f66f451Sopenharmony_ci      s->index.hash.crc32 = xz_crc32(
26610f66f451Sopenharmony_ci          (const uint8_t *)&s->index.hash,
26620f66f451Sopenharmony_ci          sizeof(s->index.hash),
26630f66f451Sopenharmony_ci          s->index.hash.crc32);
26640f66f451Sopenharmony_ci      --s->index.count;
26650f66f451Sopenharmony_ci      s->index.sequence = SEQ_INDEX_UNPADDED;
26660f66f451Sopenharmony_ci      break;
26670f66f451Sopenharmony_ci    }
26680f66f451Sopenharmony_ci  } while (s->index.count > 0);
26690f66f451Sopenharmony_ci
26700f66f451Sopenharmony_ci  return XZ_STREAM_END;
26710f66f451Sopenharmony_ci}
26720f66f451Sopenharmony_ci
26730f66f451Sopenharmony_ci/*
26740f66f451Sopenharmony_ci * Validate that the next four or eight input bytes match the value
26750f66f451Sopenharmony_ci * of s->crc. s->pos must be zero when starting to validate the first byte.
26760f66f451Sopenharmony_ci * The "bits" argument allows using the same code for both CRC32 and CRC64.
26770f66f451Sopenharmony_ci */
26780f66f451Sopenharmony_cistatic enum xz_ret crc_validate(struct xz_dec *s, struct xz_buf *b,
26790f66f451Sopenharmony_ci        uint32_t bits)
26800f66f451Sopenharmony_ci{
26810f66f451Sopenharmony_ci  do {
26820f66f451Sopenharmony_ci    if (b->in_pos == b->in_size)
26830f66f451Sopenharmony_ci      return XZ_OK;
26840f66f451Sopenharmony_ci
26850f66f451Sopenharmony_ci    if (((s->crc >> s->pos) & 0xFF) != b->in[b->in_pos++])
26860f66f451Sopenharmony_ci      return XZ_DATA_ERROR;
26870f66f451Sopenharmony_ci
26880f66f451Sopenharmony_ci    s->pos += 8;
26890f66f451Sopenharmony_ci
26900f66f451Sopenharmony_ci  } while (s->pos < bits);
26910f66f451Sopenharmony_ci
26920f66f451Sopenharmony_ci  s->crc = 0;
26930f66f451Sopenharmony_ci  s->pos = 0;
26940f66f451Sopenharmony_ci
26950f66f451Sopenharmony_ci  return XZ_STREAM_END;
26960f66f451Sopenharmony_ci}
26970f66f451Sopenharmony_ci
26980f66f451Sopenharmony_ci/*
26990f66f451Sopenharmony_ci * Skip over the Check field when the Check ID is not supported.
27000f66f451Sopenharmony_ci * Returns true once the whole Check field has been skipped over.
27010f66f451Sopenharmony_ci */
27020f66f451Sopenharmony_cistatic int check_skip(struct xz_dec *s, struct xz_buf *b)
27030f66f451Sopenharmony_ci{
27040f66f451Sopenharmony_ci  while (s->pos < check_sizes[s->check_type]) {
27050f66f451Sopenharmony_ci    if (b->in_pos == b->in_size) return 0;
27060f66f451Sopenharmony_ci
27070f66f451Sopenharmony_ci    ++b->in_pos;
27080f66f451Sopenharmony_ci    ++s->pos;
27090f66f451Sopenharmony_ci  }
27100f66f451Sopenharmony_ci
27110f66f451Sopenharmony_ci  s->pos = 0;
27120f66f451Sopenharmony_ci
27130f66f451Sopenharmony_ci  return 1;
27140f66f451Sopenharmony_ci}
27150f66f451Sopenharmony_ci
27160f66f451Sopenharmony_ci/* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
27170f66f451Sopenharmony_cistatic enum xz_ret dec_stream_header(struct xz_dec *s)
27180f66f451Sopenharmony_ci{
27190f66f451Sopenharmony_ci  if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
27200f66f451Sopenharmony_ci    return XZ_FORMAT_ERROR;
27210f66f451Sopenharmony_ci
27220f66f451Sopenharmony_ci  if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0)
27230f66f451Sopenharmony_ci      != get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
27240f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
27250f66f451Sopenharmony_ci
27260f66f451Sopenharmony_ci  if (s->temp.buf[HEADER_MAGIC_SIZE] != 0)
27270f66f451Sopenharmony_ci    return XZ_OPTIONS_ERROR;
27280f66f451Sopenharmony_ci
27290f66f451Sopenharmony_ci  /*
27300f66f451Sopenharmony_ci   * Of integrity checks, we support none (Check ID = 0),
27310f66f451Sopenharmony_ci   * CRC32 (Check ID = 1), and optionally CRC64 (Check ID = 4).
27320f66f451Sopenharmony_ci   * However, if XZ_DEC_ANY_CHECK is defined, we will accept other
27330f66f451Sopenharmony_ci   * check types too, but then the check won't be verified and
27340f66f451Sopenharmony_ci   * a warning (XZ_UNSUPPORTED_CHECK) will be given.
27350f66f451Sopenharmony_ci   */
27360f66f451Sopenharmony_ci  s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1];
27370f66f451Sopenharmony_ci
27380f66f451Sopenharmony_ci  if (s->check_type > XZ_CHECK_MAX)
27390f66f451Sopenharmony_ci    return XZ_OPTIONS_ERROR;
27400f66f451Sopenharmony_ci
27410f66f451Sopenharmony_ci  if (s->check_type > XZ_CHECK_CRC32 && !IS_CRC64(s->check_type))
27420f66f451Sopenharmony_ci    return XZ_UNSUPPORTED_CHECK;
27430f66f451Sopenharmony_ci
27440f66f451Sopenharmony_ci  return XZ_OK;
27450f66f451Sopenharmony_ci}
27460f66f451Sopenharmony_ci
27470f66f451Sopenharmony_ci/* Decode the Stream Footer field (the last 12 bytes of the .xz Stream) */
27480f66f451Sopenharmony_cistatic enum xz_ret dec_stream_footer(struct xz_dec *s)
27490f66f451Sopenharmony_ci{
27500f66f451Sopenharmony_ci  if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
27510f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
27520f66f451Sopenharmony_ci
27530f66f451Sopenharmony_ci  if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
27540f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
27550f66f451Sopenharmony_ci
27560f66f451Sopenharmony_ci  /*
27570f66f451Sopenharmony_ci   * Validate Backward Size. Note that we never added the size of the
27580f66f451Sopenharmony_ci   * Index CRC32 field to s->index.size, thus we use s->index.size / 4
27590f66f451Sopenharmony_ci   * instead of s->index.size / 4 - 1.
27600f66f451Sopenharmony_ci   */
27610f66f451Sopenharmony_ci  if ((s->index.size >> 2) != get_le32(s->temp.buf + 4))
27620f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
27630f66f451Sopenharmony_ci
27640f66f451Sopenharmony_ci  if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->check_type)
27650f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
27660f66f451Sopenharmony_ci
27670f66f451Sopenharmony_ci  /*
27680f66f451Sopenharmony_ci   * Use XZ_STREAM_END instead of XZ_OK to be more convenient
27690f66f451Sopenharmony_ci   * for the caller.
27700f66f451Sopenharmony_ci   */
27710f66f451Sopenharmony_ci  return XZ_STREAM_END;
27720f66f451Sopenharmony_ci}
27730f66f451Sopenharmony_ci
27740f66f451Sopenharmony_ci/* Decode the Block Header and initialize the filter chain. */
27750f66f451Sopenharmony_cistatic enum xz_ret dec_block_header(struct xz_dec *s)
27760f66f451Sopenharmony_ci{
27770f66f451Sopenharmony_ci  enum xz_ret ret;
27780f66f451Sopenharmony_ci
27790f66f451Sopenharmony_ci  /*
27800f66f451Sopenharmony_ci   * Validate the CRC32. We know that the temp buffer is at least
27810f66f451Sopenharmony_ci   * eight bytes so this is safe.
27820f66f451Sopenharmony_ci   */
27830f66f451Sopenharmony_ci  s->temp.size -= 4;
27840f66f451Sopenharmony_ci  if (xz_crc32(s->temp.buf, s->temp.size, 0)
27850f66f451Sopenharmony_ci      != get_le32(s->temp.buf + s->temp.size))
27860f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
27870f66f451Sopenharmony_ci
27880f66f451Sopenharmony_ci  s->temp.pos = 2;
27890f66f451Sopenharmony_ci
27900f66f451Sopenharmony_ci  /*
27910f66f451Sopenharmony_ci   * Catch unsupported Block Flags. We support only one or two filters
27920f66f451Sopenharmony_ci   * in the chain, so we catch that with the same test.
27930f66f451Sopenharmony_ci   */
27940f66f451Sopenharmony_ci#ifdef XZ_DEC_BCJ
27950f66f451Sopenharmony_ci  if (s->temp.buf[1] & 0x3E)
27960f66f451Sopenharmony_ci#else
27970f66f451Sopenharmony_ci  if (s->temp.buf[1] & 0x3F)
27980f66f451Sopenharmony_ci#endif
27990f66f451Sopenharmony_ci    return XZ_OPTIONS_ERROR;
28000f66f451Sopenharmony_ci
28010f66f451Sopenharmony_ci  /* Compressed Size */
28020f66f451Sopenharmony_ci  if (s->temp.buf[1] & 0x40) {
28030f66f451Sopenharmony_ci    if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
28040f66f451Sopenharmony_ci          != XZ_STREAM_END)
28050f66f451Sopenharmony_ci      return XZ_DATA_ERROR;
28060f66f451Sopenharmony_ci
28070f66f451Sopenharmony_ci    s->block_header.compressed = s->vli;
28080f66f451Sopenharmony_ci  } else {
28090f66f451Sopenharmony_ci    s->block_header.compressed = VLI_UNKNOWN;
28100f66f451Sopenharmony_ci  }
28110f66f451Sopenharmony_ci
28120f66f451Sopenharmony_ci  /* Uncompressed Size */
28130f66f451Sopenharmony_ci  if (s->temp.buf[1] & 0x80) {
28140f66f451Sopenharmony_ci    if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
28150f66f451Sopenharmony_ci        != XZ_STREAM_END)
28160f66f451Sopenharmony_ci      return XZ_DATA_ERROR;
28170f66f451Sopenharmony_ci
28180f66f451Sopenharmony_ci    s->block_header.uncompressed = s->vli;
28190f66f451Sopenharmony_ci  } else {
28200f66f451Sopenharmony_ci    s->block_header.uncompressed = VLI_UNKNOWN;
28210f66f451Sopenharmony_ci  }
28220f66f451Sopenharmony_ci
28230f66f451Sopenharmony_ci#ifdef XZ_DEC_BCJ
28240f66f451Sopenharmony_ci  /* If there are two filters, the first one must be a BCJ filter. */
28250f66f451Sopenharmony_ci  s->bcj_active = s->temp.buf[1] & 0x01;
28260f66f451Sopenharmony_ci  if (s->bcj_active) {
28270f66f451Sopenharmony_ci    if (s->temp.size - s->temp.pos < 2)
28280f66f451Sopenharmony_ci      return XZ_OPTIONS_ERROR;
28290f66f451Sopenharmony_ci
28300f66f451Sopenharmony_ci    ret = xz_dec_bcj_reset(s->bcj, s->temp.buf[s->temp.pos++]);
28310f66f451Sopenharmony_ci    if (ret != XZ_OK)
28320f66f451Sopenharmony_ci      return ret;
28330f66f451Sopenharmony_ci
28340f66f451Sopenharmony_ci    /*
28350f66f451Sopenharmony_ci     * We don't support custom start offset,
28360f66f451Sopenharmony_ci     * so Size of Properties must be zero.
28370f66f451Sopenharmony_ci     */
28380f66f451Sopenharmony_ci    if (s->temp.buf[s->temp.pos++] != 0x00)
28390f66f451Sopenharmony_ci      return XZ_OPTIONS_ERROR;
28400f66f451Sopenharmony_ci  }
28410f66f451Sopenharmony_ci#endif
28420f66f451Sopenharmony_ci
28430f66f451Sopenharmony_ci  /* Valid Filter Flags always take at least two bytes. */
28440f66f451Sopenharmony_ci  if (s->temp.size - s->temp.pos < 2)
28450f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
28460f66f451Sopenharmony_ci
28470f66f451Sopenharmony_ci  /* Filter ID = LZMA2 */
28480f66f451Sopenharmony_ci  if (s->temp.buf[s->temp.pos++] != 0x21)
28490f66f451Sopenharmony_ci    return XZ_OPTIONS_ERROR;
28500f66f451Sopenharmony_ci
28510f66f451Sopenharmony_ci  /* Size of Properties = 1-byte Filter Properties */
28520f66f451Sopenharmony_ci  if (s->temp.buf[s->temp.pos++] != 0x01)
28530f66f451Sopenharmony_ci    return XZ_OPTIONS_ERROR;
28540f66f451Sopenharmony_ci
28550f66f451Sopenharmony_ci  /* Filter Properties contains LZMA2 dictionary size. */
28560f66f451Sopenharmony_ci  if (s->temp.size - s->temp.pos < 1)
28570f66f451Sopenharmony_ci    return XZ_DATA_ERROR;
28580f66f451Sopenharmony_ci
28590f66f451Sopenharmony_ci  ret = xz_dec_lzma2_reset(s->lzma2, s->temp.buf[s->temp.pos++]);
28600f66f451Sopenharmony_ci  if (ret != XZ_OK)
28610f66f451Sopenharmony_ci    return ret;
28620f66f451Sopenharmony_ci
28630f66f451Sopenharmony_ci  /* The rest must be Header Padding. */
28640f66f451Sopenharmony_ci  while (s->temp.pos < s->temp.size)
28650f66f451Sopenharmony_ci    if (s->temp.buf[s->temp.pos++] != 0x00)
28660f66f451Sopenharmony_ci      return XZ_OPTIONS_ERROR;
28670f66f451Sopenharmony_ci
28680f66f451Sopenharmony_ci  s->temp.pos = 0;
28690f66f451Sopenharmony_ci  s->block.compressed = 0;
28700f66f451Sopenharmony_ci  s->block.uncompressed = 0;
28710f66f451Sopenharmony_ci
28720f66f451Sopenharmony_ci  return XZ_OK;
28730f66f451Sopenharmony_ci}
28740f66f451Sopenharmony_ci
28750f66f451Sopenharmony_cistatic enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
28760f66f451Sopenharmony_ci{
28770f66f451Sopenharmony_ci  enum xz_ret ret;
28780f66f451Sopenharmony_ci
28790f66f451Sopenharmony_ci  /*
28800f66f451Sopenharmony_ci   * Store the start position for the case when we are in the middle
28810f66f451Sopenharmony_ci   * of the Index field.
28820f66f451Sopenharmony_ci   */
28830f66f451Sopenharmony_ci  s->in_start = b->in_pos;
28840f66f451Sopenharmony_ci
28850f66f451Sopenharmony_ci  for (;;) {
28860f66f451Sopenharmony_ci    switch (s->sequence) {
28870f66f451Sopenharmony_ci    case SEQ_STREAM_HEADER:
28880f66f451Sopenharmony_ci      /*
28890f66f451Sopenharmony_ci       * Stream Header is copied to s->temp, and then
28900f66f451Sopenharmony_ci       * decoded from there. This way if the caller
28910f66f451Sopenharmony_ci       * gives us only little input at a time, we can
28920f66f451Sopenharmony_ci       * still keep the Stream Header decoding code
28930f66f451Sopenharmony_ci       * simple. Similar approach is used in many places
28940f66f451Sopenharmony_ci       * in this file.
28950f66f451Sopenharmony_ci       */
28960f66f451Sopenharmony_ci      if (!fill_temp(s, b))
28970f66f451Sopenharmony_ci        return XZ_OK;
28980f66f451Sopenharmony_ci
28990f66f451Sopenharmony_ci      /*
29000f66f451Sopenharmony_ci       * If dec_stream_header() returns
29010f66f451Sopenharmony_ci       * XZ_UNSUPPORTED_CHECK, it is still possible
29020f66f451Sopenharmony_ci       * to continue decoding if working in multi-call
29030f66f451Sopenharmony_ci       * mode. Thus, update s->sequence before calling
29040f66f451Sopenharmony_ci       * dec_stream_header().
29050f66f451Sopenharmony_ci       */
29060f66f451Sopenharmony_ci      s->sequence = SEQ_BLOCK_START;
29070f66f451Sopenharmony_ci
29080f66f451Sopenharmony_ci      ret = dec_stream_header(s);
29090f66f451Sopenharmony_ci      if (ret != XZ_OK)
29100f66f451Sopenharmony_ci        return ret;
29110f66f451Sopenharmony_ci
29120f66f451Sopenharmony_ci    case SEQ_BLOCK_START:
29130f66f451Sopenharmony_ci      /* We need one byte of input to continue. */
29140f66f451Sopenharmony_ci      if (b->in_pos == b->in_size)
29150f66f451Sopenharmony_ci        return XZ_OK;
29160f66f451Sopenharmony_ci
29170f66f451Sopenharmony_ci      /* See if this is the beginning of the Index field. */
29180f66f451Sopenharmony_ci      if (b->in[b->in_pos] == 0) {
29190f66f451Sopenharmony_ci        s->in_start = b->in_pos++;
29200f66f451Sopenharmony_ci        s->sequence = SEQ_INDEX;
29210f66f451Sopenharmony_ci        break;
29220f66f451Sopenharmony_ci      }
29230f66f451Sopenharmony_ci
29240f66f451Sopenharmony_ci      /*
29250f66f451Sopenharmony_ci       * Calculate the size of the Block Header and
29260f66f451Sopenharmony_ci       * prepare to decode it.
29270f66f451Sopenharmony_ci       */
29280f66f451Sopenharmony_ci      s->block_header.size
29290f66f451Sopenharmony_ci        = ((uint32_t)b->in[b->in_pos] + 1) * 4;
29300f66f451Sopenharmony_ci
29310f66f451Sopenharmony_ci      s->temp.size = s->block_header.size;
29320f66f451Sopenharmony_ci      s->temp.pos = 0;
29330f66f451Sopenharmony_ci      s->sequence = SEQ_BLOCK_HEADER;
29340f66f451Sopenharmony_ci
29350f66f451Sopenharmony_ci    case SEQ_BLOCK_HEADER:
29360f66f451Sopenharmony_ci      if (!fill_temp(s, b))
29370f66f451Sopenharmony_ci        return XZ_OK;
29380f66f451Sopenharmony_ci
29390f66f451Sopenharmony_ci      ret = dec_block_header(s);
29400f66f451Sopenharmony_ci      if (ret != XZ_OK)
29410f66f451Sopenharmony_ci        return ret;
29420f66f451Sopenharmony_ci
29430f66f451Sopenharmony_ci      s->sequence = SEQ_BLOCK_UNCOMPRESS;
29440f66f451Sopenharmony_ci
29450f66f451Sopenharmony_ci    case SEQ_BLOCK_UNCOMPRESS:
29460f66f451Sopenharmony_ci      ret = dec_block(s, b);
29470f66f451Sopenharmony_ci      if (ret != XZ_STREAM_END)
29480f66f451Sopenharmony_ci        return ret;
29490f66f451Sopenharmony_ci
29500f66f451Sopenharmony_ci      s->sequence = SEQ_BLOCK_PADDING;
29510f66f451Sopenharmony_ci
29520f66f451Sopenharmony_ci    case SEQ_BLOCK_PADDING:
29530f66f451Sopenharmony_ci      /*
29540f66f451Sopenharmony_ci       * Size of Compressed Data + Block Padding
29550f66f451Sopenharmony_ci       * must be a multiple of four. We don't need
29560f66f451Sopenharmony_ci       * s->block.compressed for anything else
29570f66f451Sopenharmony_ci       * anymore, so we use it here to test the size
29580f66f451Sopenharmony_ci       * of the Block Padding field.
29590f66f451Sopenharmony_ci       */
29600f66f451Sopenharmony_ci      while (s->block.compressed & 3) {
29610f66f451Sopenharmony_ci        if (b->in_pos == b->in_size)
29620f66f451Sopenharmony_ci          return XZ_OK;
29630f66f451Sopenharmony_ci
29640f66f451Sopenharmony_ci        if (b->in[b->in_pos++] != 0)
29650f66f451Sopenharmony_ci          return XZ_DATA_ERROR;
29660f66f451Sopenharmony_ci
29670f66f451Sopenharmony_ci        ++s->block.compressed;
29680f66f451Sopenharmony_ci      }
29690f66f451Sopenharmony_ci
29700f66f451Sopenharmony_ci      s->sequence = SEQ_BLOCK_CHECK;
29710f66f451Sopenharmony_ci
29720f66f451Sopenharmony_ci    case SEQ_BLOCK_CHECK:
29730f66f451Sopenharmony_ci      if (s->check_type == XZ_CHECK_CRC32) {
29740f66f451Sopenharmony_ci        ret = crc_validate(s, b, 32);
29750f66f451Sopenharmony_ci        if (ret != XZ_STREAM_END)
29760f66f451Sopenharmony_ci          return ret;
29770f66f451Sopenharmony_ci      }
29780f66f451Sopenharmony_ci      else if (IS_CRC64(s->check_type)) {
29790f66f451Sopenharmony_ci        ret = crc_validate(s, b, 64);
29800f66f451Sopenharmony_ci        if (ret != XZ_STREAM_END)
29810f66f451Sopenharmony_ci          return ret;
29820f66f451Sopenharmony_ci      }
29830f66f451Sopenharmony_ci      else if (!check_skip(s, b)) {
29840f66f451Sopenharmony_ci        return XZ_OK;
29850f66f451Sopenharmony_ci      }
29860f66f451Sopenharmony_ci
29870f66f451Sopenharmony_ci      s->sequence = SEQ_BLOCK_START;
29880f66f451Sopenharmony_ci      break;
29890f66f451Sopenharmony_ci
29900f66f451Sopenharmony_ci    case SEQ_INDEX:
29910f66f451Sopenharmony_ci      ret = dec_index(s, b);
29920f66f451Sopenharmony_ci      if (ret != XZ_STREAM_END)
29930f66f451Sopenharmony_ci        return ret;
29940f66f451Sopenharmony_ci
29950f66f451Sopenharmony_ci      s->sequence = SEQ_INDEX_PADDING;
29960f66f451Sopenharmony_ci
29970f66f451Sopenharmony_ci    case SEQ_INDEX_PADDING:
29980f66f451Sopenharmony_ci      while ((s->index.size + (b->in_pos - s->in_start))
29990f66f451Sopenharmony_ci          & 3) {
30000f66f451Sopenharmony_ci        if (b->in_pos == b->in_size) {
30010f66f451Sopenharmony_ci          index_update(s, b);
30020f66f451Sopenharmony_ci          return XZ_OK;
30030f66f451Sopenharmony_ci        }
30040f66f451Sopenharmony_ci
30050f66f451Sopenharmony_ci        if (b->in[b->in_pos++] != 0)
30060f66f451Sopenharmony_ci          return XZ_DATA_ERROR;
30070f66f451Sopenharmony_ci      }
30080f66f451Sopenharmony_ci
30090f66f451Sopenharmony_ci      /* Finish the CRC32 value and Index size. */
30100f66f451Sopenharmony_ci      index_update(s, b);
30110f66f451Sopenharmony_ci
30120f66f451Sopenharmony_ci      /* Compare the hashes to validate the Index field. */
30130f66f451Sopenharmony_ci      if (!memeq(&s->block.hash, &s->index.hash,
30140f66f451Sopenharmony_ci          sizeof(s->block.hash)))
30150f66f451Sopenharmony_ci        return XZ_DATA_ERROR;
30160f66f451Sopenharmony_ci
30170f66f451Sopenharmony_ci      s->sequence = SEQ_INDEX_CRC32;
30180f66f451Sopenharmony_ci
30190f66f451Sopenharmony_ci    case SEQ_INDEX_CRC32:
30200f66f451Sopenharmony_ci      ret = crc_validate(s, b, 32);
30210f66f451Sopenharmony_ci      if (ret != XZ_STREAM_END)
30220f66f451Sopenharmony_ci        return ret;
30230f66f451Sopenharmony_ci
30240f66f451Sopenharmony_ci      s->temp.size = STREAM_HEADER_SIZE;
30250f66f451Sopenharmony_ci      s->sequence = SEQ_STREAM_FOOTER;
30260f66f451Sopenharmony_ci
30270f66f451Sopenharmony_ci    case SEQ_STREAM_FOOTER:
30280f66f451Sopenharmony_ci      if (!fill_temp(s, b))
30290f66f451Sopenharmony_ci        return XZ_OK;
30300f66f451Sopenharmony_ci
30310f66f451Sopenharmony_ci      return dec_stream_footer(s);
30320f66f451Sopenharmony_ci    }
30330f66f451Sopenharmony_ci  }
30340f66f451Sopenharmony_ci
30350f66f451Sopenharmony_ci  /* Never reached */
30360f66f451Sopenharmony_ci}
30370f66f451Sopenharmony_ci
30380f66f451Sopenharmony_ci/*
30390f66f451Sopenharmony_ci * xz_dec_run() is a wrapper for dec_main() to handle some special cases in
30400f66f451Sopenharmony_ci * multi-call and single-call decoding.
30410f66f451Sopenharmony_ci *
30420f66f451Sopenharmony_ci * In multi-call mode, we must return XZ_BUF_ERROR when it seems clear that we
30430f66f451Sopenharmony_ci * are not going to make any progress anymore. This is to prevent the caller
30440f66f451Sopenharmony_ci * from calling us infinitely when the input file is truncated or otherwise
30450f66f451Sopenharmony_ci * corrupt. Since zlib-style API allows that the caller fills the input buffer
30460f66f451Sopenharmony_ci * only when the decoder doesn't produce any new output, we have to be careful
30470f66f451Sopenharmony_ci * to avoid returning XZ_BUF_ERROR too easily: XZ_BUF_ERROR is returned only
30480f66f451Sopenharmony_ci * after the second consecutive call to xz_dec_run() that makes no progress.
30490f66f451Sopenharmony_ci *
30500f66f451Sopenharmony_ci * In single-call mode, if we couldn't decode everything and no error
30510f66f451Sopenharmony_ci * occurred, either the input is truncated or the output buffer is too small.
30520f66f451Sopenharmony_ci * Since we know that the last input byte never produces any output, we know
30530f66f451Sopenharmony_ci * that if all the input was consumed and decoding wasn't finished, the file
30540f66f451Sopenharmony_ci * must be corrupt. Otherwise the output buffer has to be too small or the
30550f66f451Sopenharmony_ci * file is corrupt in a way that decoding it produces too big output.
30560f66f451Sopenharmony_ci *
30570f66f451Sopenharmony_ci * If single-call decoding fails, we reset b->in_pos and b->out_pos back to
30580f66f451Sopenharmony_ci * their original values. This is because with some filter chains there won't
30590f66f451Sopenharmony_ci * be any valid uncompressed data in the output buffer unless the decoding
30600f66f451Sopenharmony_ci * actually succeeds (that's the price to pay of using the output buffer as
30610f66f451Sopenharmony_ci * the workspace).
30620f66f451Sopenharmony_ci */
30630f66f451Sopenharmony_cienum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b)
30640f66f451Sopenharmony_ci{
30650f66f451Sopenharmony_ci  size_t in_start;
30660f66f451Sopenharmony_ci  size_t out_start;
30670f66f451Sopenharmony_ci  enum xz_ret ret;
30680f66f451Sopenharmony_ci
30690f66f451Sopenharmony_ci  in_start = b->in_pos;
30700f66f451Sopenharmony_ci  out_start = b->out_pos;
30710f66f451Sopenharmony_ci  ret = dec_main(s, b);
30720f66f451Sopenharmony_ci
30730f66f451Sopenharmony_ci  if (ret == XZ_OK && in_start == b->in_pos && out_start == b->out_pos) {
30740f66f451Sopenharmony_ci    if (s->allow_buf_error)
30750f66f451Sopenharmony_ci      ret = XZ_BUF_ERROR;
30760f66f451Sopenharmony_ci
30770f66f451Sopenharmony_ci    s->allow_buf_error = 1;
30780f66f451Sopenharmony_ci  } else {
30790f66f451Sopenharmony_ci    s->allow_buf_error = 0;
30800f66f451Sopenharmony_ci  }
30810f66f451Sopenharmony_ci
30820f66f451Sopenharmony_ci  return ret;
30830f66f451Sopenharmony_ci}
30840f66f451Sopenharmony_ci
30850f66f451Sopenharmony_cistruct xz_dec *xz_dec_init(uint32_t dict_max)
30860f66f451Sopenharmony_ci{
30870f66f451Sopenharmony_ci  struct xz_dec *s = malloc(sizeof(*s));
30880f66f451Sopenharmony_ci  if (!s)
30890f66f451Sopenharmony_ci    return NULL;
30900f66f451Sopenharmony_ci
30910f66f451Sopenharmony_ci#ifdef XZ_DEC_BCJ
30920f66f451Sopenharmony_ci  s->bcj = malloc(sizeof(*s->bcj));
30930f66f451Sopenharmony_ci  if (!s->bcj)
30940f66f451Sopenharmony_ci    goto error_bcj;
30950f66f451Sopenharmony_ci#endif
30960f66f451Sopenharmony_ci
30970f66f451Sopenharmony_ci  s->lzma2 = xz_dec_lzma2_create(dict_max);
30980f66f451Sopenharmony_ci  if (s->lzma2 == NULL)
30990f66f451Sopenharmony_ci    goto error_lzma2;
31000f66f451Sopenharmony_ci
31010f66f451Sopenharmony_ci  xz_dec_reset(s);
31020f66f451Sopenharmony_ci  return s;
31030f66f451Sopenharmony_ci
31040f66f451Sopenharmony_cierror_lzma2:
31050f66f451Sopenharmony_ci#ifdef XZ_DEC_BCJ
31060f66f451Sopenharmony_ci  free(s->bcj);
31070f66f451Sopenharmony_cierror_bcj:
31080f66f451Sopenharmony_ci#endif
31090f66f451Sopenharmony_ci  free(s);
31100f66f451Sopenharmony_ci  return NULL;
31110f66f451Sopenharmony_ci}
31120f66f451Sopenharmony_ci
31130f66f451Sopenharmony_civoid xz_dec_reset(struct xz_dec *s)
31140f66f451Sopenharmony_ci{
31150f66f451Sopenharmony_ci  s->sequence = SEQ_STREAM_HEADER;
31160f66f451Sopenharmony_ci  s->allow_buf_error = 0;
31170f66f451Sopenharmony_ci  s->pos = 0;
31180f66f451Sopenharmony_ci  s->crc = 0;
31190f66f451Sopenharmony_ci  memset(&s->block, 0, sizeof(s->block));
31200f66f451Sopenharmony_ci  memset(&s->index, 0, sizeof(s->index));
31210f66f451Sopenharmony_ci  s->temp.pos = 0;
31220f66f451Sopenharmony_ci  s->temp.size = STREAM_HEADER_SIZE;
31230f66f451Sopenharmony_ci}
31240f66f451Sopenharmony_ci
31250f66f451Sopenharmony_civoid xz_dec_end(struct xz_dec *s)
31260f66f451Sopenharmony_ci{
31270f66f451Sopenharmony_ci  if (s != NULL) {
31280f66f451Sopenharmony_ci    free((s->lzma2)->dict.buf);
31290f66f451Sopenharmony_ci    free(s->lzma2);
31300f66f451Sopenharmony_ci
31310f66f451Sopenharmony_ci#ifdef XZ_DEC_BCJ
31320f66f451Sopenharmony_ci    free(s->bcj);
31330f66f451Sopenharmony_ci#endif
31340f66f451Sopenharmony_ci    free(s);
31350f66f451Sopenharmony_ci  }
31360f66f451Sopenharmony_ci}
3137