[Git][debian-gis-team/unarr][upstream] New upstream version 1.0.1

Alec leamas gitlab at salsa.debian.org
Tue Oct 2 18:03:41 BST 2018


Alec leamas pushed to branch upstream at Debian GIS Project / unarr


Commits:
37a62798 by Alec Leamas at 2018-10-01T05:38:25Z
New upstream version 1.0.1
- - - - -


30 changed files:

- AUTHORS
- + CHANGELOG.md
- + CMakeLists.txt
- − README
- + README.md
- lzmasdk/7zTypes.h
- lzmasdk/CpuArch.c
- lzmasdk/CpuArch.h
- lzmasdk/LzmaDec.c
- lzmasdk/LzmaDec.h
- lzmasdk/Ppmd.h
- lzmasdk/Ppmd7.c
- lzmasdk/Ppmd7.h
- lzmasdk/Ppmd7Dec.c
- lzmasdk/Ppmd8.c
- lzmasdk/Ppmd8.h
- lzmasdk/Ppmd8Dec.c
- lzmasdk/Precomp.h
- + pkg-config.pc.cmake
- rar/parse-rar.c
- rar/rarvm.c
- rar/rarvm.h
- rar/uncompress-rar.c
- Makefile → test/Makefile
- main.c → test/main.c
- unarr.h
- zip/parse-zip.c
- zip/uncompress-zip.c
- zip/zip.c
- zip/zip.h


Changes:

=====================================
AUTHORS
=====================================
@@ -1,7 +1,9 @@
 unarr contains code by:
 
-* The Unarchiver project (https://code.google.com/p/theunarchiver/)
+* The Unarchiver project (https://bitbucket.org/kosovan/theunarchiver/)
 * Simon Bünzli (zeniko at gmail.com, http://www.zeniko.ch/#SumatraPDF)
+* Felix Kauselmann (licorn at gmail.com)
+* Bastien Nocera (hadess at hadess.net, http://www.hadess.net/)
 
 Most code is licensed under LGPLv3 (see COPYING). Exceptions are in code
 included from other projects:


=====================================
CHANGELOG.md
=====================================
@@ -0,0 +1,26 @@
+# (lib)unarr changelog
+
+## 1.0.1 - 2017-11-04
+This is a bugfix release.
+
+### Fixed
+* Fixed typo in pkg-config.pc.cmake template
+
+## 1.0.0 - 2017-09-22
+
+### Added
+* Cmake based build system for library builds
+* Support for pkg-config (libunarr.pc)
+* Windows compatible export header for DLL builds
+* xz utils / libLZMA can be used as decoder for LZMA1 and XZ (LZMA2) compressed
+ZIP archives.
+* The internal LZMA1 decoder can be replaced with xz utils / libLZMA if present
+
+### Changed
+* LZMA SDK code was updated to version 17.01 beta
+* 7z extraction support is currently broken due to LZMA SDK api changes.
+* Unarr sample application (unarr-test) and its makefile
+  (legacy unarr build system) have been moved to the [test](test) folder
+
+### Fixed
+* Various small bugfixes related to compiler warnings


=====================================
CMakeLists.txt
=====================================
@@ -0,0 +1,150 @@
+cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
+
+project(unarr VERSION 1.0.0 LANGUAGES C)
+set(PROJECT_DESCRIPTION
+  "A decompression library for rar, tar and zip files.")
+
+include(GNUInstallDirs)
+
+# Set build type to default if unset.
+if(NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
+  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
+    "MinSizeRel" "RelWithDebInfo")
+endif()
+
+# Build options
+option(BUILD_SHARED_LIBS "Build ${PROJECT_NAME} as a shared library" ON)
+
+# Build target
+add_library(unarr
+  _7z/_7z.h
+  _7z/_7z.c
+  common/allocator.h
+  common/unarr-imp.h
+  common/conv.c
+  common/crc32.c
+  #common/custalloc.c
+  common/stream.c
+  common/unarr.c
+  lzmasdk/7zTypes.h
+  lzmasdk/CpuArch.h
+  lzmasdk/Ppmd.h
+  lzmasdk/Ppmd7.h
+  lzmasdk/Ppmd8.h
+  lzmasdk/Precomp.h
+  lzmasdk/CpuArch.c
+  lzmasdk/Ppmd7.c
+  lzmasdk/Ppmd8.c
+  lzmasdk/Ppmd7Dec.c
+  lzmasdk/Ppmd8Dec.c
+  rar/lzss.h
+  rar/rar.h
+  rar/rarvm.h
+  rar/filter-rar.c
+  rar/uncompress-rar.c
+  rar/huffman-rar.c
+  rar/rar.c
+  rar/rarvm.c
+  rar/parse-rar.c
+  tar/tar.h
+  tar/parse-tar.c
+  tar/tar.c
+  zip/inflate.h
+  zip/zip.h
+  zip/inflate.c
+  zip/parse-zip.c
+  zip/uncompress-zip.c
+  zip/zip.c)
+
+set_target_properties(unarr PROPERTIES
+                      PUBLIC_HEADER unarr.h
+                      C_VISIBILITY_PRESET hidden
+                      C_STANDARD 99
+                      C_STANDARD_REQUIRED ON
+                      DEFINE_SYMBOL UNARR_EXPORT_SYMBOLS
+                      VERSION ${PROJECT_VERSION}
+                      SOVERSION ${PROJECT_VERSION_MAJOR})
+
+if(BUILD_SHARED_LIBS)
+  target_compile_definitions(unarr PUBLIC UNARR_IS_SHARED_LIBRARY)
+endif()
+
+find_package(BZip2)
+if(BZIP2_FOUND)
+  target_include_directories(unarr PRIVATE ${BZIP_INCLUDE_DIRS})
+  target_link_libraries(unarr ${BZIP2_LIBRARIES})
+  target_compile_definitions(unarr PRIVATE -DHAVE_BZIP2)
+  # Bzip2 upstream does not supply a .pc file. Add it to Libs.private.
+  set(PROJECT_LIBS_PRIVATE "-I${BZIP_INCLUDE_DIRS} -l${BZIP2_LIBRARIES}")
+endif()
+
+find_package(LibLZMA)
+if(LIBLZMA_FOUND)
+  target_include_directories(unarr PRIVATE ${LIBLZMA_INCLUDE_DIRS})
+  target_link_libraries(unarr ${LIBLZMA_LIBRARIES})
+  target_compile_definitions(unarr PRIVATE -DHAVE_LIBLZMA)
+  set(PROJECT_REQUIRES_PRIVATE "${UNARR_REQUIRES_PRIVATE} liblzma")
+else()
+  target_sources(unarr PRIVATE
+    lzmasdk/LzmaDec.h
+    lzmasdk/LzmaDec.c)
+endif()
+
+find_package(ZLIB)
+if(ZLIB_FOUND)
+  target_include_directories(unarr PRIVATE ${ZLIB_INCLUDE_DIRS})
+  target_link_libraries(unarr ${ZLIB_LIBRARIES})
+  target_compile_definitions(unarr PRIVATE -DHAVE_ZLIB)
+  # Add zlib to libunarr.pc Requires.private
+  set(PROJECT_REQUIRES_PRIVATE "${PROJECT_REQUIRES_PRIVATE} zlib")
+endif()
+
+# Compiler specific settings
+
+if(UNIX OR MINGW OR MSYS)
+  target_compile_options(unarr PRIVATE -Wall -Wextra -pedantic
+                    -Wstrict-prototypes -Wmissing-prototypes
+                    -Werror-implicit-function-declaration
+                    $<$<CONFIG:Release>:-fomit-frame-pointer>
+                    $<$<OR:$<C_COMPILER_ID:Clang>,$<C_COMPILER_ID:AppleClang>>:
+                    -Wno-missing-field-initializers>
+                    -flto)
+  target_compile_definitions(unarr PRIVATE -D_FILE_OFFSET_BITS=64)
+
+  # Linker flags
+
+  # Clang linker needs -flto too when doing lto
+  if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+    set_target_properties(unarr PROPERTIES LINK_FLAGS
+                          "-Wl,--no-undefined -Wl,--as-needed -flto")
+  # Apple ld uses different syntax for undefined symbol check
+  elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
+    set_target_properties(unarr PROPERTIES LINK_FLAGS
+                          "-Wl,-undefined,error -flto")
+  else()
+    set_target_properties(unarr PROPERTIES LINK_FLAGS
+                          "-Wl,--no-undefined -Wl,--as-needed")
+  endif()
+endif()
+
+if(MSVC)
+  target_compile_options(unarr PRIVATE /W3
+                        $<$<CONFIG:Release>:/Ox>)
+  target_compile_definitions(unarr PRIVATE _CRT_SECURE_NO_WARNINGS)
+endif()
+
+# Write pkg-config file
+configure_file("pkg-config.pc.cmake" "lib${PROJECT_NAME}.pc" @ONLY)
+
+# Install library and header
+install(TARGETS unarr
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
+# Install pkg-config file
+install(FILES
+        ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${PROJECT_NAME}.pc
+        DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)


=====================================
README deleted
=====================================
@@ -1,24 +0,0 @@
-unarr is a decompression library for RAR, TAR, ZIP and 7z archives.
-
-unarr originated as a port of the RAR extraction features from
-The Unarchiver project required for extracting images from comic
-book archives (.cbr). It was written as an alternative to
-libarchive which didn't have support for parsing filters or solid
-compression at the time.
-
-There is currently only an experimental Linux Makefile for building
-unarr (see ../makefile.msvc for what SumatraPDF does under Windows).
-In any case, compiling unarr should be as simple as compiling all
-files with a C99 compatible compiler (omit main.c if you want to use
-it as a library).
-
-The following symbols can be defined if other libraries are present
-in the include path:
-
-Symbol          Required header Required for (format/method)
-------------------------------------------------------------
-HAVE_ZLIB       zlib.h          faster CRC-32 and Deflate
-HAVE_BZIP2      bzlib.h         ZIP / Bzip2
-HAVE_7Z         7z.h            7Z  / LZMA, LZMA2, BCJ
-
-_7ZIP_PPMD_SUPPPORT             7Z  / PPMd


=====================================
README.md
=====================================
@@ -0,0 +1,87 @@
+# (lib)unarr
+
+**(lib)unarr** is a decompression library for RAR, TAR, ZIP and 7z* archives.
+
+It was forked from **unarr**, which originated as a port of the RAR extraction
+features from The Unarchiver project required for extracting images from comic
+book archives. [Zeniko](https://github.com/zeniko/) wrote unarr as an
+alternative to libarchive which didn't have support for parsing filters or
+solid compression at the time.
+
+While (lib)unarr was started with the intent of providing unarr with a proper
+cmake based build system suitable for packaging and cross-platform development,
+it's focus has now been extended to provide code maintenance and to continue the
+development of unarr, which no longer is maintained.
+
+## Getting started
+
+### Building from source
+
+#### Dependencies
+
+(lib)unarr can take advantage of the following libraries if they are present:
+
+* bzip2
+* xz / libLZMA
+* zlib
+
+More information on what library is used for which purpose can be found in the
+description for embedded builds.
+
+#### Cmake
+
+>mkdir build  
+>cd build  
+>cmake ..  
+>make
+
+... as a static library
+
+>cmake .. -DBUILD_SHARED_LIBS=OFF
+
+Install
+
+>make install  
+
+#### Embedded build
+
+Make sure your compiler is C99 compatible, grab the source code, copy it into your project and adjust your build system accordingly.
+
+You can define the following symbols to take advantage of third party libraries:
+
+| Symbol            | Required header | Required for (format/method)|
+|-------------------|:---------------:|:----------------------------|
+|HAVE_ZLIB          |     zlib.h      |  faster CRC-32 and Deflate  |
+|HAVE_BZIP2         |     bzlib.h     |    ZIP / Bzip2              |
+|HAVE_LIBLZMA       |     lzma.h      |    ZIP / LZMA, XZ(LZMA2)    |
+|HAVE_7Z            |     7z.h        |    7Z* / LZMA, LZMA2, BCJ   |
+|_7ZIP_PPMD_SUPPORT |                 |    7Z* / PPMd               |
+
+Make sure the required headers are present in the include path.
+
+## Usage
+
+### Examples
+
+Check [unarr.h](unarr.h) and [unarr-test](test/main.c) to get a general feel
+for the api and usage.
+
+## Limitations
+
+Unarr was written for comic book archives, so it currently doesn't support:
+
+* password protected archives
+* self extracting archives
+* split archives
+
+### 7z support
+
+7z support is currently broken. This is due to two problems:
+
+1. The version of the LZMA SDK used in the 7z extraction code is outdated and
+no longer compatible with the LZMA code used in the other formats
+2. The ANSI-C based 7z extraction code provided by the LZMA SDK has a known
+performance issue that limits it's usefullness for large files with solid
+compression (see https://github.com/zeniko/unarr/issues/4).
+
+Fixing these problems requires a partial rewrite of the code involved.


=====================================
lzmasdk/7zTypes.h
=====================================
@@ -1,5 +1,5 @@
 /* 7zTypes.h -- Basic types
-2013-11-12 : Igor Pavlov : Public domain */
+2017-07-17 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_TYPES_H
 #define __7Z_TYPES_H
@@ -42,13 +42,23 @@ EXTERN_C_BEGIN
 
 typedef int SRes;
 
+
 #ifdef _WIN32
+
 /* typedef DWORD WRes; */
 typedef unsigned WRes;
+#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
+
 #else
+
 typedef int WRes;
+#define MY__FACILITY_WIN32 7
+#define MY__FACILITY__WRes MY__FACILITY_WIN32
+#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
+
 #endif
 
+
 #ifndef RINOK
 #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
 #endif
@@ -112,48 +122,72 @@ typedef int Bool;
 #define MY_NO_INLINE
 #endif
 
+#define MY_FORCE_INLINE __forceinline
+
 #define MY_CDECL __cdecl
 #define MY_FAST_CALL __fastcall
 
 #else
 
 #define MY_NO_INLINE
+#define MY_FORCE_INLINE
 #define MY_CDECL
 #define MY_FAST_CALL
 
+/* inline keyword : for C++ / C99 */
+
+/* GCC, clang: */
+/*
+#if defined (__GNUC__) && (__GNUC__ >= 4)
+#define MY_FORCE_INLINE __attribute__((always_inline))
+#define MY_NO_INLINE __attribute__((noinline))
+#endif
+*/
+
 #endif
 
 
 /* The following interfaces use first parameter as pointer to structure */
 
-typedef struct
+typedef struct IByteIn IByteIn;
+struct IByteIn
 {
-  Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
-} IByteIn;
+  Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
+};
+#define IByteIn_Read(p) (p)->Read(p)
 
-typedef struct
+
+typedef struct IByteOut IByteOut;
+struct IByteOut
 {
-  void (*Write)(void *p, Byte b);
-} IByteOut;
+  void (*Write)(const IByteOut *p, Byte b);
+};
+#define IByteOut_Write(p, b) (p)->Write(p, b)
 
-typedef struct
+
+typedef struct ISeqInStream ISeqInStream;
+struct ISeqInStream
 {
-  SRes (*Read)(void *p, void *buf, size_t *size);
+  SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
     /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
        (output(*size) < input(*size)) is allowed */
-} ISeqInStream;
+};
+#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
 
 /* it can return SZ_ERROR_INPUT_EOF */
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
 
-typedef struct
+
+typedef struct ISeqOutStream ISeqOutStream;
+struct ISeqOutStream
 {
-  size_t (*Write)(void *p, const void *buf, size_t size);
+  size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
     /* Returns: result - the number of actually written bytes.
        (result < size) means error */
-} ISeqOutStream;
+};
+#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
 
 typedef enum
 {
@@ -162,78 +196,162 @@ typedef enum
   SZ_SEEK_END = 2
 } ESzSeek;
 
-typedef struct
+
+typedef struct ISeekInStream ISeekInStream;
+struct ISeekInStream
 {
-  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
-  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-} ISeekInStream;
+  SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
+  SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
+};
+#define ISeekInStream_Read(p, buf, size)   (p)->Read(p, buf, size)
+#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
 
-typedef struct
+
+typedef struct ILookInStream ILookInStream;
+struct ILookInStream
 {
-  SRes (*Look)(void *p, const void **buf, size_t *size);
+  SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
     /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
        (output(*size) > input(*size)) is not allowed
        (output(*size) < input(*size)) is allowed */
-  SRes (*Skip)(void *p, size_t offset);
+  SRes (*Skip)(const ILookInStream *p, size_t offset);
     /* offset must be <= output(*size) of Look */
 
-  SRes (*Read)(void *p, void *buf, size_t *size);
+  SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
     /* reads directly (without buffer). It's same as ISeqInStream::Read */
-  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-} ILookInStream;
+  SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
+};
 
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+#define ILookInStream_Look(p, buf, size)   (p)->Look(p, buf, size)
+#define ILookInStream_Skip(p, offset)      (p)->Skip(p, offset)
+#define ILookInStream_Read(p, buf, size)   (p)->Read(p, buf, size)
+#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
+
+
+SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
 
 /* reads via ILookInStream::Read */
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
+
 
-#define LookToRead_BUF_SIZE (1 << 14)
 
 typedef struct
 {
-  ILookInStream s;
-  ISeekInStream *realStream;
+  ILookInStream vt;
+  const ISeekInStream *realStream;
+ 
   size_t pos;
-  size_t size;
-  Byte buf[LookToRead_BUF_SIZE];
-} CLookToRead;
+  size_t size; /* it's data size */
+  
+  /* the following variables must be set outside */
+  Byte *buf;
+  size_t bufSize;
+} CLookToRead2;
+
+void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
+
+#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
 
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
-void LookToRead_Init(CLookToRead *p);
 
 typedef struct
 {
-  ISeqInStream s;
-  ILookInStream *realStream;
+  ISeqInStream vt;
+  const ILookInStream *realStream;
 } CSecToLook;
 
 void SecToLook_CreateVTable(CSecToLook *p);
 
