"Fossies" - the Fresh Open Source Software Archive

Member "xdelta3-3.0.11/xdelta3-decode.h" (9 Dec 2015, 33128 Bytes) of package /linux/misc/xdelta3-3.0.11.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "xdelta3-decode.h" see the Fossies "Dox" file reference documentation.

    1 /* xdelta 3 - delta compression tools and library
    2  * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
    3  * 2011, 2012, 2013, 2014, 2015.  Joshua P. MacDonald
    4  *
    5  *  This program is free software; you can redistribute it and/or modify
    6  *  it under the terms of the GNU General Public License as published by
    7  *  the Free Software Foundation; either version 2 of the License, or
    8  *  (at your option) any later version.
    9  *
   10  *  This program is distributed in the hope that it will be useful,
   11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  *  GNU General Public License for more details.
   14  *
   15  *  You should have received a copy of the GNU General Public License
   16  *  along with this program; if not, write to the Free Software
   17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   18  */
   19 
   20 #ifndef _XDELTA3_DECODE_H_
   21 #define _XDELTA3_DECODE_H_
   22 
   23 #include "xdelta3-internal.h"
   24 
   25 #define SRCORTGT(x) ((((x) & VCD_SRCORTGT) == VCD_SOURCE) ? \
   26                      VCD_SOURCE : ((((x) & VCD_SRCORTGT) == \
   27                                     VCD_TARGET) ? VCD_TARGET : 0))
   28 
   29 static inline int
   30 xd3_decode_byte (xd3_stream *stream, usize_t *val)
   31 {
   32   if (stream->avail_in == 0)
   33     {
   34       stream->msg = "further input required";
   35       return XD3_INPUT;
   36     }
   37 
   38   (*val) = stream->next_in[0];
   39 
   40   DECODE_INPUT (1);
   41   return 0;
   42 }
   43 
   44 static inline int
   45 xd3_decode_bytes (xd3_stream *stream, uint8_t *buf, usize_t *pos, usize_t size)
   46 {
   47   usize_t want;
   48   usize_t take;
   49 
   50   /* Note: The case where (*pos == size) happens when a zero-length
   51    * appheader or code table is transmitted, but there is nothing in
   52    * the standard against that. */
   53   while (*pos < size)
   54     {
   55       if (stream->avail_in == 0)
   56     {
   57       stream->msg = "further input required";
   58       return XD3_INPUT;
   59     }
   60 
   61       want = size - *pos;
   62       take = xd3_min (want, stream->avail_in);
   63 
   64       memcpy (buf + *pos, stream->next_in, (size_t) take);
   65 
   66       DECODE_INPUT (take);
   67       (*pos) += take;
   68     }
   69 
   70   return 0;
   71 }
   72 
   73 /* Initialize the decoder for a new window.  The dec_tgtlen value is
   74  * preserved across successive window decodings, and the update to
   75  * dec_winstart is delayed until a new window actually starts.  This
   76  * is to avoid throwing an error due to overflow until the last
   77  * possible moment.  This makes it possible to encode exactly 4GB
   78  * through a 32-bit encoder. */
   79 static int
   80 xd3_decode_init_window (xd3_stream *stream)
   81 {
   82   stream->dec_cpylen = 0;
   83   stream->dec_cpyoff = 0;
   84   stream->dec_cksumbytes = 0;
   85 
   86   xd3_init_cache (& stream->acache);
   87 
   88   return 0;
   89 }
   90 
   91 /* Allocates buffer space for the target window and possibly the
   92  * VCD_TARGET copy-window.  Also sets the base of the two copy
   93  * segments. */
   94 static int
   95 xd3_decode_setup_buffers (xd3_stream *stream)
   96 {
   97   /* If VCD_TARGET is set then the previous buffer may be reused. */
   98   if (stream->dec_win_ind & VCD_TARGET)
   99     {
  100       /* Note: this implementation is untested, since Xdelta3 itself
  101        * does not implement an encoder for VCD_TARGET mode. Thus, mark
  102        * unimplemented until needed. */
  103       if (1)
  104     {
  105       stream->msg = "VCD_TARGET not implemented";
  106       return XD3_UNIMPLEMENTED;
  107     }
  108 
  109       /* But this implementation only supports copying from the last
  110        * target window.  If the offset is outside that range, it can't
  111        * be done. */
  112       if (stream->dec_cpyoff < stream->dec_laststart)
  113     {
  114       stream->msg = "unsupported VCD_TARGET offset";
  115       return XD3_INVALID_INPUT;
  116     }
  117 
  118       /* See if the two windows are the same.  This indicates the
  119        * first time VCD_TARGET is used.  This causes a second buffer
  120        * to be allocated, after that the two are swapped in the
  121        * DEC_FINISH case. */
  122       if (stream->dec_lastwin == stream->next_out)
  123     {
  124       stream->next_out  = NULL;
  125       stream->space_out = 0;
  126     }
  127 
  128       /* TODO: (See note above, this looks incorrect) */
  129       stream->dec_cpyaddrbase = stream->dec_lastwin +
  130     (usize_t) (stream->dec_cpyoff - stream->dec_laststart);
  131     }
  132 
  133   /* See if the current output window is large enough. */
  134   if (stream->space_out < stream->dec_tgtlen)
  135     {
  136       xd3_free (stream, stream->dec_buffer);
  137 
  138       stream->space_out =
  139     xd3_round_blksize (stream->dec_tgtlen, XD3_ALLOCSIZE);
  140 
  141       if ((stream->dec_buffer =
  142        (uint8_t*) xd3_alloc (stream, stream->space_out, 1)) == NULL)
  143     {
  144       return ENOMEM;
  145     }
  146 
  147       stream->next_out = stream->dec_buffer;
  148     }
  149 
  150   /* dec_tgtaddrbase refers to an invalid base address, but it is
  151    * always used with a sufficiently large instruction offset (i.e.,
  152    * beyond the copy window).  This condition is enforced by
  153    * xd3_decode_output_halfinst. */
  154   stream->dec_tgtaddrbase = stream->next_out - stream->dec_cpylen;
  155 
  156   return 0;
  157 }
  158 
  159 static int
  160 xd3_decode_allocate (xd3_stream  *stream,
  161              usize_t       size,
  162              uint8_t    **buf_ptr,
  163              usize_t      *buf_alloc)
  164 {
  165   IF_DEBUG2 (DP(RINT "[xd3_decode_allocate] size %u alloc %u\n",
  166         size, *buf_alloc));
  167   
  168   if (*buf_ptr != NULL && *buf_alloc < size)
  169     {
  170       xd3_free (stream, *buf_ptr);
  171       *buf_ptr = NULL;
  172     }
  173 
  174   if (*buf_ptr == NULL)
  175     {
  176       *buf_alloc = xd3_round_blksize (size, XD3_ALLOCSIZE);
  177 
  178       if ((*buf_ptr = (uint8_t*) xd3_alloc (stream, *buf_alloc, 1)) == NULL)
  179     {
  180       return ENOMEM;
  181     }
  182     }
  183 
  184   return 0;
  185 }
  186 
  187 static int
  188 xd3_decode_section (xd3_stream *stream,
  189             xd3_desect *section,
  190             xd3_decode_state nstate,
  191             int copy)
  192 {
  193   XD3_ASSERT (section->pos <= section->size);
  194   XD3_ASSERT (stream->dec_state != nstate);
  195 
  196   if (section->pos < section->size)
  197     {
  198       usize_t sect_take;
  199 
  200       if (stream->avail_in == 0)
  201     {
  202       return XD3_INPUT;
  203     }
  204 
  205       if ((copy == 0) && (section->pos == 0))
  206     {
  207       /* No allocation/copy needed */
  208       section->buf = stream->next_in;
  209       sect_take    = section->size;
  210       IF_DEBUG1 (DP(RINT "[xd3_decode_section] zerocopy %u @ %u avail %u\n",
  211             sect_take, section->pos, stream->avail_in));
  212     }
  213       else
  214     {
  215       usize_t sect_need = section->size - section->pos;
  216 
  217       /* Allocate and copy */
  218       sect_take = xd3_min (sect_need, stream->avail_in);
  219 
  220       if (section->pos == 0)
  221         {
  222           int ret;
  223 
  224           if ((ret = xd3_decode_allocate (stream,
  225                           section->size,
  226                           & section->copied1,
  227                           & section->alloc1)))
  228         {
  229           return ret;
  230         }
  231 
  232           section->buf = section->copied1;
  233         }
  234 
  235       IF_DEBUG2 (DP(RINT "[xd3_decode_section] take %u @ %u [need %u] avail %u\n",
  236             sect_take, section->pos, sect_need, stream->avail_in));
  237       XD3_ASSERT (section->pos + sect_take <= section->alloc1);
  238 
  239       memcpy (section->copied1 + section->pos,
  240           stream->next_in,
  241           sect_take);
  242     }
  243 
  244       section->pos += sect_take;
  245 
  246       stream->dec_winbytes += sect_take;
  247 
  248       DECODE_INPUT (sect_take);
  249     }
  250 
  251   if (section->pos < section->size)
  252     {
  253       IF_DEBUG1 (DP(RINT "[xd3_decode_section] further input required %u\n", section->size - section->pos));
  254       stream->msg = "further input required";
  255       return XD3_INPUT;
  256     }
  257 
  258   XD3_ASSERT (section->pos == section->size);
  259 
  260   stream->dec_state = nstate;
  261   section->buf_max  = section->buf + section->size;
  262   section->pos      = 0;
  263   return 0;
  264 }
  265 
  266 /* Decode the size and address for half of an instruction (i.e., a
  267  * single opcode).  This updates the stream->dec_position, which are
  268  * bytes already output prior to processing this instruction.  Perform
  269  * bounds checking for sizes and copy addresses, which uses the
  270  * dec_position (which is why these checks are done here). */
  271 static int
  272 xd3_decode_parse_halfinst (xd3_stream *stream, xd3_hinst *inst)
  273 {
  274   int ret;
  275 
  276   /* If the size from the instruction table is zero then read a size value. */
  277   if ((inst->size == 0) &&
  278       (ret = xd3_read_size (stream,
  279                 & stream->inst_sect.buf,
  280                   stream->inst_sect.buf_max,
  281                 & inst->size)))
  282     {
  283       return XD3_INVALID_INPUT;
  284     }
  285 
  286   /* For copy instructions, read address. */
  287   if (inst->type >= XD3_CPY)
  288     {
  289       IF_DEBUG2 ({
  290     static int cnt = 0;
  291     XPR(NT "DECODE:%u: COPY at %"Q"u (winoffset %u) size %u winaddr %u\n",
  292          cnt++,
  293          stream->total_out + (stream->dec_position -
  294                       stream->dec_cpylen),
  295          (stream->dec_position - stream->dec_cpylen),
  296          inst->size,
  297          inst->addr);
  298       });
  299 
  300       if ((ret = xd3_decode_address (stream,
  301                      stream->dec_position,
  302                      inst->type - XD3_CPY,
  303                      & stream->addr_sect.buf,
  304                      stream->addr_sect.buf_max,
  305                      & inst->addr)))
  306     {
  307       return ret;
  308     }
  309 
  310       /* Cannot copy an address before it is filled-in. */
  311       if (inst->addr >= stream->dec_position)
  312     {
  313       stream->msg = "address too large";
  314       return XD3_INVALID_INPUT;
  315     }
  316 
  317       /* Check: a VCD_TARGET or VCD_SOURCE copy cannot exceed the remaining
  318        * buffer space in its own segment. */
  319       if (inst->addr < stream->dec_cpylen &&
  320       inst->addr + inst->size > stream->dec_cpylen)
  321     {
  322       stream->msg = "size too large";
  323       return XD3_INVALID_INPUT;
  324     }
  325     }
  326   else
  327     {
  328       IF_DEBUG2 ({
  329     if (inst->type == XD3_ADD)
  330       {
  331         static int cnt;
  332         XPR(NT "DECODE:%d: ADD at %"Q"u (winoffset %u) size %u\n",
  333            cnt++,
  334            (stream->total_out + stream->dec_position - stream->dec_cpylen),
  335            stream->dec_position - stream->dec_cpylen,
  336            inst->size);
  337       }
  338     else
  339       {
  340         static int cnt;
  341         XD3_ASSERT (inst->type == XD3_RUN);
  342         XPR(NT "DECODE:%d: RUN at %"Q"u (winoffset %u) size %u\n",
  343            cnt++,
  344            stream->total_out + stream->dec_position - stream->dec_cpylen,
  345            stream->dec_position - stream->dec_cpylen,
  346            inst->size);
  347       }
  348       });
  349     }
  350 
  351   /* Check: The instruction will not overflow the output buffer. */
  352   if (stream->dec_position + inst->size > stream->dec_maxpos)
  353     {
  354       stream->msg = "size too large";
  355       return XD3_INVALID_INPUT;
  356     }
  357 
  358   stream->dec_position += inst->size;
  359   return 0;
  360 }
  361 
  362 /* Decode a single opcode and then decode the two half-instructions. */
  363 static int
  364 xd3_decode_instruction (xd3_stream *stream)
  365 {
  366   int ret;
  367   const xd3_dinst *inst;
  368 
  369   if (stream->inst_sect.buf == stream->inst_sect.buf_max)
  370     {
  371       stream->msg = "instruction underflow";
  372       return XD3_INVALID_INPUT;
  373     }
  374 
  375   inst = &stream->code_table[*stream->inst_sect.buf++];
  376 
  377   stream->dec_current1.type = inst->type1;
  378   stream->dec_current2.type = inst->type2;
  379   stream->dec_current1.size = inst->size1;
  380   stream->dec_current2.size = inst->size2;
  381 
  382   /* For each instruction with a real operation, decode the
  383    * corresponding size and addresses if necessary.  Assume a
  384    * code-table may have NOOP in either position, although this is
  385    * unlikely. */
  386   if (inst->type1 != XD3_NOOP &&
  387       (ret = xd3_decode_parse_halfinst (stream, & stream->dec_current1)))
  388     {
  389       return ret;
  390     }
  391   if (inst->type2 != XD3_NOOP &&
  392       (ret = xd3_decode_parse_halfinst (stream, & stream->dec_current2)))
  393     {
  394       return ret;
  395     }
  396   return 0;
  397 }
  398 
  399 /* Output the result of a single half-instruction. OPT: This the
  400    decoder hotspot.  Modifies "hinst", see below.  */
  401 static int
  402 xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
  403 {
  404   /* This method is reentrant for copy instructions which may return
  405    * XD3_GETSRCBLK to the caller.  Each time through a copy takes the
  406    * minimum of inst->size and the available space on whichever block
  407    * supplies the data */
  408   usize_t take = inst->size;
  409 
  410   if (USIZE_T_OVERFLOW (stream->avail_out, take) ||
  411       stream->avail_out + take > stream->space_out)
  412     {
  413       stream->msg = "overflow while decoding";
  414       return XD3_INVALID_INPUT;
  415     }
  416 
  417   XD3_ASSERT (inst->type != XD3_NOOP);
  418 
  419   switch (inst->type)
  420     {
  421     case XD3_RUN:
  422       {
  423     /* Only require a single data byte. */
  424     if (stream->data_sect.buf == stream->data_sect.buf_max)
  425       {
  426         stream->msg = "data underflow";
  427         return XD3_INVALID_INPUT;
  428       }
  429 
  430     memset (stream->next_out + stream->avail_out,
  431         stream->data_sect.buf[0],
  432         take);
  433 
  434     stream->data_sect.buf += 1;
  435     stream->avail_out += take;
  436     inst->type = XD3_NOOP;
  437     break;
  438       }
  439     case XD3_ADD:
  440       {
  441     /* Require at least TAKE data bytes. */
  442     if (stream->data_sect.buf + take > stream->data_sect.buf_max)
  443       {
  444         stream->msg = "data underflow";
  445         return XD3_INVALID_INPUT;
  446       }
  447 
  448     memcpy (stream->next_out + stream->avail_out,
  449         stream->data_sect.buf,
  450         take);
  451 
  452     stream->data_sect.buf += take;
  453     stream->avail_out += take;
  454     inst->type = XD3_NOOP;
  455     break;
  456       }
  457     default:
  458       {
  459     usize_t i;
  460     const uint8_t *src;
  461     uint8_t *dst;
  462     int overlap;
  463 
  464     /* See if it copies from the VCD_TARGET/VCD_SOURCE window or
  465      * the target window.  Out-of-bounds checks for the addresses
  466      * and sizes are performed in xd3_decode_parse_halfinst.  This
  467      * if/else must set "overlap", "src", and "dst". */
  468     if (inst->addr < stream->dec_cpylen)
  469       {
  470         /* In both branches we are copying from outside the
  471          * current decoder window, the first (VCD_TARGET) is
  472          * unimplemented. */
  473         overlap = 0;
  474         
  475         /* This branch sets "src".  As a side-effect, we modify
  476          * "inst" so that if we reenter this method after a
  477          * XD3_GETSRCBLK response the state is correct.  So if the
  478          * instruction can be fulfilled by a contiguous block of
  479          * memory then we will set:
  480          *
  481          *  inst->type = XD3_NOOP;
  482          *  inst->size = 0;
  483          */
  484         if (stream->dec_win_ind & VCD_TARGET)
  485           {
  486         /* TODO: Users have requested long-distance copies of
  487          * similar material within a target (e.g., for dup
  488          * supression in backups). This code path is probably
  489          * dead due to XD3_UNIMPLEMENTED in xd3_decode_setup_buffers */
  490         inst->size = 0;
  491         inst->type = XD3_NOOP;
  492         stream->msg = "VCD_TARGET not implemented";
  493         return XD3_UNIMPLEMENTED;
  494           }
  495         else
  496           {
  497         /* In this case we have to read a source block, which
  498          * could return control to the caller.  We need to
  499          * know the first block number needed for this
  500          * copy. */
  501         xd3_source *source = stream->src;
  502         xoff_t block = source->cpyoff_blocks;
  503         usize_t blkoff = source->cpyoff_blkoff;
  504         const usize_t blksize = source->blksize;
  505         int ret;
  506 
  507         xd3_blksize_add (&block, &blkoff, source, inst->addr);
  508         XD3_ASSERT (blkoff < blksize);
  509 
  510         if ((ret = xd3_getblk (stream, block)))
  511           {
  512             /* could be a XD3_GETSRCBLK failure. */
  513             if (ret == XD3_TOOFARBACK)
  514               {
  515             stream->msg = "non-seekable source in decode";
  516             ret = XD3_INTERNAL;
  517               }
  518             return ret;
  519           }
  520 
  521         src = source->curblk + blkoff;
  522 
  523         /* This block is either full, or a partial block that
  524          * must contain enough bytes. */
  525         if ((source->onblk != blksize) &&
  526             (blkoff + take > source->onblk))
  527           {
  528             IF_DEBUG1 (XPR(NT "[srcfile] short at blkno %"Q"u onblk "
  529                    "%u blksize %u blkoff %u take %u\n",
  530                    block,
  531                    source->onblk,
  532                    blksize,
  533                    blkoff,
  534                    take));
  535             stream->msg = "source file too short";
  536             return XD3_INVALID_INPUT;
  537           }
  538 
  539         XD3_ASSERT (blkoff != blksize);
  540 
  541         /* Check if we have enough data on this block to
  542          * finish the instruction. */
  543         if (blkoff + take <= blksize)
  544           {
  545             inst->type = XD3_NOOP;
  546             inst->size = 0;
  547           }
  548         else
  549           {
  550             take = blksize - blkoff;
  551             inst->size -= take;
  552             inst->addr += take;
  553 
  554             /* because (blkoff + take > blksize), above */
  555             XD3_ASSERT (inst->size != 0);
  556           }
  557           }
  558       }
  559     else
  560       {
  561         /* TODO: the memcpy/overlap optimization, etc.  Overlap
  562          * here could be more specific, it's whether (inst->addr -
  563          * srclen) + inst->size > input_pos ?  And is the system
  564          * memcpy really any good? */
  565         overlap = 1;
  566 
  567         /* For a target-window copy, we know the entire range is
  568          * in-memory.  The dec_tgtaddrbase is negatively offset by
  569          * dec_cpylen because the addresses start beyond that
  570          * point. */
  571         src = stream->dec_tgtaddrbase + inst->addr;
  572         inst->type = XD3_NOOP;
  573         inst->size = 0;
  574       }
  575 
  576     dst = stream->next_out + stream->avail_out;
  577 
  578     stream->avail_out += take;
  579 
  580     if (overlap)
  581       {
  582         /* Can't just memcpy here due to possible overlap. */
  583         for (i = take; i != 0; i -= 1)
  584           {
  585         *dst++ = *src++;
  586           }
  587       }
  588     else
  589       {
  590         memcpy (dst, src, take);
  591       }
  592       }
  593     }
  594 
  595   return 0;
  596 }
  597 
  598 static int
  599 xd3_decode_finish_window (xd3_stream *stream)
  600 {
  601   stream->dec_winbytes  = 0;
  602   stream->dec_state     = DEC_FINISH;
  603 
  604   stream->data_sect.pos = 0;
  605   stream->inst_sect.pos = 0;
  606   stream->addr_sect.pos = 0;
  607 
  608   return XD3_OUTPUT;
  609 }
  610 
  611 static int
  612 xd3_decode_secondary_sections (xd3_stream *secondary_stream)
  613 {
  614 #if SECONDARY_ANY
  615   int ret;
  616 #define DECODE_SECONDARY_SECTION(UPPER,LOWER) \
  617   ((secondary_stream->dec_del_ind & VCD_ ## UPPER ## COMP) && \
  618    (ret = xd3_decode_secondary (secondary_stream, \
  619                 & secondary_stream-> LOWER ## _sect,    \
  620                 & xd3_sec_ ## LOWER (secondary_stream))))
  621 
  622   if (DECODE_SECONDARY_SECTION (DATA, data) ||
  623       DECODE_SECONDARY_SECTION (INST, inst) ||
  624       DECODE_SECONDARY_SECTION (ADDR, addr))
  625     {
  626       return ret;
  627     }
  628 #undef DECODE_SECONDARY_SECTION
  629 #endif
  630   return 0;
  631 }
  632 
  633 static int
  634 xd3_decode_sections (xd3_stream *stream)
  635 {
  636   usize_t need, more, take;
  637   int copy, ret;
  638 
  639   if ((stream->flags & XD3_JUST_HDR) != 0)
  640     {
  641       /* Nothing left to do. */
  642       return xd3_decode_finish_window (stream);
  643     }
  644 
  645   /* To avoid extra copying, allocate three sections at once (but
  646    * check for overflow). */
  647   need = stream->inst_sect.size;
  648 
  649   if (USIZE_T_OVERFLOW (need, stream->addr_sect.size))
  650     {
  651       stream->msg = "decoder section size overflow";
  652       return XD3_INTERNAL;
  653     }
  654   need += stream->addr_sect.size;
  655 
  656   if (USIZE_T_OVERFLOW (need, stream->data_sect.size))
  657     {
  658       stream->msg = "decoder section size overflow";
  659       return XD3_INTERNAL;
  660     }
  661   need += stream->data_sect.size;
  662 
  663   /* The window may be entirely processed. */
  664   XD3_ASSERT (stream->dec_winbytes <= need);
  665 
  666   /* Compute how much more input is needed. */
  667   more = (need - stream->dec_winbytes);
  668 
  669   /* How much to consume. */
  670   take = xd3_min (more, stream->avail_in);
  671 
  672   /* See if the input is completely available, to avoid copy. */
  673   copy = (take != more);
  674 
  675   /* If the window is skipped... */
  676   if ((stream->flags & XD3_SKIP_WINDOW) != 0)
  677     {
  678       /* Skip the available input. */
  679       DECODE_INPUT (take);
  680 
  681       stream->dec_winbytes += take;
  682 
  683       if (copy)
  684     {
  685       stream->msg = "further input required";
  686       return XD3_INPUT;
  687     }
  688 
  689       return xd3_decode_finish_window (stream);
  690     }
  691 
  692   /* Process all but the DATA section. */
  693   switch (stream->dec_state)
  694     {
  695     default:
  696       stream->msg = "internal error";
  697       return XD3_INVALID_INPUT;
  698 
  699     case DEC_DATA:
  700       if ((ret = xd3_decode_section (stream, & stream->data_sect,
  701                      DEC_INST, copy))) { return ret; }
  702     case DEC_INST:
  703       if ((ret = xd3_decode_section (stream, & stream->inst_sect,
  704                      DEC_ADDR, copy))) { return ret; }
  705     case DEC_ADDR:
  706       if ((ret = xd3_decode_section (stream, & stream->addr_sect,
  707                      DEC_EMIT, copy))) { return ret; }
  708     }
  709 
  710   XD3_ASSERT (stream->dec_winbytes == need);
  711 
  712   if ((ret = xd3_decode_secondary_sections (stream))) { return ret; }
  713 
  714   if (stream->flags & XD3_SKIP_EMIT)
  715     {
  716       return xd3_decode_finish_window (stream);
  717     }
  718 
  719   /* OPT: A possible optimization is to avoid allocating memory in
  720    * decode_setup_buffers and to avoid a large memcpy when the window
  721    * consists of a single VCD_SOURCE copy instruction. */
  722   if ((ret = xd3_decode_setup_buffers (stream))) { return ret; }
  723 
  724   return 0;
  725 }
  726 
  727 static int
  728 xd3_decode_emit (xd3_stream *stream)
  729 {
  730   int ret;
  731 
  732   /* Produce output: originally structured to allow reentrant code
  733    * that fills as much of the output buffer as possible, but VCDIFF
  734    * semantics allows to copy from anywhere from the target window, so
  735    * instead allocate a sufficiently sized buffer after the target
  736    * window length is decoded.
  737    *
  738    * This code still needs to be reentrant to allow XD3_GETSRCBLK to
  739    * return control.  This is handled by setting the
  740    * stream->dec_currentN instruction types to XD3_NOOP after they
  741    * have been processed. */
  742   XD3_ASSERT (! (stream->flags & XD3_SKIP_EMIT));
  743   XD3_ASSERT (stream->dec_tgtlen <= stream->space_out);
  744 
  745   while (stream->inst_sect.buf != stream->inst_sect.buf_max ||
  746      stream->dec_current1.type != XD3_NOOP ||
  747      stream->dec_current2.type != XD3_NOOP)
  748     {
  749       /* Decode next instruction pair. */
  750       if ((stream->dec_current1.type == XD3_NOOP) &&
  751       (stream->dec_current2.type == XD3_NOOP) &&
  752       (ret = xd3_decode_instruction (stream))) { return ret; }
  753 
  754       /* Output dec_current1 */
  755       while ((stream->dec_current1.type != XD3_NOOP))
  756     {
  757       if ((ret = xd3_decode_output_halfinst (stream, & stream->dec_current1)))
  758         {
  759           return ret;
  760         }
  761     }
  762       /* Output dec_current2 */
  763       while (stream->dec_current2.type != XD3_NOOP)
  764     {
  765       if ((ret = xd3_decode_output_halfinst (stream, & stream->dec_current2)))
  766         {
  767           return ret;
  768         }
  769     }
  770     }
  771 
  772   if (stream->avail_out != stream->dec_tgtlen)
  773     {
  774       IF_DEBUG2 (DP(RINT "AVAIL_OUT(%d) != DEC_TGTLEN(%d)\n",
  775             stream->avail_out, stream->dec_tgtlen));
  776       stream->msg = "wrong window length";
  777       return XD3_INVALID_INPUT;
  778     }
  779 
  780   if (stream->data_sect.buf != stream->data_sect.buf_max)
  781     {
  782       stream->msg = "extra data section";
  783       return XD3_INVALID_INPUT;
  784     }
  785 
  786   if (stream->addr_sect.buf != stream->addr_sect.buf_max)
  787     {
  788       stream->msg = "extra address section";
  789       return XD3_INVALID_INPUT;
  790     }
  791 
  792   /* OPT: Should cksum computation be combined with the above loop? */
  793   if ((stream->dec_win_ind & VCD_ADLER32) != 0 &&
  794       (stream->flags & XD3_ADLER32_NOVER) == 0)
  795     {
  796       uint32_t a32 = adler32 (1L, stream->next_out, stream->avail_out);
  797 
  798       if (a32 != stream->dec_adler32)
  799     {
  800       stream->msg = "target window checksum mismatch";
  801       return XD3_INVALID_INPUT;
  802     }
  803     }
  804 
  805   /* Finished with a window. */
  806   return xd3_decode_finish_window (stream);
  807 }
  808 
  809 int
  810 xd3_decode_input (xd3_stream *stream)
  811 {
  812   int ret;
  813 
  814   if (stream->enc_state != 0)
  815     {
  816       stream->msg = "encoder/decoder transition";
  817       return XD3_INVALID_INPUT;
  818     }
  819 
  820 #define BYTE_CASE(expr,x,nstate) \
  821       do { \
  822       if ( (expr) && \
  823            ((ret = xd3_decode_byte (stream, & (x))) != 0) ) { return ret; } \
  824       stream->dec_state = (nstate); \
  825       } while (0)
  826 
  827 #define OFFSET_CASE(expr,x,nstate) \
  828       do { \
  829       if ( (expr) && \
  830            ((ret = xd3_decode_offset (stream, & (x))) != 0) ) { return ret; } \
  831       stream->dec_state = (nstate); \
  832       } while (0)
  833 
  834 #define SIZE_CASE(expr,x,nstate) \
  835       do { \
  836       if ( (expr) && \
  837            ((ret = xd3_decode_size (stream, & (x))) != 0) ) { return ret; } \
  838       stream->dec_state = (nstate); \
  839       } while (0)
  840 
  841   switch (stream->dec_state)
  842     {
  843     case DEC_VCHEAD:
  844       {
  845     if ((ret = xd3_decode_bytes (stream, stream->dec_magic,
  846                      & stream->dec_magicbytes, 4)))
  847       {
  848         return ret;
  849       }
  850 
  851     if (stream->dec_magic[0] != VCDIFF_MAGIC1 ||
  852         stream->dec_magic[1] != VCDIFF_MAGIC2 ||
  853         stream->dec_magic[2] != VCDIFF_MAGIC3)
  854       {
  855         stream->msg = "not a VCDIFF input";
  856         return XD3_INVALID_INPUT;
  857       }
  858 
  859     if (stream->dec_magic[3] != 0)
  860       {
  861         stream->msg = "VCDIFF input version > 0 is not supported";
  862         return XD3_INVALID_INPUT;
  863       }
  864 
  865     stream->dec_state = DEC_HDRIND;
  866       }
  867     case DEC_HDRIND:
  868       {
  869     if ((ret = xd3_decode_byte (stream, & stream->dec_hdr_ind)))
  870       {
  871         return ret;
  872       }
  873 
  874     if ((stream->dec_hdr_ind & VCD_INVHDR) != 0)
  875       {
  876         stream->msg = "unrecognized header indicator bits set";
  877         return XD3_INVALID_INPUT;
  878       }
  879 
  880     stream->dec_state = DEC_SECONDID;
  881       }
  882 
  883     case DEC_SECONDID:
  884       /* Secondary compressor ID: only if VCD_SECONDARY is set */
  885       if ((stream->dec_hdr_ind & VCD_SECONDARY) != 0)
  886     {
  887       BYTE_CASE (1, stream->dec_secondid, DEC_TABLEN);
  888 
  889       switch (stream->dec_secondid)
  890         {
  891         case VCD_FGK_ID:
  892           FGK_CASE (stream);
  893         case VCD_DJW_ID:
  894           DJW_CASE (stream);
  895         case VCD_LZMA_ID:
  896           LZMA_CASE (stream);
  897         default:
  898           stream->msg = "unknown secondary compressor ID";
  899           return XD3_INVALID_INPUT;
  900         }
  901     }
  902 
  903     case DEC_TABLEN:
  904       /* Length of code table data: only if VCD_CODETABLE is set */
  905       SIZE_CASE ((stream->dec_hdr_ind & VCD_CODETABLE) != 0,
  906          stream->dec_codetblsz, DEC_NEAR);
  907 
  908       /* The codetblsz counts the two NEAR/SAME bytes */
  909       if ((stream->dec_hdr_ind & VCD_CODETABLE) != 0) {
  910     if (stream->dec_codetblsz <= 2) {
  911       stream->msg = "invalid code table size";
  912       return ENOMEM;
  913     }
  914     stream->dec_codetblsz -= 2;
  915       }
  916     case DEC_NEAR:
  917       /* Near modes: only if VCD_CODETABLE is set */
  918       BYTE_CASE((stream->dec_hdr_ind & VCD_CODETABLE) != 0,
  919         stream->acache.s_near, DEC_SAME);
  920     case DEC_SAME:
  921       /* Same modes: only if VCD_CODETABLE is set */
  922       BYTE_CASE((stream->dec_hdr_ind & VCD_CODETABLE) != 0,
  923         stream->acache.s_same, DEC_TABDAT);
  924     case DEC_TABDAT:
  925       /* Compressed code table data */
  926 
  927       if ((stream->dec_hdr_ind & VCD_CODETABLE) != 0)
  928     {
  929       stream->msg = "VCD_CODETABLE support was removed";
  930       return XD3_UNIMPLEMENTED;
  931     }
  932       else
  933     {
  934       /* Use the default table. */
  935       stream->acache.s_near = __rfc3284_code_table_desc.near_modes;
  936       stream->acache.s_same = __rfc3284_code_table_desc.same_modes;
  937       stream->code_table    = xd3_rfc3284_code_table ();
  938     }
  939 
  940       if ((ret = xd3_alloc_cache (stream))) { return ret; }
  941 
  942       stream->dec_state = DEC_APPLEN;
  943 
  944     case DEC_APPLEN:
  945       /* Length of application data */
  946       SIZE_CASE((stream->dec_hdr_ind & VCD_APPHEADER) != 0,
  947         stream->dec_appheadsz, DEC_APPDAT);
  948 
  949     case DEC_APPDAT:
  950       /* Application data */
  951       if (stream->dec_hdr_ind & VCD_APPHEADER)
  952     {
  953       /* Note: we add an additional byte for padding, to allow
  954          0-termination. Check for overflow: */
  955       if (USIZE_T_OVERFLOW(stream->dec_appheadsz, 1))
  956         {
  957           stream->msg = "exceptional appheader size";
  958           return XD3_INVALID_INPUT;
  959         }
  960 
  961       if ((stream->dec_appheader == NULL) &&
  962           (stream->dec_appheader =
  963            (uint8_t*) xd3_alloc (stream,
  964                      stream->dec_appheadsz+1, 1)) == NULL)
  965         {
  966           return ENOMEM;
  967         }
  968 
  969       stream->dec_appheader[stream->dec_appheadsz] = 0;
  970 
  971       if ((ret = xd3_decode_bytes (stream, stream->dec_appheader,
  972                        & stream->dec_appheadbytes,
  973                        stream->dec_appheadsz)))
  974         {
  975           return ret;
  976         }
  977     }
  978 
  979       /* xoff_t -> usize_t is safe because this is the first block. */
  980       stream->dec_hdrsize = (usize_t) stream->total_in;
  981       stream->dec_state = DEC_WININD;
  982 
  983     case DEC_WININD:
  984       {
  985     /* Start of a window: the window indicator */
  986     if ((ret = xd3_decode_byte (stream, & stream->dec_win_ind)))
  987       {
  988         return ret;
  989       }
  990 
  991     stream->current_window = stream->dec_window_count;
  992 
  993     if (XOFF_T_OVERFLOW (stream->dec_winstart, stream->dec_tgtlen))
  994       {
  995         stream->msg = "decoder file offset overflow";
  996         return XD3_INVALID_INPUT;
  997       }
  998 
  999     stream->dec_winstart += stream->dec_tgtlen;
 1000 
 1001     if ((stream->dec_win_ind & VCD_INVWIN) != 0)
 1002       {
 1003         stream->msg = "unrecognized window indicator bits set";
 1004         return XD3_INVALID_INPUT;
 1005       }
 1006 
 1007     if ((ret = xd3_decode_init_window (stream))) { return ret; }
 1008 
 1009     stream->dec_state = DEC_CPYLEN;
 1010 
 1011     IF_DEBUG2 (DP(RINT "--------- TARGET WINDOW %"Q"u -----------\n",
 1012               stream->current_window));
 1013       }
 1014 
 1015     case DEC_CPYLEN:
 1016       /* Copy window length: only if VCD_SOURCE or VCD_TARGET is set */
 1017       SIZE_CASE(SRCORTGT (stream->dec_win_ind), stream->dec_cpylen,
 1018         DEC_CPYOFF);
 1019 
 1020       /* Set the initial, logical decoder position (HERE address) in
 1021        * dec_position.  This is set to just after the source/copy
 1022        * window, as we are just about to output the first byte of
 1023        * target window. */
 1024       stream->dec_position = stream->dec_cpylen;
 1025 
 1026     case DEC_CPYOFF:
 1027       /* Copy window offset: only if VCD_SOURCE or VCD_TARGET is set */
 1028       
 1029       OFFSET_CASE(SRCORTGT (stream->dec_win_ind), stream->dec_cpyoff,
 1030           DEC_ENCLEN);
 1031 
 1032       /* Copy offset and copy length may not overflow. */
 1033       if (XOFF_T_OVERFLOW (stream->dec_cpyoff, stream->dec_cpylen))
 1034     {
 1035       stream->msg = "decoder copy window overflows a file offset";
 1036       return XD3_INVALID_INPUT;
 1037     }
 1038 
 1039       /* Check copy window bounds: VCD_TARGET window may not exceed
 1040      current position. */
 1041       if ((stream->dec_win_ind & VCD_TARGET) &&
 1042       (stream->dec_cpyoff + (xoff_t) stream->dec_cpylen >
 1043        stream->dec_winstart))
 1044     {
 1045       stream->msg = "VCD_TARGET window out of bounds";
 1046       return XD3_INVALID_INPUT;
 1047     }
 1048 
 1049     case DEC_ENCLEN:
 1050       /* Length of the delta encoding */
 1051       SIZE_CASE(1, stream->dec_enclen, DEC_TGTLEN);
 1052     case DEC_TGTLEN:
 1053       /* Length of target window */
 1054       SIZE_CASE(1, stream->dec_tgtlen, DEC_DELIND);
 1055 
 1056       /* Set the maximum decoder position, beyond which we should not
 1057        * decode any data.  This is the maximum value for dec_position.
 1058        * This may not exceed the size of a usize_t. */
 1059       if (USIZE_T_OVERFLOW (stream->dec_cpylen, stream->dec_tgtlen))
 1060     {
 1061       stream->msg = "decoder target window overflows a usize_t";
 1062       return XD3_INVALID_INPUT;
 1063     }
 1064 
 1065       /* Check for malicious files. */
 1066       if (stream->dec_tgtlen > XD3_HARDMAXWINSIZE)
 1067     {
 1068       stream->msg = "hard window size exceeded";
 1069       return XD3_INVALID_INPUT;
 1070     }
 1071 
 1072       stream->dec_maxpos = stream->dec_cpylen + stream->dec_tgtlen;
 1073 
 1074     case DEC_DELIND:
 1075       /* Delta indicator */
 1076       BYTE_CASE(1, stream->dec_del_ind, DEC_DATALEN);
 1077 
 1078       if ((stream->dec_del_ind & VCD_INVDEL) != 0)
 1079     {
 1080       stream->msg = "unrecognized delta indicator bits set";
 1081       return XD3_INVALID_INPUT;
 1082     }
 1083 
 1084       /* Delta indicator is only used with secondary compression. */
 1085       if ((stream->dec_del_ind != 0) && (stream->sec_type == NULL))
 1086     {
 1087       stream->msg = "invalid delta indicator bits set";
 1088       return XD3_INVALID_INPUT;
 1089     }
 1090 
 1091       /* Section lengths */
 1092     case DEC_DATALEN:
 1093       SIZE_CASE(1, stream->data_sect.size, DEC_INSTLEN);
 1094     case DEC_INSTLEN:
 1095       SIZE_CASE(1, stream->inst_sect.size, DEC_ADDRLEN);
 1096     case DEC_ADDRLEN:
 1097       SIZE_CASE(1, stream->addr_sect.size, DEC_CKSUM);
 1098 
 1099     case DEC_CKSUM:
 1100       /* Window checksum. */
 1101       if ((stream->dec_win_ind & VCD_ADLER32) != 0)
 1102     {
 1103       int i;
 1104 
 1105       if ((ret = xd3_decode_bytes (stream, stream->dec_cksum,
 1106                        & stream->dec_cksumbytes, 4)))
 1107         {
 1108           return ret;
 1109         }
 1110 
 1111       for (i = 0; i < 4; i += 1)
 1112         {
 1113           stream->dec_adler32 =
 1114         (stream->dec_adler32 << 8) | stream->dec_cksum[i];
 1115         }
 1116     }
 1117 
 1118       stream->dec_state = DEC_DATA;
 1119 
 1120       /* Check dec_enclen for redundency, otherwise it is not really used. */
 1121       {
 1122     usize_t enclen_check =
 1123       (1 + (xd3_sizeof_size (stream->dec_tgtlen) +
 1124         xd3_sizeof_size (stream->data_sect.size) +
 1125         xd3_sizeof_size (stream->inst_sect.size) +
 1126         xd3_sizeof_size (stream->addr_sect.size)) +
 1127        stream->data_sect.size +
 1128        stream->inst_sect.size +
 1129        stream->addr_sect.size +
 1130        ((stream->dec_win_ind & VCD_ADLER32) ? 4 : 0));
 1131 
 1132     if (stream->dec_enclen != enclen_check)
 1133       {
 1134         stream->msg = "incorrect encoding length (redundent)";
 1135         return XD3_INVALID_INPUT;
 1136       }
 1137       }
 1138 
 1139       /* Returning here gives the application a chance to inspect the
 1140        * header, skip the window, etc. */
 1141       if (stream->current_window == 0) { return XD3_GOTHEADER; }
 1142       else                             { return XD3_WINSTART; }
 1143 
 1144     case DEC_DATA:
 1145     case DEC_INST:
 1146     case DEC_ADDR:
 1147       /* Next read the three sections. */
 1148      if ((ret = xd3_decode_sections (stream))) { return ret; }
 1149 
 1150     case DEC_EMIT:
 1151 
 1152       /* To speed VCD_SOURCE block-address calculations, the source
 1153        * cpyoff_blocks and cpyoff_blkoff are pre-computed. */
 1154       if (stream->dec_win_ind & VCD_SOURCE)
 1155     {
 1156       xd3_source *src = stream->src;
 1157 
 1158       if (src == NULL)
 1159         {
 1160           stream->msg = "source input required";
 1161           return XD3_INVALID_INPUT;
 1162         }
 1163 
 1164       xd3_blksize_div(stream->dec_cpyoff, src,
 1165               &src->cpyoff_blocks,
 1166               &src->cpyoff_blkoff);
 1167       
 1168       IF_DEBUG2(DP(RINT
 1169                "[decode_cpyoff] %"Q"u "
 1170                "cpyblkno %"Q"u "
 1171                "cpyblkoff %u "
 1172                "blksize %u\n",
 1173                stream->dec_cpyoff,
 1174                src->cpyoff_blocks,
 1175                src->cpyoff_blkoff,
 1176                src->blksize));
 1177     }
 1178 
 1179       /* xd3_decode_emit returns XD3_OUTPUT on every success. */
 1180       if ((ret = xd3_decode_emit (stream)) == XD3_OUTPUT)
 1181     {
 1182       stream->total_out += (xoff_t) stream->avail_out;
 1183     }
 1184 
 1185       return ret;
 1186 
 1187     case DEC_FINISH:
 1188       {
 1189     if (stream->dec_win_ind & VCD_TARGET)
 1190       {
 1191         if (stream->dec_lastwin == NULL)
 1192           {
 1193         stream->dec_lastwin   = stream->next_out;
 1194         stream->dec_lastspace = stream->space_out;
 1195           }
 1196         else
 1197           {
 1198         xd3_swap_uint8p (& stream->dec_lastwin,
 1199                  & stream->next_out);
 1200         xd3_swap_usize_t (& stream->dec_lastspace,
 1201                   & stream->space_out);
 1202           }
 1203       }
 1204 
 1205     stream->dec_lastlen   = stream->dec_tgtlen;
 1206     stream->dec_laststart = stream->dec_winstart;
 1207     stream->dec_window_count += 1;
 1208 
 1209     /* Note: the updates to dec_winstart & current_window are
 1210      * deferred until after the next DEC_WININD byte is read. */
 1211     stream->dec_state = DEC_WININD;
 1212     return XD3_WINFINISH;
 1213       }
 1214 
 1215     default:
 1216       stream->msg = "invalid state";
 1217       return XD3_INVALID_INPUT;
 1218     }
 1219 }
 1220 
 1221 #endif // _XDELTA3_DECODE_H_