diff options
-rw-r--r-- | .github/workflows/build.yml | 181 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | meson.build | 2 | ||||
-rw-r--r-- | src/fr-command-rar.c | 76 | ||||
-rw-r--r-- | src/fr-command-rar.h | 8 |
6 files changed, 246 insertions, 30 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..c4f5436 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,181 @@ +name: CI Build + +on: + push: + branches: + - master + pull_request: + branches: + - master + workflow_dispatch: + +# cancel already running builds of the same branch or pull request +concurrency: + group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.head_ref || github.sha }} + cancel-in-progress: true + +env: + MATE_PANEL_DEP: 1.27.1 + CONFIGURE_FLAGS: --enable-compile-warnings=maximum + CFLAGS: -g -O2 -Werror=pointer-arith -Werror=implicit-function-declaration + JOBS: 2 + # Useful URL: https://github.com/mate-desktop/debian-packages + # Useful URL: https://salsa.debian.org/debian-mate-team/mate-panel + DEB_LIBRARY_DEPS: | + libcaja-extension-dev + libglib2.0-dev + libgtk-3-dev + libjson-glib-dev + libmagic-dev + DEB_BUILD_DEPS: | + ccache + autoconf-archive + autopoint + git + gettext + make + mate-common + yelp-tools + # Useful URL: https://git.archlinux.org/svntogit/community.git/tree/mate-panel + ARCH_BUILD_DEPS: | + ccache + autoconf-archive + caja + clang + file + gcc + git + glib2-devel + gtk3 + json-glib + make + mate-common + which + yelp-tools + +jobs: + build: + name: Build on ${{matrix.container}} (using ${{matrix.cc}}) + runs-on: ubuntu-latest + container: ${{matrix.container}} + + strategy: + fail-fast: false # don't cancel other jobs in the matrix if one fails + matrix: + container: ['debian:testing', 'ubuntu:rolling', 'archlinux:latest'] + cc: ['gcc'] + cxx: ['g++'] + include: + # test with clang on archlinux:latest + - container: 'archlinux:latest' + cc: 'clang' + cxx: 'clang++' + + env: + # Speed up build with ccache + CC: ccache ${{matrix.cc}} + CXX: ccache ${{matrix.cxx}} + + steps: + # For Debian and Ubuntu (apt-based with reasonably compatible packages) + - name: Install dependencies + if: ${{ startsWith(matrix.container, 'debian:') || startsWith(matrix.container, 'ubuntu:') }} + run: | + apt-get update -qq + apt-get install --assume-yes --no-install-recommends \ + ${DEB_BUILD_DEPS} ${DEB_LIBRARY_DEPS} + + # For ArchLinux + - name: Install dependencies + if: ${{ startsWith(matrix.container, 'archlinux:') }} + # don't upgrade, although told otherwise (see link below), because + # apparently in the container it doesn't quit work... + # https://wiki.archlinux.org/title/System_maintenance#Partial_upgrades_are_unsupported + run: | + pacman --noconfirm -Syu + pacman --noconfirm -S ${ARCH_BUILD_DEPS} + + # Checkout the repository + - uses: actions/checkout@v3 + with: + path: engrampa + submodules: true + + # Setup ccache cache + - name: ccache + uses: hendrikmuhs/[email protected] + with: + key: ${{ matrix.container }}-${{ matrix.cc }} + + # Follows regular build and test steps + + - name: Configure + run: | + cd engrampa + NOCONFIGURE=1 ./autogen.sh + { ./configure ${CONFIGURE_FLAGS} || { cat config.log; exit 1; } ; } + + - name: Build + run: make -C engrampa -j ${{ env.JOBS }} + + - name: Run Tests + run: make -C engrampa -j ${{ env.JOBS }} check + + - name: Run distcheck + # We only run distcheck on one container, because it takes time and + # doesn't seem so useful to repeat everywhere -- it mostly checks the + # build system itself, rather than the build. + if: ${{ startsWith(matrix.container, 'debian:') }} + run: make -C engrampa -j ${{ env.JOBS }} distcheck + + # Do we need the real build for cppcheck run? I don't think so + cppcheck: + name: Run cppcheck + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + # Install code dependencies so that cppcheck has more info + - name: Install dependencies + run: | + sudo apt-get update -qq + sudo apt-get install --assume-yes --no-install-recommends \ + cppcheck ${DEB_LIBRARY_DEPS} + + # - define relevant configuration I can think of + # - _Noreturn: this is to avoid false positive with functions that + # don't return, like g_assert(false). Here, we rely on G_NORETURN + # (GLib 2.68+) using _Noreturn C11 attribute if __STDC_VERSION__ is + # high enough (cppcheck sets it for us in newer versions, but not on + # here yet); but the version of cppcheck we run on don't know about + # the C11 attribute, so map it to the GCC one it does know. + # This is a tad over-specific, but it removes some spurious warnings, + # and defining e.g. __GNUC__=12 is simpler, but is a *lot* slower + # (more than 3 times slower), and doesn't seem to yield other + # benefits for the moment. + # - -I flags from pkg-config (grepped from configure.ac) + # - ignore non-source directories + - name: cppcheck + env: + checks: warning,style,performance,portability,information,missingInclude + defines: > + -DGETTEXT_PACKAGE="engrampa" + -D__STDC_VERSION__=201112 -D_Noreturn=__attribute__((__noreturn__)) + packages: > + gio-2.0 + gio-unix-2.0 + gtk+-3.0 + ice + json-glib-1.0 + libcaja-extension + sm + run: | + cppcheck --enable="$checks" \ + -j $JOBS \ + $defines \ + $(pkg-config --cflags-only-I $packages) \ + -i engrampa/mate-submodules/ \ + . @@ -1,3 +1,10 @@ +### engrampa 1.28.2 + + * Fix extract of encrypted archives + * Fix volume split button in "Compress" window + * src/file-utils.c: Fix "error: implicit declaration of function ‘strcasecmp’..." + * fr-process.c: Setting error status + ### engrampa 1.28.1 * Distribute Meson build system diff --git a/configure.ac b/configure.ac index 60abcb2..875c56b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([engrampa], [1.28.1], [https://github.com/mate-desktop/engrampa/issues], [engrampa], [https://mate-desktop.org]) +AC_INIT([engrampa], [1.28.2], [https://github.com/mate-desktop/engrampa/issues], [engrampa], [https://mate-desktop.org]) AM_INIT_AUTOMAKE([1.9 foreign dist-xz no-dist-gzip check-news]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/meson.build b/meson.build index f7576f1..0e12ef1 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('engrampa', 'c', license : 'GPL2+', - version : '1.28.1', + version : '1.28.2', meson_version : '>=0.43' ) diff --git a/src/fr-command-rar.c b/src/fr-command-rar.c index 6bb70cd..880bfe9 100644 --- a/src/fr-command-rar.c +++ b/src/fr-command-rar.c @@ -39,6 +39,10 @@ #include "fr-error.h" #include "rar-utils.h" + +#define IS_OUTPUT_TYPE(comm, type) ((comm)->output_type & (type)) + + static void fr_command_rar_class_init (FrCommandRarClass *class); static void fr_command_rar_init (FrCommand *afile); static void fr_command_rar_finalize (GObject *object); @@ -150,6 +154,18 @@ attribute_field_with_space (const char *line) return ((line[0] != ' ') && (line[1] == ' ')); } +static gboolean +attr_field_is_dir (const char *attr_field, + FrCommandRar *rar_comm) +{ + if ((attr_field[0] == 'd') || + (IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR5) && attr_field[3] == 'D') || + (! IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR5) && attr_field[1] == 'D')) + return TRUE; + + return FALSE; +} + static void parse_name_field (char *line, FrCommandRar *rar_comm) @@ -163,10 +179,22 @@ parse_name_field (char *line, fdata->encrypted = (line[0] == '*') ? TRUE : FALSE; - if (rar_comm->output_type == FR_COMMAND_RAR_TYPE_RAR5) + if (IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR5)) { + int field_num = attribute_field_with_space (line) ? 9 : 8; + const char *field; + + /* in RAR7 format, directories have a blank CRC32, not the + * "????????" of the RAR5 format */ + if (IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR7)) { + field = get_last_field (line, field_num - 8); + if (attr_field_is_dir (field, rar_comm)) + field_num--; + } + + field = get_last_field (line, field_num); /* rar-5 output adds trailing spaces to short file names :( */ - name_field = g_strchomp (g_strdup (get_last_field (line, attribute_field_with_space (line) ? 9 : 8))); - else + name_field = field ? g_strchomp (g_strdup (field)) : NULL; + } else name_field = g_strdup (line + 1); if (name_field == NULL) @@ -187,18 +215,6 @@ parse_name_field (char *line, g_free (name_field); } -static gboolean -attr_field_is_dir (const char *attr_field, - FrCommandRar *rar_comm) -{ - if ((attr_field[0] == 'd') || - (rar_comm->output_type == FR_COMMAND_RAR_TYPE_RAR5 && attr_field[3] == 'D') || - (rar_comm->output_type != FR_COMMAND_RAR_TYPE_RAR5 && attr_field[1] == 'D')) - return TRUE; - - return FALSE; -} - static void process_line (char *line, gpointer data) @@ -213,7 +229,12 @@ process_line (char *line, int version = 0; if (sscanf (line, "RAR %d.", &version) == 1 || sscanf (line, "UNRAR %d.", &version) == 1) { - rar_comm->output_type = (version >= 5) ? FR_COMMAND_RAR_TYPE_RAR5 : FR_COMMAND_RAR_TYPE_RAR4; + if (version >= 7) + rar_comm->output_type = FR_COMMAND_RAR_TYPE_RAR7; + else if (version >= 5) + rar_comm->output_type = FR_COMMAND_RAR_TYPE_RAR5; + else + rar_comm->output_type = FR_COMMAND_RAR_TYPE_RAR4; if (version > 5) date_newstyle = TRUE; @@ -230,7 +251,7 @@ process_line (char *line, } else if (strncmp (line, "--------", 8) == 0) { rar_comm->list_started = TRUE; - if (rar_comm->output_type != FR_COMMAND_RAR_TYPE_RAR5) + if (! IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR5)) rar_comm->rar4_odd_line = TRUE; } else if (strncmp (line, "Volume ", 7) == 0) @@ -243,17 +264,17 @@ process_line (char *line, return; } - if (rar_comm->rar4_odd_line || rar_comm->output_type == FR_COMMAND_RAR_TYPE_RAR5) + if (rar_comm->rar4_odd_line || IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR5)) parse_name_field (line, rar_comm); - if (! rar_comm->rar4_odd_line) { + if (! rar_comm->rar4_odd_line && rar_comm->fdata && rar_comm->fdata->full_path) { FileData *fdata; const char *size_field, *ratio_field, *date_field, *time_field, *attr_field; int n_fields; - if (rar_comm->output_type == FR_COMMAND_RAR_TYPE_RAR5) + if (IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR5)) n_fields = 6 + (attribute_field_with_space (line) != 0); - else if (rar_comm->output_type == FR_COMMAND_RAR_TYPE_UNRAR_FREE) + else if (IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_UNRAR_FREE)) n_fields = 4; else n_fields = 6; @@ -272,7 +293,7 @@ process_line (char *line, parse_name_field (line, rar_comm); } else { - if (rar_comm->output_type == FR_COMMAND_RAR_TYPE_RAR5) { + if (IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR5)) { int offset = attribute_field_with_space (line) ? 1 : 0; size_field = fields[1+offset]; @@ -281,7 +302,7 @@ process_line (char *line, time_field = fields[5+offset]; attr_field = fields[0+offset]; } - else if (rar_comm->output_type == FR_COMMAND_RAR_TYPE_UNRAR_FREE) { + else if (IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_UNRAR_FREE)) { size_field = fields[0]; date_field = fields[1]; time_field = fields[2]; @@ -336,7 +357,7 @@ process_line (char *line, } } - if (rar_comm->output_type != FR_COMMAND_RAR_TYPE_RAR5) + if (! IS_OUTPUT_TYPE (rar_comm, FR_COMMAND_RAR_TYPE_RAR5)) rar_comm->rar4_odd_line = ! rar_comm->rar4_odd_line; } @@ -676,7 +697,12 @@ fr_command_rar_handle_error (FrCommand *comm, volume_filename = g_path_get_basename (line + strlen ("Cannot find volume ")); error->gerror = g_error_new (FR_ERROR, error->status, _("Could not find the volume: %s"), volume_filename); g_free (volume_filename); - break; + + /* RAR7 complains about missing volume for incorrect passwords + * as well, so don't make this a definite error in case we also + * had an incorrect password one earlier */ + if (! IS_OUTPUT_TYPE (FR_COMMAND_RAR (comm), FR_COMMAND_RAR_TYPE_RAR7)) + break; } } } diff --git a/src/fr-command-rar.h b/src/fr-command-rar.h index 185d24e..ab4e12d 100644 --- a/src/fr-command-rar.h +++ b/src/fr-command-rar.h @@ -40,9 +40,11 @@ typedef struct _FrCommandRarClass FrCommandRarClass; typedef enum { - FR_COMMAND_RAR_TYPE_RAR4 = 0, - FR_COMMAND_RAR_TYPE_RAR5, - FR_COMMAND_RAR_TYPE_UNRAR_FREE, + FR_COMMAND_RAR_TYPE_RAR4 = 1<<0, + FR_COMMAND_RAR_TYPE_RAR5 = 1<<1, + FR_COMMAND_RAR_TYPE_UNRAR_FREE = 1<<2, + /* RAR5 + empty CRC for directories */ + FR_COMMAND_RAR_TYPE_RAR7 = (1<<3) | FR_COMMAND_RAR_TYPE_RAR5, } FrCommandRarType; struct _FrCommandRar |