+
+
 typedef struct
 {
-  ISeqInStream s;
-  ILookInStream *realStream;
+  ISeqInStream vt;
+  const ILookInStream *realStream;
 } CSecToRead;
 
 void SecToRead_CreateVTable(CSecToRead *p);
 
-typedef struct
+
+typedef struct ICompressProgress ICompressProgress;
+
+struct ICompressProgress
 {
-  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+  SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
     /* Returns: result. (result != SZ_OK) means break.
        Value (UInt64)(Int64)-1 for size means unknown value. */
-} ICompressProgress;
+};
+#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
 
-typedef struct
+
+
+typedef struct ISzAlloc ISzAlloc;
+typedef const ISzAlloc * ISzAllocPtr;
+
+struct ISzAlloc
 {
-  void *(*Alloc)(void *p, size_t size);
-  void (*Free)(void *p, void *address); /* address can be 0 */
-} ISzAlloc;
+  void *(*Alloc)(ISzAllocPtr p, size_t size);
+  void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
+};
+
+#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
+#define ISzAlloc_Free(p, a) (p)->Free(p, a)
+
+/* deprecated */
+#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
+#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
+
+
+
+
+
+#ifndef MY_offsetof
+  #ifdef offsetof
+    #define MY_offsetof(type, m) offsetof(type, m)
+    /*
+    #define MY_offsetof(type, m) FIELD_OFFSET(type, m)
+    */
+  #else
+    #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
+  #endif
+#endif
+
+
+
+#ifndef MY_container_of
+
+/*
+#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
+#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
+#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
+#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
+*/
+
+/*
+  GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
+    GCC 3.4.4 : classes with constructor
+    GCC 4.8.1 : classes with non-public variable members"
+*/
+
+#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
+
+
+#endif
+
+#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
+
+/*
+#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
+*/
+#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
+
+#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
+/*
+#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
+*/
+
 
-#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
-#define IAlloc_Free(p, a) (p)->Free((p), a)
 
 #ifdef _WIN32
 


=====================================
lzmasdk/CpuArch.c
=====================================
@@ -1,5 +1,5 @@
 /* CpuArch.c -- CPU specific code
-2012-05-29: Igor Pavlov : Public domain */
+2016-02-25: Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
     "push %%EDX\n\t"
     "popf\n\t"
     "andl %%EAX, %0\n\t":
-    "=c" (flag) : "c" (flag));
+    "=c" (flag) : "c" (flag) :
+    "%eax", "%edx");
   #endif
   return flag;
 }
@@ -54,7 +55,7 @@ static UInt32 CheckFlag(UInt32 flag)
 #define CHECK_CPUID_IS_SUPPORTED
 #endif
 
-static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
+void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
 {
   #ifdef USE_ASM
 
@@ -79,7 +80,13 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
   #else
 
   __asm__ __volatile__ (
-  #if defined(MY_CPU_X86) && defined(__PIC__)
+  #if defined(MY_CPU_AMD64) && defined(__PIC__)
+    "mov %%rbx, %%rdi;"
+    "cpuid;"
+    "xchg %%rbx, %%rdi;"
+    : "=a" (*a) ,
+      "=D" (*b) ,
+  #elif defined(MY_CPU_X86) && defined(__PIC__)
     "mov %%ebx, %%edi;"
     "cpuid;"
     "xchgl %%ebx, %%edi;"
@@ -116,7 +123,7 @@ Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
   return True;
 }
 
-static UInt32 kVendors[][3] =
+static const UInt32 kVendors[][3] =
 {
   { 0x756E6547, 0x49656E69, 0x6C65746E},
   { 0x68747541, 0x69746E65, 0x444D4163},
@@ -144,18 +151,21 @@ Bool CPU_Is_InOrder()
   UInt32 family, model;
   if (!x86cpuid_CheckAndRead(&p))
     return True;
-  family = x86cpuid_GetFamily(&p);
-  model = x86cpuid_GetModel(&p);
+
+  family = x86cpuid_GetFamily(p.ver);
+  model = x86cpuid_GetModel(p.ver);
+  
   firm = x86cpuid_GetFirm(&p);
+
   switch (firm)
   {
     case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
-        /* Atom CPU */
-           model == 0x100C  /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
-        || model == 0x2006  /* 45 nm, Z6xx */
-        || model == 0x2007  /* 32 nm, Z2460 */
-        || model == 0x3005  /* 32 nm, Z2760 */
-        || model == 0x3006  /* 32 nm, N2xxx, D2xxx */
+        /* In-Order Atom CPU */
+           model == 0x1C  /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
+        || model == 0x26  /* 45 nm, Z6xx */
+        || model == 0x27  /* 32 nm, Z2460 */
+        || model == 0x35  /* 32 nm, Z2760 */
+        || model == 0x36  /* 32 nm, N2xxx, D2xxx */
         )));
     case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
     case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));


=====================================
lzmasdk/CpuArch.h
=====================================
@@ -1,157 +1,335 @@
-/* CpuArch.h -- CPU specific code
-2013-11-12: Igor Pavlov : Public domain */
-
-#ifndef __CPU_ARCH_H
-#define __CPU_ARCH_H
-
-#include "7zTypes.h"
-
-EXTERN_C_BEGIN
-
-/*
-MY_CPU_LE means that CPU is LITTLE ENDIAN.
-If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
-
-MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
-If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
-*/
-
-#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
-#define MY_CPU_AMD64
-#endif
-
-#if defined(MY_CPU_AMD64) || defined(_M_IA64)
-#define MY_CPU_64BIT
-#endif
-
-#if defined(_M_IX86) || defined(__i386__)
-#define MY_CPU_X86
-#endif
-
-#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
-#define MY_CPU_X86_OR_AMD64
-#endif
-
-#if defined(MY_CPU_X86) || defined(_M_ARM)
-#define MY_CPU_32BIT
-#endif
-
-#if defined(_WIN32) && defined(_M_ARM)
-#define MY_CPU_ARM_LE
-#endif
-
-#if defined(_WIN32) && defined(_M_IA64)
-#define MY_CPU_IA64_LE
-#endif
-
-#if defined(MY_CPU_X86_OR_AMD64)
-#define MY_CPU_LE_UNALIGN
-#endif
-
-#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE)  || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
-#define MY_CPU_LE
-#endif
-
-#if defined(__BIG_ENDIAN__) || defined(__m68k__) ||  defined(__ARMEB__) || defined(__MIPSEB__)
-#define MY_CPU_BE
-#endif
-
-#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
-Stop_Compiling_Bad_Endian
-#endif
-
-#ifdef MY_CPU_LE_UNALIGN
-
-#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
-#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
-#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
-#define SetUi16(p, d) *(UInt16 *)(p) = (d);
-#define SetUi32(p, d) *(UInt32 *)(p) = (d);
-#define SetUi64(p, d) *(UInt64 *)(p) = (d);
-
-#else
-
-#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
-
-#define GetUi32(p) ( \
-             ((const Byte *)(p))[0]        | \
-    ((UInt32)((const Byte *)(p))[1] <<  8) | \
-    ((UInt32)((const Byte *)(p))[2] << 16) | \
-    ((UInt32)((const Byte *)(p))[3] << 24))
-
-#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
-
-#define SetUi16(p, d) { UInt32 _x_ = (d); \
-    ((Byte *)(p))[0] = (Byte)_x_; \
-    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
-
-#define SetUi32(p, d) { UInt32 _x_ = (d); \
-    ((Byte *)(p))[0] = (Byte)_x_; \
-    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
-    ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
-    ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
-
-#define SetUi64(p, d) { UInt64 _x64_ = (d); \
-    SetUi32(p, (UInt32)_x64_); \
-    SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
-
-#endif
-
-#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
-
-#include <stdlib.h>
-
-#pragma intrinsic(_byteswap_ulong)
-#pragma intrinsic(_byteswap_uint64)
-#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
-#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
-
-#else
-
-#define GetBe32(p) ( \
-    ((UInt32)((const Byte *)(p))[0] << 24) | \
-    ((UInt32)((const Byte *)(p))[1] << 16) | \
-    ((UInt32)((const Byte *)(p))[2] <<  8) | \
-             ((const Byte *)(p))[3] )
-
-#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
-
-#endif
-
-#define GetBe16(p) ((UInt16)(((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]))
-
-
-#ifdef MY_CPU_X86_OR_AMD64
-
-typedef struct
-{
-  UInt32 maxFunc;
-  UInt32 vendor[3];
-  UInt32 ver;
-  UInt32 b;
-  UInt32 c;
-  UInt32 d;
-} Cx86cpuid;
-
-enum
-{
-  CPU_FIRM_INTEL,
-  CPU_FIRM_AMD,
-  CPU_FIRM_VIA
-};
-
-Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
-int x86cpuid_GetFirm(const Cx86cpuid *p);
-
-#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
-#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
-#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
-
-Bool CPU_Is_InOrder();
-Bool CPU_Is_Aes_Supported();
-
-#endif
-
-EXTERN_C_END
-
-#endif
+/* CpuArch.h -- CPU specific code
+2017-06-30 : Igor Pavlov : Public domain */
+
+#ifndef __CPU_ARCH_H
+#define __CPU_ARCH_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+/*
+MY_CPU_LE means that CPU is LITTLE ENDIAN.
+MY_CPU_BE means that CPU is BIG ENDIAN.
+If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
+
+MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
+*/
+
+#if  defined(_M_X64) \
+  || defined(_M_AMD64) \
+  || defined(__x86_64__) \
+  || defined(__AMD64__) \
+  || defined(__amd64__)
+  #define MY_CPU_AMD64
+  #ifdef __ILP32__
+    #define MY_CPU_NAME "x32"
+  #else
+    #define MY_CPU_NAME "x64"
+  #endif
+  #define MY_CPU_64BIT
+#endif
+
+
+#if  defined(_M_IX86) \
+  || defined(__i386__)
+  #define MY_CPU_X86
+  #define MY_CPU_NAME "x86"
+  #define MY_CPU_32BIT
+#endif
+
+
+#if  defined(_M_ARM64) \
+  || defined(__AARCH64EL__) \
+  || defined(__AARCH64EB__) \
+  || defined(__aarch64__)
+  #define MY_CPU_ARM64
+  #define MY_CPU_NAME "arm64"
+  #define MY_CPU_64BIT
+#endif
+
+
+#if  defined(_M_ARM) \
+  || defined(_M_ARM_NT) \
+  || defined(_M_ARMT) \
+  || defined(__arm__) \
+  || defined(__thumb__) \
+  || defined(__ARMEL__) \
+  || defined(__ARMEB__) \
+  || defined(__THUMBEL__) \
+  || defined(__THUMBEB__)
+  #define MY_CPU_ARM
+  #define MY_CPU_NAME "arm"
+  #define MY_CPU_32BIT
+#endif
+
+
+#if  defined(_M_IA64) \
+  || defined(__ia64__)
+  #define MY_CPU_IA64
+  #define MY_CPU_NAME "ia64"
+  #define MY_CPU_64BIT
+#endif
+
+
+#if  defined(__mips64) \
+  || defined(__mips64__) \
+  || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
+  #define MY_CPU_NAME "mips64"
+  #define MY_CPU_64BIT
+#elif defined(__mips__)
+  #define MY_CPU_NAME "mips"
+  /* #define MY_CPU_32BIT */
+#endif
+
+
+#if  defined(__ppc64__) \
+  || defined(__powerpc64__)
+  #ifdef __ILP32__
+    #define MY_CPU_NAME "ppc64-32"
+  #else
+    #define MY_CPU_NAME "ppc64"
+  #endif
+  #define MY_CPU_64BIT
+#elif defined(__ppc__) \
+  || defined(__powerpc__)
+  #define MY_CPU_NAME "ppc"
+  #define MY_CPU_32BIT
+#endif
+
+
+#if  defined(__sparc64__)
+  #define MY_CPU_NAME "sparc64"
+  #define MY_CPU_64BIT
+#elif defined(__sparc__)
+  #define MY_CPU_NAME "sparc"
+  /* #define MY_CPU_32BIT */
+#endif
+
+
+#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
+#define MY_CPU_X86_OR_AMD64
+#endif
+
+
+#ifdef _WIN32
+
+  #ifdef MY_CPU_ARM
+  #define MY_CPU_ARM_LE
+  #endif
+
+  #ifdef MY_CPU_ARM64
+  #define MY_CPU_ARM64_LE
+  #endif
+
+  #ifdef _M_IA64
+  #define MY_CPU_IA64_LE
+  #endif
+
+#endif
+
+
+#if defined(MY_CPU_X86_OR_AMD64) \
+    || defined(MY_CPU_ARM_LE) \
+    || defined(MY_CPU_ARM64_LE) \
+    || defined(MY_CPU_IA64_LE) \
+    || defined(__LITTLE_ENDIAN__) \
+    || defined(__ARMEL__) \
+    || defined(__THUMBEL__) \
+    || defined(__AARCH64EL__) \
+    || defined(__MIPSEL__) \
+    || defined(__MIPSEL) \
+    || defined(_MIPSEL) \
+    || defined(__BFIN__) \
+    || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
+  #define MY_CPU_LE
+#endif
+
+#if defined(__BIG_ENDIAN__) \
+    || defined(__ARMEB__) \
+    || defined(__THUMBEB__) \
+    || defined(__AARCH64EB__) \
+    || defined(__MIPSEB__) \
+    || defined(__MIPSEB) \
+    || defined(_MIPSEB) \
+    || defined(__m68k__) \
+    || defined(__s390__) \
+    || defined(__s390x__) \
+    || defined(__zarch__) \
+    || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
+  #define MY_CPU_BE
+#endif
+
+
+#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
+  #error Stop_Compiling_Bad_Endian
+#endif
+
+
+#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
+  #error Stop_Compiling_Bad_32_64_BIT
+#endif
+
+
+#ifndef MY_CPU_NAME
+  #ifdef MY_CPU_LE
+    #define MY_CPU_NAME "LE"
+  #elif defined (MY_CPU_BE)
+    #define MY_CPU_NAME "BE"
+  #else
+    /*
+    #define MY_CPU_NAME ""
+    */
+  #endif
+#endif
+
+
+
+
+
+#ifdef MY_CPU_LE
+  #if defined(MY_CPU_X86_OR_AMD64) \
+      || defined(MY_CPU_ARM64) \
+      || defined(__ARM_FEATURE_UNALIGNED)
+    #define MY_CPU_LE_UNALIGN
+  #endif
+#endif
+
+
+#ifdef MY_CPU_LE_UNALIGN
+
+#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
+#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
+#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
+
+#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
+#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
+#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
+
+#else
+
+#define GetUi16(p) ( (UInt16) ( \
+             ((const Byte *)(p))[0] | \
+    ((UInt16)((const Byte *)(p))[1] << 8) ))
+
+#define GetUi32(p) ( \
+             ((const Byte *)(p))[0]        | \
+    ((UInt32)((const Byte *)(p))[1] <<  8) | \
+    ((UInt32)((const Byte *)(p))[2] << 16) | \
+    ((UInt32)((const Byte *)(p))[3] << 24))
+
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
+
+#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+    _ppp_[0] = (Byte)_vvv_; \
+    _ppp_[1] = (Byte)(_vvv_ >> 8); }
+
+#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+    _ppp_[0] = (Byte)_vvv_; \
+    _ppp_[1] = (Byte)(_vvv_ >> 8); \
+    _ppp_[2] = (Byte)(_vvv_ >> 16); \
+    _ppp_[3] = (Byte)(_vvv_ >> 24); }
+
+#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
+    SetUi32(_ppp2_    , (UInt32)_vvv2_); \
+    SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
+
+#endif
+
+#ifdef __has_builtin
+  #define MY__has_builtin(x) __has_builtin(x)
+#else
+  #define MY__has_builtin(x) 0
+#endif
+
+#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
+
+/* Note: we use bswap instruction, that is unsupported in 386 cpu */
+
+#include <stdlib.h>
+
+#pragma intrinsic(_byteswap_ushort)
+#pragma intrinsic(_byteswap_ulong)
+#pragma intrinsic(_byteswap_uint64)
+
+/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
+
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
+
+#elif defined(MY_CPU_LE_UNALIGN) && ( \
+       (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
+    || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
+
+/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
+#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
+
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
+
+#else
+
+#define GetBe32(p) ( \
+    ((UInt32)((const Byte *)(p))[0] << 24) | \
+    ((UInt32)((const Byte *)(p))[1] << 16) | \
+    ((UInt32)((const Byte *)(p))[2] <<  8) | \
+             ((const Byte *)(p))[3] )
+
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
+
+#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+    _ppp_[0] = (Byte)(_vvv_ >> 24); \
+    _ppp_[1] = (Byte)(_vvv_ >> 16); \
+    _ppp_[2] = (Byte)(_vvv_ >> 8); \
+    _ppp_[3] = (Byte)_vvv_; }
+
+#endif
+
+
+#ifndef GetBe16
+
+#define GetBe16(p) ( (UInt16) ( \
+    ((UInt16)((const Byte *)(p))[0] << 8) | \
+             ((const Byte *)(p))[1] ))
+
+#endif
+
+
+
+#ifdef MY_CPU_X86_OR_AMD64
+
+typedef struct
+{
+  UInt32 maxFunc;
+  UInt32 vendor[3];
+  UInt32 ver;
+  UInt32 b;
+  UInt32 c;
+  UInt32 d;
+} Cx86cpuid;
+
+enum
+{
+  CPU_FIRM_INTEL,
+  CPU_FIRM_AMD,
+  CPU_FIRM_VIA
+};
+
+void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
+
+Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
+int x86cpuid_GetFirm(const Cx86cpuid *p);
+
+#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
+#define x86cpuid_GetModel(ver)  (((ver >> 12) &  0xF0) | ((ver >> 4) & 0xF))
+#define x86cpuid_GetStepping(ver) (ver & 0xF)
+
+Bool CPU_Is_InOrder(void);
+Bool CPU_Is_Aes_Supported(void);
+
+#endif
+
+EXTERN_C_END
+
+#endif


=====================================
lzmasdk/LzmaDec.c
=====================================
@@ -1,5 +1,5 @@
 /* LzmaDec.c -- LZMA Decoder
-2015-01-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -114,14 +114,14 @@
 #define Literal (RepLenCoder + kNumLenProbs)
 
 #define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+#define LZMA_LIT_SIZE 0x300
 
 #if Literal != LZMA_BASE_SIZE
 StopCompilingDueBUG
 #endif
 
+#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
 #define LZMA_DIC_MIN (1 << 12)
 
 /* First LZMA-symbol is always decoded.
@@ -133,8 +133,8 @@ Out:
   p->remainLen:
     < kMatchSpecLenStart : normal remain
     = kMatchSpecLenStart : finished
-    = kMatchSpecLenStart + 1 : Flush marker
-    = kMatchSpecLenStart + 2 : State Init Marker
+    = kMatchSpecLenStart + 1 : Flush marker (unused now)
+    = kMatchSpecLenStart + 2 : State Init Marker (unused now)
 */
 
 static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
@@ -150,7 +150,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
   Byte *dic = p->dic;
   SizeT dicBufSize = p->dicBufSize;
   SizeT dicPos = p->dicPos;
-  
+
   UInt32 processedPos = p->processedPos;
   UInt32 checkDicSize = p->checkDicSize;
   unsigned len = 0;
@@ -172,9 +172,10 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
       unsigned symbol;
       UPDATE_0(prob);
       prob = probs + Literal;
-      if (checkDicSize != 0 || processedPos != 0)
-        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
-        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+      if (processedPos != 0 || checkDicSize != 0)
+        prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+            (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+      processedPos++;
 
       if (state < kNumLitStates)
       {
@@ -195,7 +196,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
       }
       else
       {
-        unsigned matchByte = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+        unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
         unsigned offs = 0x100;
         state -= (state < 10) ? 3 : 6;
         symbol = 1;
@@ -222,11 +223,11 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
         }
         #endif
       }
+
       dic[dicPos++] = (Byte)symbol;
-      processedPos++;
       continue;
     }
-    else
+
     {
       UPDATE_1(prob);
       prob = probs + IsRep + state;
@@ -249,7 +250,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
           IF_BIT_0(prob)
           {
             UPDATE_0(prob);
-            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+            dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
             dicPos++;
             processedPos++;
             state = state < kNumLitStates ? 9 : 11;
@@ -290,15 +291,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
         state = state < kNumLitStates ? 8 : 11;
         prob = probs + RepLenCoder;
       }
+
+      #ifdef _LZMA_SIZE_OPT
       {
-        unsigned limit, offset;
+        unsigned lim, offset;
         CLzmaProb *probLen = prob + LenChoice;
         IF_BIT_0(probLen)
         {
           UPDATE_0(probLen);
           probLen = prob + LenLow + (posState << kLenNumLowBits);
           offset = 0;
-          limit = (1 << kLenNumLowBits);
+          lim = (1 << kLenNumLowBits);
         }
         else
         {
@@ -309,19 +312,55 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
             UPDATE_0(probLen);
             probLen = prob + LenMid + (posState << kLenNumMidBits);
             offset = kLenNumLowSymbols;
-            limit = (1 << kLenNumMidBits);
+            lim = (1 << kLenNumMidBits);
           }
           else
           {
             UPDATE_1(probLen);
             probLen = prob + LenHigh;
             offset = kLenNumLowSymbols + kLenNumMidSymbols;
-            limit = (1 << kLenNumHighBits);
+            lim = (1 << kLenNumHighBits);
           }
         }
-        TREE_DECODE(probLen, limit, len);
+        TREE_DECODE(probLen, lim, len);
         len += offset;
       }
+      #else
+      {
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0(probLen)
+        {
+          UPDATE_0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          len = 1;
+          TREE_GET_BIT(probLen, len);
+          TREE_GET_BIT(probLen, len);
+          TREE_GET_BIT(probLen, len);
+          len -= 8;
+        }
+        else
+        {
+          UPDATE_1(probLen);
+          probLen = prob + LenChoice2;
+          IF_BIT_0(probLen)
+          {
+            UPDATE_0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            len = 1;
+            TREE_GET_BIT(probLen, len);
+            TREE_GET_BIT(probLen, len);
+            TREE_GET_BIT(probLen, len);
+          }
+          else
+          {
+            UPDATE_1(probLen);
+            probLen = prob + LenHigh;
+            TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
+            len += kLenNumLowSymbols + kLenNumMidSymbols;
+          }
+        }
+      }
+      #endif
 
       if (state >= kNumStates)
       {
@@ -332,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
         if (distance >= kStartPosModelIndex)
         {
           unsigned posSlot = (unsigned)distance;
-          int numDirectBits = (int)(((distance >> 1) - 1));
+          unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
           distance = (2 | (distance & 1));
           if (posSlot < kEndPosModelIndex)
           {
@@ -356,7 +395,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
             {
               NORMALIZE
               range >>= 1;
-              
+
               {
                 UInt32 t;
                 code -= range;
@@ -391,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
             }
           }
         }
+
         rep3 = rep2;
         rep2 = rep1;
         rep1 = rep0;
@@ -398,26 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
         if (checkDicSize == 0)
         {
           if (distance >= processedPos)
+          {
+            p->dicPos = dicPos;
             return SZ_ERROR_DATA;
+          }
         }
         else if (distance >= checkDicSize)
+        {
+          p->dicPos = dicPos;
           return SZ_ERROR_DATA;
+        }
         state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
       }
 
       len += kMatchMinLen;
 
-      if (limit == dicPos)
-        return SZ_ERROR_DATA;
       {
-        SizeT rem = limit - dicPos;
-        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
-        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+        SizeT rem;
+        unsigned curLen;
+        SizeT pos;
+
+        if ((rem = limit - dicPos) == 0)
+        {
+          p->dicPos = dicPos;
+          return SZ_ERROR_DATA;
+        }
+
+        curLen = ((rem < len) ? (unsigned)rem : len);
+        pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
 
         processedPos += curLen;
 
         len -= curLen;
-        if (pos + curLen <= dicBufSize)
+        if (curLen <= dicBufSize - pos)
         {
           Byte *dest = dic + dicPos;
           ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
@@ -441,7 +494,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
     }
   }
   while (dicPos < limit && buf < bufLimit);
+
   NORMALIZE;
+
   p->buf = buf;
   p->range = range;
   p->code = code;
@@ -465,9 +520,10 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
     SizeT dicPos = p->dicPos;
     SizeT dicBufSize = p->dicBufSize;
     unsigned len = p->remainLen;
-    UInt32 rep0 = p->reps[0];
-    if (limit - dicPos < len)
-      len = (unsigned)(limit - dicPos);
+    SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
+    SizeT rem = limit - dicPos;
+    if (rem < len)
+      len = (unsigned)(rem);
 
     if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
       p->checkDicSize = p->prop.dicSize;
@@ -477,7 +533,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
     while (len != 0)
     {
       len--;
-      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+      dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
       dicPos++;
     }
     p->dicPos = dicPos;
@@ -495,17 +551,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
       if (limit - p->dicPos > rem)
         limit2 = p->dicPos + rem;
     }
+
     RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
-    if (p->processedPos >= p->prop.dicSize)
+
+    if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
       p->checkDicSize = p->prop.dicSize;
+
     LzmaDec_WriteRem(p, limit);
   }
   while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
 
   if (p->remainLen > kMatchSpecLenStart)
-  {
     p->remainLen = kMatchSpecLenStart;
-  }
+
   return 0;
 }
 
@@ -522,12 +580,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
   UInt32 range = p->range;
   UInt32 code = p->code;
   const Byte *bufLimit = buf + inSize;
-  CLzmaProb *probs = p->probs;
+  const CLzmaProb *probs = p->probs;
   unsigned state = p->state;
   ELzmaDummy res;
 
   {
-    CLzmaProb *prob;
+    const CLzmaProb *prob;
     UInt32 bound;
     unsigned ttt;
     unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
@@ -541,9 +599,9 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
 
       prob = probs + Literal;
       if (p->checkDicSize != 0 || p->processedPos != 0)
-        prob += (LZMA_LIT_SIZE *
-          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
-          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+        prob += ((UInt32)LZMA_LIT_SIZE *
+            ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+            (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
 
       if (state < kNumLitStates)
       {
@@ -553,13 +611,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
       else
       {
         unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
-            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+            (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];
         unsigned offs = 0x100;
         unsigned symbol = 1;
         do
         {
           unsigned bit;
-          CLzmaProb *probLit;
+          const CLzmaProb *probLit;
           matchByte <<= 1;
           bit = (matchByte & offs);
           probLit = prob + offs + bit + symbol;
@@ -629,7 +687,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
       }
       {
         unsigned limit, offset;
-        CLzmaProb *probLen = prob + LenChoice;
+        const CLzmaProb *probLen = prob + LenChoice;
         IF_BIT_0_CHECK(probLen)
         {
           UPDATE_0_CHECK;
@@ -669,7 +727,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
         TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
         if (posSlot >= kStartPosModelIndex)
         {
-          int numDirectBits = ((posSlot >> 1) - 1);
+          unsigned numDirectBits = ((posSlot >> 1) - 1);
 
           /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
 
@@ -708,14 +766,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
 }
 
 
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
-{
-  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
-  p->range = 0xFFFFFFFF;
-  p->needFlush = 0;
-}
-
-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
 {
   p->needFlush = 1;
   p->remainLen = 0;
@@ -739,8 +790,8 @@ void LzmaDec_Init(CLzmaDec *p)
 
 static void LzmaDec_InitStateReal(CLzmaDec *p)
 {
-  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
-  UInt32 i;
+  SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
+  SizeT i;
   CLzmaProb *probs = p->probs;
   for (i = 0; i < numProbs; i++)
     probs[i] = kBitModelTotal >> 1;
@@ -755,14 +806,14 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
   SizeT inSize = *srcLen;
   (*srcLen) = 0;
   LzmaDec_WriteRem(p, dicLimit);
-  
+
   *status = LZMA_STATUS_NOT_SPECIFIED;
 
   while (p->remainLen != kMatchSpecLenStart)
   {
       int checkEndMarkNow;
 
-      if (p->needFlush != 0)
+      if (p->needFlush)
       {
         for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
           p->tempBuf[p->tempBufSize++] = *src++;
@@ -773,8 +824,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
         }
         if (p->tempBuf[0] != 0)
           return SZ_ERROR_DATA;
-
-        LzmaDec_InitRc(p, p->tempBuf);
+        p->code =
+              ((UInt32)p->tempBuf[1] << 24)
+            | ((UInt32)p->tempBuf[2] << 16)
+            | ((UInt32)p->tempBuf[3] << 8)
+            | ((UInt32)p->tempBuf[4]);
+        p->range = 0xFFFFFFFF;
+        p->needFlush = 0;
         p->tempBufSize = 0;
       }
 
@@ -801,7 +857,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
 
       if (p->needInitState)
         LzmaDec_InitStateReal(p);
-  
+
       if (p->tempBufSize == 0)
       {
         SizeT processed;
@@ -858,7 +914,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
         p->buf = p->tempBuf;
         if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
           return SZ_ERROR_DATA;
-        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+
+        {
+          unsigned kkk = (unsigned)(p->buf - p->tempBuf);
+          if (rem < kkk)
+            return SZ_ERROR_FAIL; /* some internal error */
+          rem -= kkk;
+          if (lookAhead < rem)
+            return SZ_ERROR_FAIL; /* some internal error */
+          lookAhead -= rem;
+        }
         (*srcLen) += lookAhead;
         src += lookAhead;
         inSize -= lookAhead;
@@ -910,19 +975,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
   }
 }
 
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->probs);
-  p->probs = 0;
+  ISzAlloc_Free(alloc, p->probs);
+  p->probs = NULL;
 }
 
-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->dic);
-  p->dic = 0;
+  ISzAlloc_Free(alloc, p->dic);
+  p->dic = NULL;
 }
 
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
 {
   LzmaDec_FreeProbs(p, alloc);
   LzmaDec_FreeDict(p, alloc);
@@ -932,12 +997,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
 {
   UInt32 dicSize;
   Byte d;
-  
+
   if (size < LZMA_PROPS_SIZE)
     return SZ_ERROR_UNSUPPORTED;
   else
     dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
- 
+
   if (dicSize < LZMA_DIC_MIN)
     dicSize = LZMA_DIC_MIN;
   p->dicSize = dicSize;
@@ -954,21 +1019,21 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
   return SZ_OK;
 }
 
-static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
 {
   UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
-  if (p->probs == 0 || numProbs != p->numProbs)
+  if (!p->probs || numProbs != p->numProbs)
   {
     LzmaDec_FreeProbs(p, alloc);
-    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+    p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
     p->numProbs = numProbs;
-    if (p->probs == 0)
+    if (!p->probs)
       return SZ_ERROR_MEM;
   }
   return SZ_OK;
 }
 
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
 {
   CLzmaProps propNew;
   RINOK(LzmaProps_Decode(&propNew, props, propsSize));
@@ -977,18 +1042,28 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I
   return SZ_OK;
 }
 
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
 {
   CLzmaProps propNew;
   SizeT dicBufSize;
   RINOK(LzmaProps_Decode(&propNew, props, propsSize));
   RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-  dicBufSize = propNew.dicSize;
-  if (p->dic == 0 || dicBufSize != p->dicBufSize)
+
+  {
+    UInt32 dictSize = propNew.dicSize;
+    SizeT mask = ((UInt32)1 << 12) - 1;
+         if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
+    else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;
+    dicBufSize = ((SizeT)dictSize + mask) & ~mask;
+    if (dicBufSize < dictSize)
+      dicBufSize = dictSize;
+  }
+
+  if (!p->dic || dicBufSize != p->dicBufSize)
   {
     LzmaDec_FreeDict(p, alloc);
-    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
-    if (p->dic == 0)
+    p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
+    if (!p->dic)
     {
       LzmaDec_FreeProbs(p, alloc);
       return SZ_ERROR_MEM;
@@ -1001,7 +1076,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
 
 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-    ELzmaStatus *status, ISzAlloc *alloc)
+    ELzmaStatus *status, ISzAllocPtr alloc)
 {
   CLzmaDec p;
   SRes res;


=====================================
lzmasdk/LzmaDec.h
=====================================
@@ -1,5 +1,5 @@
 /* LzmaDec.h -- LZMA Decoder
-2013-01-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #ifndef __LZMA_DEC_H
 #define __LZMA_DEC_H
@@ -129,11 +129,11 @@ LzmaDec_Allocate* can return:
   SZ_ERROR_UNSUPPORTED - Unsupported properties
 */
    
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
 
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAllocPtr alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAllocPtr alloc);
 
 /* ---------- Dictionary Interface ---------- */
 
@@ -220,7 +220,7 @@ Returns:
 
 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-    ELzmaStatus *status, ISzAlloc *alloc);
+    ELzmaStatus *status, ISzAllocPtr alloc);
 
 EXTERN_C_END
 


=====================================
lzmasdk/Ppmd.h
=====================================
@@ -1,5 +1,5 @@
 /* Ppmd.h -- PPMD codec common code
-2013-01-18 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
 #ifndef __PPMD_H
@@ -77,8 +77,8 @@ typedef
   CPpmd_Byte_Ref;
 
 #define PPMD_SetAllBitsIn256Bytes(p) \
-  { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
-  p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
+  { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
+  p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
 
 EXTERN_C_END
  


=====================================
lzmasdk/Ppmd7.c
=====================================
@@ -1,10 +1,10 @@
 /* Ppmd7.c -- PPMdH codec
-2010-03-12 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
 #include "Precomp.h"
 
-#include <memory.h>
+#include <string.h>
 
 #include "Ppmd7.h"
 
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
 #define UNIT_SIZE 12
 
 #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
-#define U2I(nu) (p->Units2Indx[(nu) - 1])
+#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
 #define I2U(indx) (p->Indx2Units[indx])
 
 #ifdef PPMD_32BIT
@@ -66,7 +66,7 @@ void Ppmd7_Construct(CPpmd7 *p)
   for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
   {
     unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
-    do { p->Units2Indx[k++] = (Byte)i; } while(--step);
+    do { p->Units2Indx[k++] = (Byte)i; } while (--step);
     p->Indx2Units[i] = (Byte)k;
   }
 
@@ -88,29 +88,31 @@ void Ppmd7_Construct(CPpmd7 *p)
   memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
 }
 
-void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
+void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->Base);
+  ISzAlloc_Free(alloc, p->Base);
   p->Size = 0;
   p->Base = 0;
 }
 
-Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
 {
-  if (p->Base == 0 || p->Size != size)
+  if (!p->Base || p->Size != size)
   {
+    size_t size2;
     Ppmd7_Free(p, alloc);
+    size2 = 0
+      #ifndef PPMD_32BIT
+      + UNIT_SIZE
+      #endif
+      ;
     p->AlignOffset =
       #ifdef PPMD_32BIT
         (4 - size) & 3;
       #else
         4 - (size & 3);
       #endif
-    if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
-        #ifndef PPMD_32BIT
-        + UNIT_SIZE
-        #endif
-        )) == 0)
+    if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size + size2)) == 0)
       return False;
     p->Size = size;
   }
@@ -257,7 +259,7 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
 
 #define MyMem12Cpy(dest, src, num) \
   { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
-    do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
+    do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
 
 static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
 {
@@ -513,7 +515,7 @@ static void UpdateModel(CPpmd7 *p)
         /* Expand for one UNIT */
         unsigned oldNU = ns1 >> 1;
         unsigned i = U2I(oldNU);
-        if (i != U2I(oldNU + 1))
+        if (i != U2I((size_t)oldNU + 1))
         {
           void *ptr = AllocUnits(p, i + 1);
           void *oldPtr;
@@ -639,10 +641,10 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
   unsigned nonMasked = p->MinContext->NumStats - numMasked;
   if (p->MinContext->NumStats != 256)
   {
-    see = p->See[p->NS2Indx[nonMasked - 1]] +
+    see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] +
         (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
-        2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
-        4 * (numMasked > nonMasked) +
+        2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
+        4 * (unsigned)(numMasked > nonMasked) +
         p->HiBitsFlag;
     {
       unsigned r = (see->Summ >> see->Shift);


=====================================
lzmasdk/Ppmd7.h
=====================================
@@ -1,5 +1,5 @@
 /* Ppmd7.h -- PPMdH compression codec
-2010-03-12 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
 /* This code supports virtual RangeDecoder and includes the implementation
@@ -60,8 +60,8 @@ typedef struct
 } CPpmd7;
 
 void Ppmd7_Construct(CPpmd7 *p);
-Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
-void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
+void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
 void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
 #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
 
@@ -86,10 +86,10 @@ void Ppmd7_Update2(CPpmd7 *p);
 void Ppmd7_UpdateBin(CPpmd7 *p);
 
 #define Ppmd7_GetBinSumm(p) \
-    &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
-    p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
+    &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
+    p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
     (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
-    2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
+    2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
     ((p->RunLength >> 26) & 0x20)]
 
 CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
@@ -97,16 +97,18 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
 
 /* ---------- Decode ---------- */
 
-typedef struct
+typedef struct IPpmd7_RangeDec IPpmd7_RangeDec;
+
+struct IPpmd7_RangeDec
 {
-  UInt32 (*GetThreshold)(void *p, UInt32 total);
-  void (*Decode)(void *p, UInt32 start, UInt32 size);
-  UInt32 (*DecodeBit)(void *p, UInt32 size0);
-} IPpmd7_RangeDec;
+  UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total);
+  void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size);
+  UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0);
+};
 
 typedef struct
 {
-  IPpmd7_RangeDec p;
+  IPpmd7_RangeDec vt;
   UInt32 Range;
   UInt32 Code;
   IByteIn *Stream;
@@ -116,7 +118,7 @@ void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
 Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
 #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
 
-int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
+int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc);
 
 
 /* ---------- Encode ---------- */


=====================================
lzmasdk/Ppmd7Dec.c
=====================================
@@ -1,5 +1,5 @@
 /* Ppmd7Dec.c -- PPMdH Decoder
-2010-03-12 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
 #include "Precomp.h"
@@ -13,44 +13,46 @@ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
   unsigned i;
   p->Code = 0;
   p->Range = 0xFFFFFFFF;
-  if (p->Stream->Read((void *)p->Stream) != 0)
+  if (IByteIn_Read(p->Stream) != 0)
     return False;
   for (i = 0; i < 4; i++)
-    p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+    p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
   return (p->Code < 0xFFFFFFFF);
 }
 
-static UInt32 Range_GetThreshold(void *pp, UInt32 total)
+#define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt);
+ 
+static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
 {
-  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
-  return (p->Code) / (p->Range /= total);
+  GET_Ppmd7z_RangeDec
+  return p->Code / (p->Range /= total);
 }
 
 static void Range_Normalize(CPpmd7z_RangeDec *p)
 {
   if (p->Range < kTopValue)
   {
-    p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+    p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
     p->Range <<= 8;
     if (p->Range < kTopValue)
     {
-      p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+      p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
       p->Range <<= 8;
     }
   }
 }
 
-static void Range_Decode(void *pp, UInt32 start, UInt32 size)
+static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
 {
-  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+  GET_Ppmd7z_RangeDec
   p->Code -= start * p->Range;
   p->Range *= size;
   Range_Normalize(p);
 }
 
-static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
+static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
 {
-  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+  GET_Ppmd7z_RangeDec
   UInt32 newBound = (p->Range >> 14) * size0;
   UInt32 symbol;
   if (p->Code < newBound)
@@ -70,15 +72,15 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
 
 void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
 {
-  p->p.GetThreshold = Range_GetThreshold;
-  p->p.Decode = Range_Decode;
-  p->p.DecodeBit = Range_DecodeBit;
+  p->vt.GetThreshold = Range_GetThreshold;
+  p->vt.Decode = Range_Decode;
+  p->vt.DecodeBit = Range_DecodeBit;
 }
 
 
 #define MASK(sym) ((signed char *)charMask)[sym]
 
-int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
+int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc)
 {
   size_t charMask[256 / sizeof(size_t)];
   if (p->MinContext->NumStats != 1)


=====================================
lzmasdk/Ppmd8.c
=====================================
@@ -1,10 +1,10 @@
 /* Ppmd8.c -- PPMdI codec
-2010-03-24 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
 
 #include "Precomp.h"
 
-#include <memory.h>
+#include <string.h>
 
 #include "Ppmd8.h"
 
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
 #define UNIT_SIZE 12
 
 #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
-#define U2I(nu) (p->Units2Indx[(nu) - 1])
+#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
 #define I2U(indx) (p->Indx2Units[indx])
 
 #ifdef PPMD_32BIT
@@ -67,7 +67,7 @@ void Ppmd8_Construct(CPpmd8 *p)
   for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
   {
     unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
-    do { p->Units2Indx[k++] = (Byte)i; } while(--step);
+    do { p->Units2Indx[k++] = (Byte)i; } while (--step);
     p->Indx2Units[i] = (Byte)k;
   }
 
@@ -86,16 +86,16 @@ void Ppmd8_Construct(CPpmd8 *p)
   }
 }
 
-void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc)
+void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->Base);
+  ISzAlloc_Free(alloc, p->Base);
   p->Size = 0;
   p->Base = 0;
 }
 
-Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc)
+Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc)
 {
-  if (p->Base == 0 || p->Size != size)
+  if (!p->Base || p->Size != size)
   {
     Ppmd8_Free(p, alloc);
     p->AlignOffset =
@@ -104,7 +104,7 @@ Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc)
       #else
         4 - (size & 3);
       #endif
-    if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size)) == 0)
+    if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size)) == 0)
       return False;
     p->Size = size;
   }
@@ -240,8 +240,8 @@ static void *AllocUnits(CPpmd8 *p, unsigned indx)
 }
 
 #define MyMem12Cpy(dest, src, num) \
-  { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
-    do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
+  { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \
+    do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); }
 
 static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
 {
@@ -386,7 +386,7 @@ static void RestartModel(CPpmd8 *p)
 
   for (i = m = 0; m < 24; m++)
   {
-    while (p->NS2Indx[i + 3] == m + 3)
+    while (p->NS2Indx[(size_t)i + 3] == m + 3)
       i++;
     for (k = 0; k < 32; k++)
     {
@@ -485,10 +485,11 @@ static CPpmd_Void_Ref CutOff(CPpmd8 *p, CTX_PTR ctx, unsigned order)
     }
     if (i == 0)
     {
-      ctx->Flags = (ctx->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40);
+      ctx->Flags = (Byte)((ctx->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40));
       *ONE_STATE(ctx) = *s;
       FreeUnits(p, s, tmp);
-      ONE_STATE(ctx)->Freq = (Byte)((unsigned)ONE_STATE(ctx)->Freq + 11) >> 3;
+      /* 9.31: the code was fixed. It's was not BUG, if Freq <= MAX_FREQ = 124 */
+      ONE_STATE(ctx)->Freq = (Byte)(((unsigned)ONE_STATE(ctx)->Freq + 11) >> 3);
     }
     else
       Refresh(p, ctx, tmp, ctx->SummFreq > 16 * i);
@@ -556,17 +557,17 @@ static void RestoreModel(CPpmd8 *p, CTX_PTR c1
     if (--(c->NumStats) == 0)
     {
       s = STATS(c);
-      c->Flags = (c->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40);
+      c->Flags = (Byte)((c->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40));
       *ONE_STATE(c) = *s;
       SpecialFreeUnit(p, s);
-      ONE_STATE(c)->Freq = (ONE_STATE(c)->Freq + 11) >> 3;
+      ONE_STATE(c)->Freq = (Byte)(((unsigned)ONE_STATE(c)->Freq + 11) >> 3);
     }
     else
       Refresh(p, c, (c->NumStats+3) >> 1, 0);
  
   for (; c != p->MinContext; c = SUFFIX(c))
     if (!c->NumStats)
-      ONE_STATE(c)->Freq -= ONE_STATE(c)->Freq >> 1;
+      ONE_STATE(c)->Freq = (Byte)(ONE_STATE(c)->Freq - (ONE_STATE(c)->Freq >> 1));
     else if ((c->SummFreq += 4) > 128 + 4 * c->NumStats)
       Refresh(p, c, (c->NumStats + 2) >> 1, 1);
 
@@ -638,7 +639,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
     else
     {
       s = ONE_STATE(c);
-      s->Freq += (!SUFFIX(c)->NumStats & (s->Freq < 24));
+      s->Freq = (Byte)(s->Freq + (!SUFFIX(c)->NumStats & (s->Freq < 24)));
     }
     successor = SUCCESSOR(s);
     if (successor != upBranch)
@@ -653,7 +654,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
   
   upState.Symbol = *(const Byte *)Ppmd8_GetPtr(p, upBranch);
   SetSuccessor(&upState, upBranch + 1);
-  flags = 0x10 * (p->FoundState->Symbol >= 0x40) + 0x08 * (upState.Symbol >= 0x40);
+  flags = (Byte)(0x10 * (p->FoundState->Symbol >= 0x40) + 0x08 * (upState.Symbol >= 0x40));
 
   if (c->NumStats == 0)
     upState.Freq = ONE_STATE(c)->Freq;
@@ -745,7 +746,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
       else
       {
         s = ONE_STATE(c);
-        s->Freq += (s->Freq < 32);
+        s->Freq = (Byte)(s->Freq + (s->Freq < 32));
       }
     }
     if (SUCCESSOR(s))
@@ -771,7 +772,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
   if (SUCCESSOR(s) <= upBranch)
   {
     CTX_PTR successor;
-    CPpmd_State *s1 = p->FoundState;
+    CPpmd_State *s2 = p->FoundState;
     p->FoundState = s;
 
     successor = CreateSuccessors(p, False, NULL, c);
@@ -779,7 +780,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
       SetSuccessor(s, 0);
     else
       SetSuccessor(s, REF(successor));
-    p->FoundState = s1;
+    p->FoundState = s2;
   }
   
   if (p->OrderFall == 1 && c1 == p->MaxContext)
@@ -891,7 +892,7 @@ static void UpdateModel(CPpmd8 *p)
   #endif
   
   s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - fFreq;
-  flag = 0x08 * (fSymbol >= 0x40);
+  flag = (Byte)(0x08 * (fSymbol >= 0x40));
   
   for (; c != p->MinContext; c = SUFFIX(c))
   {
@@ -904,7 +905,7 @@ static void UpdateModel(CPpmd8 *p)
         /* Expand for one UNIT */
         unsigned oldNU = (ns1 + 1) >> 1;
         unsigned i = U2I(oldNU);
-        if (i != U2I(oldNU + 1))
+        if (i != U2I((size_t)oldNU + 1))
         {
           void *ptr = AllocUnits(p, i + 1);
           void *oldPtr;
@@ -923,19 +924,19 @@ static void UpdateModel(CPpmd8 *p)
     }
     else
     {
-      CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
-      if (!s)
+      CPpmd_State *s2 = (CPpmd_State*)AllocUnits(p, 0);
+      if (!s2)
       {
         RESTORE_MODEL(c, CTX(fSuccessor));
         return;
       }
-      *s = *ONE_STATE(c);
-      c->Stats = REF(s);
-      if (s->Freq < MAX_FREQ / 4 - 1)
-        s->Freq <<= 1;
+      *s2 = *ONE_STATE(c);
+      c->Stats = REF(s2);
+      if (s2->Freq < MAX_FREQ / 4 - 1)
+        s2->Freq <<= 1;
       else
-        s->Freq = MAX_FREQ - 4;
-      c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 2));
+        s2->Freq = MAX_FREQ - 4;
+      c->SummFreq = (UInt16)(s2->Freq + p->InitEsc + (ns > 2));
     }
     cf = 2 * fFreq * (c->SummFreq + 6);
     sf = (UInt32)s0 + c->SummFreq;
@@ -950,10 +951,10 @@ static void UpdateModel(CPpmd8 *p)
       c->SummFreq = (UInt16)(c->SummFreq + cf);
     }
     {
-      CPpmd_State *s = STATS(c) + ns1 + 1;
-      SetSuccessor(s, successor);
-      s->Symbol = fSymbol;
-      s->Freq = (Byte)cf;
+      CPpmd_State *s2 = STATS(c) + ns1 + 1;
+      SetSuccessor(s2, successor);
+      s2->Symbol = fSymbol;
+      s2->Freq = (Byte)cf;
       c->Flags |= flag;
       c->NumStats = (Byte)(ns1 + 1);
     }
@@ -1014,7 +1015,7 @@ static void Rescale(CPpmd8 *p)
       if (tmp.Freq > MAX_FREQ / 3)
         tmp.Freq = MAX_FREQ / 3;
       InsertNode(p, stats, U2I((numStats + 2) >> 1));
-      p->MinContext->Flags = (p->MinContext->Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40);
+      p->MinContext->Flags = (Byte)((p->MinContext->Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40));
       *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
       return;
     }
@@ -1037,9 +1038,9 @@ CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
   CPpmd_See *see;
   if (p->MinContext->NumStats != 0xFF)
   {
-    see = p->See[p->NS2Indx[p->MinContext->NumStats + 2] - 3] +
+    see = p->See[(size_t)(unsigned)p->NS2Indx[(size_t)(unsigned)p->MinContext->NumStats + 2] - 3] +
         (p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
-        2 * (2 * (unsigned)p->MinContext->NumStats <
+        2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats <
         ((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
         p->MinContext->Flags;
     {


=====================================
lzmasdk/Ppmd8.h
=====================================
@@ -1,5 +1,5 @@
 /* Ppmd8.h -- PPMdI codec
-2011-01-27 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on:
   PPMd var.I (2002): Dmitry Shkarin : Public domain
   Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -86,8 +86,8 @@ typedef struct
 } CPpmd8;
 
 void Ppmd8_Construct(CPpmd8 *p);
-Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc);
-void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc);
+Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc);
+void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc);
 void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
 #define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
 
@@ -112,7 +112,7 @@ void Ppmd8_Update2(CPpmd8 *p);
 void Ppmd8_UpdateBin(CPpmd8 *p);
 
 #define Ppmd8_GetBinSumm(p) \
-    &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
+    &p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
     p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
     p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
 


=====================================
lzmasdk/Ppmd8Dec.c
=====================================
@@ -1,5 +1,5 @@
 /* Ppmd8Dec.c -- PPMdI Decoder
-2010-04-16 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on:
   PPMd var.I (2002): Dmitry Shkarin : Public domain
   Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -18,7 +18,7 @@ Bool Ppmd8_RangeDec_Init(CPpmd8 *p)
   p->Range = 0xFFFFFFFF;
   p->Code = 0;
   for (i = 0; i < 4; i++)
-    p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
+    p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
   return (p->Code < 0xFFFFFFFF);
 }
 
@@ -37,7 +37,7 @@ static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
   while ((p->Low ^ (p->Low + p->Range)) < kTop ||
       (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
   {
-    p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
+    p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
     p->Range <<= 8;
     p->Low <<= 8;
   }


=====================================
lzmasdk/Precomp.h
=====================================
@@ -5,11 +5,6 @@
 #define __7Z_PRECOMP_H
 
 /* #include "Compiler.h" */
-#ifdef _MSC_VER
-#pragma warning(disable : 4456) // declaration of * hides previous local declaration
-#pragma warning(disable : 4457) // declaration of * hides function parameter
-#pragma warning(disable : 4996) // This function or variable may be unsafe
-#endif
 /* #include "7zTypes.h" */
 
 #endif


=====================================
pkg-config.pc.cmake
=====================================
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
+
+Name: @PROJECT_NAME@
+Description: @PROJECT_DESCRIPTION@
+Version: @PROJECT_VERSION@
+Cflags: -I${includedir}
+Requires.private: @PROJECT_REQUIRES_PRIVATE@
+Libs: -L${libdir} -l at PROJECT_NAME@
+Libs.private: @PROJECT_LIBS_PRIVATE@


=====================================
rar/parse-rar.c
=====================================
@@ -116,8 +116,8 @@ static char *rar_conv_unicode_to_utf8(const char *data, uint16_t len)
 #define Check(cond) if (!(cond)) { free(str); return NULL; } else ((void)0)
 
     uint8_t highbyte, flagbyte, flagbits, size, length, i;
-    const uint8_t *in = (uint8_t *)data + strlen(data) + 1;
-    const uint8_t *end_in = (uint8_t *)data + len;
+    const uint8_t *in = (const uint8_t *)data + strlen(data) + 1;
+    const uint8_t *end_in = (const uint8_t *)data + len;
     char *str = calloc(len + 1, 3);
     char *out = str;
     char *end_out = str + len * 3;


=====================================
rar/rarvm.c
=====================================
@@ -28,7 +28,7 @@ struct RARProgram_s {
 
 /* Program building */
 
-RARProgram *RARCreateProgram()
+RARProgram *RARCreateProgram(void)
 {
     return calloc(1, sizeof(RARProgram));
 }
@@ -416,7 +416,7 @@ void RARVirtualMachineWrite8(RARVirtualMachine *vm, uint32_t address, uint8_t va
 
 static uint32_t _RARGetOperand(RARVirtualMachine *vm, uint8_t addressingmode, uint32_t value, bool bytemode)
 {
-    if (RARRegisterAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterAddressingMode(7)) {
+    if (/*RARRegisterAddressingMode(0) <= addressingmode && */addressingmode <= RARRegisterAddressingMode(7)) {
         uint32_t result = vm->registers[addressingmode % 8];
         if (bytemode)
             result = result & 0xFF;
@@ -443,7 +443,7 @@ static uint32_t _RARGetOperand(RARVirtualMachine *vm, uint8_t addressingmode, ui
 
 static void _RARSetOperand(RARVirtualMachine *vm, uint8_t addressingmode, uint32_t value, bool bytemode, uint32_t data)
 {
-    if (RARRegisterAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterAddressingMode(7)) {
+    if (/*RARRegisterAddressingMode(0) <= addressingmode &&*/ addressingmode <= RARRegisterAddressingMode(7)) {
         if (bytemode)
             data = data & 0xFF;
         vm->registers[addressingmode % 8] = data;
@@ -574,7 +574,7 @@ bool RARInstructionWritesSecondOperand(uint8_t instruction)
 
 static void RARPrintOperand(uint8_t addressingmode, uint32_t value)
 {
-    if (RARRegisterAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterAddressingMode(7))
+    if (/*RARRegisterAddressingMode(0) <= addressingmode && */addressingmode <= RARRegisterAddressingMode(7))
         printf("r%d", addressingmode % 8);
     else if (RARRegisterIndirectAddressingMode(0) <= addressingmode && addressingmode <= RARRegisterIndirectAddressingMode(7))
         printf("@(r%d)", addressingmode % 8);


=====================================
rar/rarvm.h
=====================================
@@ -81,7 +81,7 @@ enum {
     RARNumberOfInstructions = 40,
 };
 
-RARProgram *RARCreateProgram();
+RARProgram *RARCreateProgram(void);
 void RARDeleteProgram(RARProgram *prog);
 bool RARProgramAddInstr(RARProgram *prog, uint8_t instruction, bool bytemode);
 bool RARSetLastInstrOperands(RARProgram *prog, uint8_t addressingmode1, uint32_t value1, uint8_t addressingmode2, uint32_t value2);


=====================================
rar/uncompress-rar.c
=====================================
@@ -6,8 +6,8 @@
 
 #include "rar.h"
 
-static void *gSzAlloc_Alloc(void *self, size_t size) { (void)self; return malloc(size); }
-static void gSzAlloc_Free(void *self, void *ptr) { (void)self; free(ptr); }
+static void *gSzAlloc_Alloc(ISzAllocPtr self, size_t size) { (void)self; return malloc(size); }
+static void gSzAlloc_Free(ISzAllocPtr self, void *ptr) { (void)self; free(ptr); }
 static ISzAlloc gSzAlloc = { gSzAlloc_Alloc, gSzAlloc_Free };
 
 static bool br_fill(ar_archive_rar *rar, int bits)
@@ -44,9 +44,9 @@ static inline uint64_t br_bits(ar_archive_rar *rar, int bits)
     return (rar->uncomp.br.bits >> (rar->uncomp.br.available -= bits)) & (((uint64_t)1 << bits) - 1);
 }
 
-static Byte ByteIn_Read(void *p)
+static Byte ByteIn_Read(const IByteIn *p)
 {
-    struct ByteReader *self = p;
+    struct ByteReader *self = (struct ByteReader *) p;
     return br_check(self->rar, 8) ? (Byte)br_bits(self->rar, 8) : 0xFF;
 }
 
@@ -68,15 +68,15 @@ static void PpmdRAR_RangeDec_Init(struct CPpmdRAR_RangeDec *p)
     }
 }
 
-static UInt32 Range_GetThreshold(void *p, UInt32 total)
+static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *p, UInt32 total)
 {
-    struct CPpmdRAR_RangeDec *self = p;
+    struct CPpmdRAR_RangeDec *self = (struct CPpmdRAR_RangeDec *) p;
     return self->Code / (self->Range /= total);
 }
 
-static void Range_Decode_RAR(void *p, UInt32 start, UInt32 size)
+static void Range_Decode_RAR(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size)
 {
-    struct CPpmdRAR_RangeDec *self = p;
+    struct CPpmdRAR_RangeDec *self = (struct CPpmdRAR_RangeDec *) p;
     self->Low += start * self->Range;
     self->Code -= start * self->Range;
     self->Range *= size;
@@ -92,7 +92,7 @@ static void Range_Decode_RAR(void *p, UInt32 start, UInt32 size)
     }
 }
 
-static UInt32 Range_DecodeBit_RAR(void *p, UInt32 size0)
+static UInt32 Range_DecodeBit_RAR(const IPpmd7_RangeDec *p, UInt32 size0)
 {
     UInt32 value = Range_GetThreshold(p, PPMD_BIN_SCALE);
     UInt32 bit = value < size0 ? 0 : 1;
@@ -358,7 +358,7 @@ static uint8_t rar_decode_audio(struct AudioState *state, int8_t *channeldelta,
     return byte;
 }
 
-int64_t rar_expand_v2(ar_archive_rar *rar, int64_t end)
+static int64_t rar_expand_v2(ar_archive_rar *rar, int64_t end)
 {
     static const uint8_t lengthbases[] =
         {   0,   1,   2,   3,   4,   5,   6,
@@ -586,7 +586,7 @@ static bool rar_parse_codes(ar_archive_rar *rar)
         if (!br_bits(rar, 1))
             memset(uncomp_v3->lengthtable, 0, sizeof(uncomp_v3->lengthtable));
         memset(&bitlengths, 0, sizeof(bitlengths));
-        for (i = 0; i < sizeof(bitlengths); i++) {
+        for (i = 0; i < (int)sizeof(bitlengths); i++) {
             if (!br_check(rar, 4))
                 return false;
             bitlengths[i] = (uint8_t)br_bits(rar, 4);
@@ -595,7 +595,7 @@ static bool rar_parse_codes(ar_archive_rar *rar)
                     return false;
                 zerocount = (uint8_t)br_bits(rar, 4);
                 if (zerocount) {
-                    for (j = 0; j < zerocount + 2 && i < sizeof(bitlengths); j++) {
+                    for (j = 0; j < zerocount + 2 && i < (int)sizeof(bitlengths); j++) {
                         bitlengths[i++] = 0;
                     }
                     i--;


=====================================
Makefile → test/Makefile
=====================================
@@ -45,7 +45,7 @@ LINK_CMD = $(QUIET_LINK) $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
 
 UNARR_OUT := $(OUT)/unarr
 
-UNARR_DIRS := common lzmasdk rar tar zip _7z
+UNARR_DIRS := .. ../common ../lzmasdk ../rar ../tar ../zip ../_7z
 UNARR_SRC := $(wildcard $(UNARR_DIRS:=/*.c))
 UNARR_OBJ := $(addprefix $(UNARR_OUT)/, $(addsuffix .o, $(basename $(UNARR_SRC))))
 


=====================================
main.c → test/main.c
=====================================


=====================================
unarr.h
=====================================
@@ -4,9 +4,41 @@
 #ifndef unarr_h
 #define unarr_h
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stddef.h>
 #include <stdint.h>
 #include <stdbool.h>
+
+
+/* macros for shared library usage */
+
+#if defined (UNARR_IS_SHARED_LIBRARY)
+#if defined (_WIN32)
+
+#if defined (UNARR_EXPORT_SYMBOLS)
+#define UNARR_EXPORT __declspec(dllexport)
+#else
+#define UNARR_EXPORT __declspec(dllimport)
+#endif // UNARR_EXPORT_SYMBOLS
+
+#else // _WIN32
+
+#if defined (UNARR_EXPORT_SYMBOLS)
+#define UNARR_EXPORT __attribute__((visibility("default")))
+#else
+#define UNARR_EXPORT
+#endif // UNARR_EXPORT_SYMBOLS
+#endif // _WIN32
+
+#else // defined UNARR_IS_SHARED_LIBRARY
+#define UNARR_EXPORT
+
+#endif // UNARR_IS_SHARED_LIBRARY
+
+
 typedef int64_t off64_t;
 typedef int64_t time64_t;
 
@@ -17,78 +49,82 @@ typedef int64_t time64_t;
 typedef struct ar_stream_s ar_stream;
 
 /* opens a read-only stream for the given file path; returns NULL on error */
-ar_stream *ar_open_file(const char *path);
+UNARR_EXPORT ar_stream *ar_open_file(const char *path);
 #ifdef _WIN32
-ar_stream *ar_open_file_w(const wchar_t *path);
+UNARR_EXPORT ar_stream *ar_open_file_w(const wchar_t *path);
 #endif
 /* opens a read-only stream for the given chunk of memory; the pointer must be valid until ar_close is called */
-ar_stream *ar_open_memory(const void *data, size_t datalen);
+UNARR_EXPORT ar_stream *ar_open_memory(const void *data, size_t datalen);
 #ifdef _WIN32
 typedef struct IStream IStream;
 /* opens a read-only stream based on the given IStream */
-ar_stream *ar_open_istream(IStream *stream);
+UNARR_EXPORT ar_stream *ar_open_istream(IStream *stream);
 #endif
 
 /* closes the stream and releases underlying resources */
-void ar_close(ar_stream *stream);
+UNARR_EXPORT void ar_close(ar_stream *stream);
 /* tries to read 'count' bytes into buffer, advancing the read offset pointer; returns the actual number of bytes read */
-size_t ar_read(ar_stream *stream, void *buffer, size_t count);
+UNARR_EXPORT size_t ar_read(ar_stream *stream, void *buffer, size_t count);
 /* moves the read offset pointer (same as fseek); returns false on failure */
-bool ar_seek(ar_stream *stream, off64_t offset, int origin);
+UNARR_EXPORT bool ar_seek(ar_stream *stream, off64_t offset, int origin);
 /* shortcut for ar_seek(stream, count, SEEK_CUR); returns false on failure */
-bool ar_skip(ar_stream *stream, off64_t count);
+UNARR_EXPORT bool ar_skip(ar_stream *stream, off64_t count);
 /* returns the current read offset (or 0 on error) */
-off64_t ar_tell(ar_stream *stream);
+UNARR_EXPORT off64_t ar_tell(ar_stream *stream);
 
 /***** common/unarr *****/
 
 typedef struct ar_archive_s ar_archive;
 
 /* frees all data stored for the given archive; does not close the underlying stream */
-void ar_close_archive(ar_archive *ar);
+UNARR_EXPORT void ar_close_archive(ar_archive *ar);
 /* reads the next archive entry; returns false on error or at the end of the file (use ar_at_eof to distinguish the two cases) */
-bool ar_parse_entry(ar_archive *ar);
+UNARR_EXPORT bool ar_parse_entry(ar_archive *ar);
 /* reads the archive entry at the given offset as returned by ar_entry_get_offset (offset 0 always restarts at the first entry); should always succeed */
-bool ar_parse_entry_at(ar_archive *ar, off64_t offset);
+UNARR_EXPORT bool ar_parse_entry_at(ar_archive *ar, off64_t offset);
 /* reads the (first) archive entry associated with the given name; returns false if the entry couldn't be found */
-bool ar_parse_entry_for(ar_archive *ar, const char *entry_name);
+UNARR_EXPORT bool ar_parse_entry_for(ar_archive *ar, const char *entry_name);
 /* returns whether the last ar_parse_entry call has reached the file's expected end */
-bool ar_at_eof(ar_archive *ar);
+UNARR_EXPORT bool ar_at_eof(ar_archive *ar);
 
 /* returns the name of the current entry as UTF-8 string; this pointer is only valid until the next call to ar_parse_entry; returns NULL on failure */
-const char *ar_entry_get_name(ar_archive *ar);
+UNARR_EXPORT const char *ar_entry_get_name(ar_archive *ar);
 /* returns the stream offset of the current entry for use with ar_parse_entry_at */
-off64_t ar_entry_get_offset(ar_archive *ar);
+UNARR_EXPORT off64_t ar_entry_get_offset(ar_archive *ar);
 /* returns the total size of uncompressed data of the current entry; read exactly that many bytes using ar_entry_uncompress */
-size_t ar_entry_get_size(ar_archive *ar);
+UNARR_EXPORT size_t ar_entry_get_size(ar_archive *ar);
 /* returns the stored modification date of the current entry in 100ns since 1601/01/01 */
-time64_t ar_entry_get_filetime(ar_archive *ar);
+UNARR_EXPORT time64_t ar_entry_get_filetime(ar_archive *ar);
 /* WARNING: don't manually seek in the stream between ar_parse_entry and the last corresponding ar_entry_uncompress call! */
 /* uncompresses the next 'count' bytes of the current entry into buffer; returns false on error */
-bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count);
+UNARR_EXPORT bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count);
 
 /* copies at most 'count' bytes of the archive's global comment (if any) into buffer; returns the actual amout of bytes copied (or, if 'buffer' is NULL, the required buffer size) */
-size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
+UNARR_EXPORT size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count);
 
 /***** rar/rar *****/
 
 /* checks whether 'stream' could contain RAR data and prepares for archive listing/extraction; returns NULL on failure */
-ar_archive *ar_open_rar_archive(ar_stream *stream);
+UNARR_EXPORT ar_archive *ar_open_rar_archive(ar_stream *stream);
 
 /***** tar/tar *****/
 
 /* checks whether 'stream' could contain TAR data and prepares for archive listing/extraction; returns NULL on failure */
-ar_archive *ar_open_tar_archive(ar_stream *stream);
+UNARR_EXPORT ar_archive *ar_open_tar_archive(ar_stream *stream);
 
 /***** zip/zip *****/
 
 /* checks whether 'stream' could contain ZIP data and prepares for archive listing/extraction; returns NULL on failure */
 /* set deflatedonly for extracting XPS, EPUB, etc. documents where non-Deflate compression methods are not supported by specification */
-ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly);
+UNARR_EXPORT ar_archive *ar_open_zip_archive(ar_stream *stream, bool deflatedonly);
 
 /***** _7z/_7z *****/
 
 /* checks whether 'stream' could contain 7Z data and prepares for archive listing/extraction; returns NULL on failure */
-ar_archive *ar_open_7z_archive(ar_stream *stream);
+UNARR_EXPORT ar_archive *ar_open_7z_archive(ar_stream *stream);
 
+#ifdef __cplusplus
+}
 #endif
+
+#endif //unarr_h


=====================================
zip/parse-zip.c
=====================================
@@ -250,7 +250,7 @@ off64_t zip_find_end_of_central_directory(ar_stream *stream)
     filesize = ar_tell(stream);
 
     while (fromend < UINT16_MAX + ZIP_END_OF_CENTRAL_DIR_SIZE && fromend < filesize) {
-        count = (int)(filesize - fromend < sizeof(data) ? filesize - fromend : sizeof(data));
+        count = (filesize - fromend < (int)sizeof(data) ? (int)(filesize - fromend) : (int)sizeof(data));
         fromend += count;
         if (count < ZIP_END_OF_CENTRAL_DIR_SIZE)
             return -1;


=====================================
zip/uncompress-zip.c
=====================================
@@ -166,8 +166,119 @@ static void zip_clear_uncompress_bzip2(struct ar_archive_zip_uncomp *uncomp)
 
 /***** LZMA compression *****/
 
-static void *gLzma_Alloc(void *self, size_t size) { (void)self; return malloc(size); }
-static void gLzma_Free(void *self, void *ptr) { (void)self; free(ptr); }
+#ifdef HAVE_LIBLZMA
+
+static void *gLzma_Alloc(void *opaque, size_t nmemb, size_t size)
+    { (void)opaque; (void) nmemb; return malloc(size); }
+static void gLzma_Free(void *opaque, void *ptr)
+    { (void)opaque; free(ptr); }
+
+static bool zip_init_uncompress_lzma(struct ar_archive_zip_uncomp *uncomp)
+{
+    lzma_stream strm = LZMA_STREAM_INIT;
+    uncomp->state.lzmastream = strm;
+    static const lzma_allocator allocator = { gLzma_Alloc, gLzma_Free, NULL };
+    uncomp->state.lzmastream.allocator = &allocator;
+    return true;
+}
+
+static uint32_t zip_uncompress_data_lzma1(struct ar_archive_zip_uncomp *uncomp, void *buffer, uint32_t buffer_size, bool is_last_chunk)
+{
+    int err;
+
+    if (uncomp->state.lzmastream.internal == NULL) {
+        uint8_t propsize;
+        propsize = uncomp->input.data[uncomp->input.offset + 2];
+
+        lzma_filter filters[2] = {{.id=LZMA_FILTER_LZMA1, .options=NULL},
+                                  {.id=LZMA_VLI_UNKNOWN, .options=NULL}};
+
+        err = lzma_properties_decode(
+        		       &filters[0], NULL,
+        		       &uncomp->input.data[uncomp->input.offset + 4], propsize);
+
+        if (err != LZMA_OK) {
+            warn("Properties error %d", err);
+            return ERR_UNCOMP;
+        }
+
+        err = lzma_raw_decoder(&uncomp->state.lzmastream, filters);
+        free(filters[0].options);
+        if (err != LZMA_OK) {
+            warn("Decoder init error %d", err);
+            return ERR_UNCOMP;
+        }
+        uncomp->input.offset += 4 + propsize;
+        uncomp->input.bytes_left -= 4 + propsize;
+    }
+
+    uncomp->state.lzmastream.next_in = &uncomp->input.data[uncomp->input.offset];
+    uncomp->state.lzmastream.avail_in = uncomp->input.bytes_left;
+    uncomp->state.lzmastream.next_out = buffer;
+    uncomp->state.lzmastream.avail_out = buffer_size;
+
+    err = lzma_code(&uncomp->state.lzmastream, LZMA_RUN);
+
+    uncomp->input.offset += (uint16_t)uncomp->input.bytes_left - (uint16_t)uncomp->state.lzmastream.avail_in;
+    uncomp->input.bytes_left = (uint16_t)uncomp->state.lzmastream.avail_in;
+
+    if (err != LZMA_OK && err != LZMA_STREAM_END) {
+        warn("Unexpected LZMA error %d", err);
+        warn("%d", buffer_size - uncomp->state.lzmastream.avail_out);
+        return ERR_UNCOMP;
+    }
+    if (err == LZMA_STREAM_END && (!is_last_chunk || uncomp->state.lzmastream.avail_out)) {
+        warn("Premature EOS in LZMA stream");
+        return ERR_UNCOMP;
+    }
+    return buffer_size - uncomp->state.lzmastream.avail_out;
+}
+
+static uint32_t zip_uncompress_data_xz(struct ar_archive_zip_uncomp *uncomp, void *buffer, uint32_t buffer_size, bool is_last_chunk)
+{
+    int err;
+
+    if (uncomp->state.lzmastream.internal == NULL) {
+        /* restrict decoder memory usage to 100 MB */
+        err = lzma_stream_decoder(&uncomp->state.lzmastream, 100 << 20, 0);
+        if (err != LZMA_OK) {
+            warn("Unexpected LZMA Decoder init error %d", err);
+            return ERR_UNCOMP;
+        }
+    }
+
+    uncomp->state.lzmastream.next_in = &uncomp->input.data[uncomp->input.offset];
+    uncomp->state.lzmastream.avail_in = uncomp->input.bytes_left;
+    uncomp->state.lzmastream.next_out = buffer;
+    uncomp->state.lzmastream.avail_out = buffer_size;
+
+    err = lzma_code(&uncomp->state.lzmastream, LZMA_RUN);
+
+    uncomp->input.offset += (uint16_t)uncomp->input.bytes_left - (uint16_t)uncomp->state.lzmastream.avail_in;
+    uncomp->input.bytes_left = (uint16_t)uncomp->state.lzmastream.avail_in;
+
+    if (err != LZMA_OK && err != LZMA_STREAM_END) {
+        warn("Unexpected XZ error %d", err);
+        warn("%d", buffer_size - uncomp->state.lzmastream.avail_out);
+        return ERR_UNCOMP;
+    }
+    if (err == LZMA_STREAM_END && (!is_last_chunk || uncomp->state.lzmastream.avail_out)) {
+        warn("Premature EOS in XZ stream");
+        return ERR_UNCOMP;
+    }
+    return buffer_size - uncomp->state.lzmastream.avail_out;
+}
+
+
+static void zip_clear_uncompress_lzma(struct ar_archive_zip_uncomp *uncomp)
+{
+    lzma_end(&uncomp->state.lzmastream);
+}
+
+#else //HAVE_LIBLZMA
+
+static void *gLzma_Alloc(ISzAllocPtr self, size_t size) { (void)self; return malloc(size); }
+static void gLzma_Free(ISzAllocPtr self, void *ptr) { (void)self; free(ptr); }
 
 static bool zip_init_uncompress_lzma(struct ar_archive_zip_uncomp *uncomp, uint16_t flags)
 {
@@ -229,14 +340,16 @@ static void zip_clear_uncompress_lzma(struct ar_archive_zip_uncomp *uncomp)
     LzmaDec_Free(&uncomp->state.lzma.dec, &uncomp->state.lzma.alloc);
 }
 
+#endif //HAVE_LIBLZMA
+
 /***** PPMd compression *****/
 
-static void *gPpmd_Alloc(void *self, size_t size) { (void)self; return malloc(size); }
-static void gPpmd_Free(void *self, void *ptr) { (void)self; free(ptr); }
+static void *gPpmd_Alloc(ISzAllocPtr self, size_t size) { (void)self; return malloc(size); }
+static void gPpmd_Free(ISzAllocPtr self, void *ptr) { (void)self; free(ptr); }
 
-static Byte gPpmd_ByteIn_Read(void *p)
+static Byte gPpmd_ByteIn_Read(const IByteIn *p)
 {
-    struct ByteReader *self = p;
+    struct ByteReader *self = (struct ByteReader *) p;
     if (!self->input->bytes_left && (!self->zip->progress.data_left || !zip_fill_input_buffer(self->zip)))
         return 0xFF;
     self->input->bytes_left--;
@@ -350,12 +463,27 @@ static bool zip_init_uncompress(ar_archive_zip *zip)
         warn("BZIP2 support requires BZIP2 (define HAVE_BZIP2)");
 #endif
     }
+#ifdef HAVE_LIBLZMA
+    else if (zip->entry.method == METHOD_LZMA) {
+        if (zip_init_uncompress_lzma(uncomp)) {
+            uncomp->uncompress_data = zip_uncompress_data_lzma1;
+            uncomp->clear_state = zip_clear_uncompress_lzma;
+        }
+    }
+    else if (zip->entry.method == METHOD_XZ) {
+        if (zip_init_uncompress_lzma(uncomp)) {
+            uncomp->uncompress_data = zip_uncompress_data_xz;
+            uncomp->clear_state = zip_clear_uncompress_lzma;
+        }
+    }
+#else
     else if (zip->entry.method == METHOD_LZMA) {
         if (zip_init_uncompress_lzma(uncomp, zip->entry.flags)) {
             uncomp->uncompress_data = zip_uncompress_data_lzma;
             uncomp->clear_state = zip_clear_uncompress_lzma;
         }
     }
+#endif // HAVE_LIBLZMA
     else if (zip->entry.method == METHOD_PPMD) {
         if (zip_init_uncompress_ppmd(zip)) {
             uncomp->uncompress_data = zip_uncompress_data_ppmd;


=====================================
zip/zip.c
=====================================
@@ -165,7 +165,7 @@ static bool zip_uncompress(ar_archive *ar, void *buffer, size_t count)
     return true;
 }
 
-size_t zip_get_global_comment(ar_archive *ar, void *buffer, size_t count)
+static size_t zip_get_global_comment(ar_archive *ar, void *buffer, size_t count)
 {
     ar_archive_zip *zip = (ar_archive_zip *)ar;
     if (!zip->comment_size)


=====================================
zip/zip.h
=====================================
@@ -13,7 +13,11 @@
 #ifdef HAVE_BZIP2
 #include <bzlib.h>
 #endif
+#ifdef HAVE_LIBLZMA
+#include <lzma.h>
+#else
 #include "../lzmasdk/LzmaDec.h"
+#endif
 #include "../lzmasdk/Ppmd8.h"
 
 typedef struct ar_archive_zip_s ar_archive_zip;
@@ -31,7 +35,7 @@ enum zip_signatures {
 enum compression_method {
     METHOD_STORE = 0, METHOD_DEFLATE = 8,
     METHOD_DEFLATE64 = 9, METHOD_BZIP2 = 12, METHOD_LZMA = 14,
-    METHOD_PPMD = 98,
+    METHOD_XZ = 95, METHOD_PPMD = 98,
 };
 
 #define ZIP_LOCAL_ENTRY_FIXED_SIZE 30
@@ -120,11 +124,15 @@ struct ar_archive_zip_uncomp {
 #ifdef HAVE_BZIP2
         bz_stream bstream;
 #endif
+#ifdef HAVE_LIBLZMA
+        lzma_stream lzmastream;
+#else
         struct {
             CLzmaDec dec;
             ELzmaFinishMode finish;
             ISzAlloc alloc;
         } lzma;
+#endif //HAVE_LIBLZMA
         struct {
             CPpmd8 ctx;
             struct ByteReader bytein;



View it on GitLab: https://salsa.debian.org/debian-gis-team/unarr/commit/37a6279853635578bb5ceaa7ce719d3461c04ac1

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/unarr/commit/37a6279853635578bb5ceaa7ce719d3461c04ac1
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20181002/ec04ac7d/attachment-0001.html>


More information about the Pkg-grass-devel mailing list