Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package gromox for openSUSE:Factory checked in at 2024-10-16 23:44:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gromox (Old) and /work/SRC/openSUSE:Factory/.gromox.new.19354 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gromox" Wed Oct 16 23:44:43 2024 rev:37 rq:1208138 version:2.35 Changes: -------- --- /work/SRC/openSUSE:Factory/gromox/gromox.changes 2024-10-09 22:12:45.301773739 +0200 +++ /work/SRC/openSUSE:Factory/.gromox.new.19354/gromox.changes 2024-10-16 23:45:48.138604012 +0200 @@ -1,0 +2,13 @@ +Tue Oct 15 11:24:31 UTC 2024 - Jan Engelhardt <jeng...@inai.de> + +- Update to release 2.35 + * alias_resolve: resolve nullptr deref crash + * ews: resolve nullptr deref crash + * mapi_lib: fix out-of-bounds access in PROBLEM_ARRAY::transform + * mapi_lib: rop_util_get_gc_value used the wrong mask, which + caused "Change commit failed because the object was changed + separately" + * exmdb: let PR_ACCESS include permissions from all group + memberships + +------------------------------------------------------------------- Old: ---- gromox-2.34.tar.asc gromox-2.34.tar.zst New: ---- gromox-2.35.tar.asc gromox-2.35.tar.zst ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gromox.spec ++++++ --- /var/tmp/diff_new_pack.VAxCOQ/_old 2024-10-16 23:45:50.094685590 +0200 +++ /var/tmp/diff_new_pack.VAxCOQ/_new 2024-10-16 23:45:50.094685590 +0200 @@ -19,7 +19,7 @@ %define _libexecdir %_prefix/libexec Name: gromox -Version: 2.34 +Version: 2.35 Release: 0 Summary: Groupware server backend with RPC, IMAP,POP3, PHP-MAPI support License: AGPL-3.0-or-later AND GPL-2.0-only AND GPL-3.0-or-later ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.VAxCOQ/_old 2024-10-16 23:45:50.122686758 +0200 +++ /var/tmp/diff_new_pack.VAxCOQ/_new 2024-10-16 23:45:50.126686925 +0200 @@ -1,5 +1,5 @@ -mtime: 1728411261 -commit: cc345f88432cf95111be4b4453707448701142ce36438794c307db79bab02063 +mtime: 1728994419 +commit: fbc8d5d4df0f2ccdb4181c021e33c3f7e1d54871af839a0bb7c1d754fa4f8ebd url: https://src.opensuse.org/jengelh/gromox revision: master ++++++ build.specials.obscpio ++++++ diff: old/*: No such file or directory diff: new/*: No such file or directory ++++++ debian.changelog ++++++ --- /var/tmp/diff_new_pack.VAxCOQ/_old 2024-10-16 23:45:50.214690595 +0200 +++ /var/tmp/diff_new_pack.VAxCOQ/_new 2024-10-16 23:45:50.218690762 +0200 @@ -1,9 +1,9 @@ -gromox (2.34-0) unstable; urgency=low +gromox (2.35-0) unstable; urgency=low * The build process is supposed to replace the entries here automatically from data present in gromox.changes. But if you see this message in installed systems, that would indicate a problem in debtransform(1). - -- Gromox <n...@gromox.com> Tue, 08 Oct 2024 17:10:00 +0200 + -- Gromox <n...@gromox.com> Tue, 15 Oct 2024 13:25:00 +0200 ++++++ gromox-2.34.tar.zst -> gromox-2.35.tar.zst ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/Makefile.am new/gromox-2.35/Makefile.am --- old/gromox-2.34/Makefile.am 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/Makefile.am 2024-10-15 13:20:17.000000000 +0200 @@ -277,7 +277,7 @@ tests_epv_unpack_SOURCES = tests/epv_unpack.cpp tools/edb_pack.cpp tools/edb_pack.hpp tests_epv_unpack_LDADD = ${libesedb_LIBS} ${libHX_LIBS} libgromox_common.la libgromox_mapi.la tests_exrpctest_SOURCES = tests/exrpctest.cpp -tests_exrpctest_LDADD = libgromox_common.la libgromox_exrpc.la +tests_exrpctest_LDADD = libgromox_common.la libgromox_exrpc.la libgromox_mapi.la tests_gxl_383_SOURCES = tests/gxl-383.cpp tests_gxl_383_LDADD = libgromox_common.la libgromox_exrpc.la libgromox_mapi.la tests_jsontest_SOURCES = tests/jsontest.cpp @@ -373,7 +373,7 @@ -e 's|#define LOCALSTATEDIR .*|#define LOCALSTATEDIR "${localstatedir}"|' \ -e 's|#define PKGDATADIR .*|#define PKGDATADIR "${pkgdatadir}"|' \ <${srcdir}/include/gromox/paths.h.in >"$@.tmp" - ${AM_V_at}if ! cmp "$@" "$@.tmp" 2>/dev/null; then mv "$@.tmp" "$@"; fi; rm -f "$@.tmp" + ${AM_V_at}if ! cmp "$@" "$@.tmp" >/dev/null 2>/dev/null; then mv "$@.tmp" "$@"; fi; rm -f "$@.tmp" include/mapierr.cpp: include/gromox/mapierr.hpp tools/defs2php.sh tools/defs2php.pl ${AM_V_GEN}${MKDIR_P} include/gromox diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/Makefile.in new/gromox-2.35/Makefile.in --- old/gromox-2.34/Makefile.in 2024-10-08 17:41:16.622193396 +0200 +++ new/gromox-2.35/Makefile.in 2024-10-15 14:11:18.645312781 +0200 @@ -767,7 +767,8 @@ $(am__DEPENDENCIES_1) libgromox_common.la libgromox_mapi.la am_tests_exrpctest_OBJECTS = tests/exrpctest.$(OBJEXT) tests_exrpctest_OBJECTS = $(am_tests_exrpctest_OBJECTS) -tests_exrpctest_DEPENDENCIES = libgromox_common.la libgromox_exrpc.la +tests_exrpctest_DEPENDENCIES = libgromox_common.la libgromox_exrpc.la \ + libgromox_mapi.la am_tests_gxl_383_OBJECTS = tests/gxl-383.$(OBJEXT) tests_gxl_383_OBJECTS = $(am_tests_gxl_383_OBJECTS) tests_gxl_383_DEPENDENCIES = libgromox_common.la libgromox_exrpc.la \ @@ -1899,7 +1900,7 @@ tests_epv_unpack_SOURCES = tests/epv_unpack.cpp tools/edb_pack.cpp tools/edb_pack.hpp tests_epv_unpack_LDADD = ${libesedb_LIBS} ${libHX_LIBS} libgromox_common.la libgromox_mapi.la tests_exrpctest_SOURCES = tests/exrpctest.cpp -tests_exrpctest_LDADD = libgromox_common.la libgromox_exrpc.la +tests_exrpctest_LDADD = libgromox_common.la libgromox_exrpc.la libgromox_mapi.la tests_gxl_383_SOURCES = tests/gxl-383.cpp tests_gxl_383_LDADD = libgromox_common.la libgromox_exrpc.la libgromox_mapi.la tests_jsontest_SOURCES = tests/jsontest.cpp @@ -5750,7 +5751,7 @@ -e 's|#define LOCALSTATEDIR .*|#define LOCALSTATEDIR "${localstatedir}"|' \ -e 's|#define PKGDATADIR .*|#define PKGDATADIR "${pkgdatadir}"|' \ <${srcdir}/include/gromox/paths.h.in >"$@.tmp" - ${AM_V_at}if ! cmp "$@" "$@.tmp" 2>/dev/null; then mv "$@.tmp" "$@"; fi; rm -f "$@.tmp" + ${AM_V_at}if ! cmp "$@" "$@.tmp" >/dev/null 2>/dev/null; then mv "$@.tmp" "$@"; fi; rm -f "$@.tmp" include/mapierr.cpp: include/gromox/mapierr.hpp tools/defs2php.sh tools/defs2php.pl ${AM_V_GEN}${MKDIR_P} include/gromox diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/configure new/gromox-2.35/configure --- old/gromox-2.34/configure 2024-10-08 17:41:16.062181357 +0200 +++ new/gromox-2.35/configure 2024-10-15 14:11:18.091981290 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for gromox 2.34. +# Generated by GNU Autoconf 2.72 for gromox 2.35. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, @@ -611,8 +611,8 @@ # Identity of this package. PACKAGE_NAME='gromox' PACKAGE_TARNAME='gromox' -PACKAGE_VERSION='2.34' -PACKAGE_STRING='gromox 2.34' +PACKAGE_VERSION='2.35' +PACKAGE_STRING='gromox 2.35' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1483,7 +1483,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures gromox 2.34 to adapt to many kinds of systems. +'configure' configures gromox 2.35 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1554,7 +1554,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of gromox 2.34:";; + short | recursive ) echo "Configuration of gromox 2.35:";; esac cat <<\_ACEOF @@ -1747,7 +1747,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -gromox configure 2.34 +gromox configure 2.35 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2197,7 +2197,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by gromox $as_me 2.34, which was +It was created by gromox $as_me 2.35, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3891,7 +3891,7 @@ # Define the identity of the package. PACKAGE='gromox' - VERSION='2.34' + VERSION='2.35' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -17715,51 +17715,56 @@ my_CFLAGS="-Wall -Wmissing-declarations -Wwrite-strings" my_CXXFLAGS="-Wall -Wmissing-declarations" my_LDFLAGS="" -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking available C++ standard" >&5 -printf %s "checking available C++ standard... " >&6; } -cxxmode="" -for i in "c++26" "c++2c" "c++23" "c++2b" "c++20"; do +cxxmode="error" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ standard availability" >&5 +printf %s "checking for C++ standard availability... " >&6; } +echo "" +for i in "" "c++26" "c++2c" "c++23" "c++2b" "c++20"; do if test -n "$COVERITY" && test "$i" != "c++20" then : continue fi - CXXFLAGS="$saved_CXXFLAGS -std=$i" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CXX${i:+ -std=$i} works for our code" >&5 +printf %s "checking if $CXX${i:+ -std=$i} works for our code... " >&6; } + CXXFLAGS="$saved_CXXFLAGS${i:+ -std=$i}" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <span> + #include <unordered_map> #include <vector> int main() { std::vector<int> v{1,9}; std::span s = v; + std::unordered_map<int, int> um{{}}; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : - cxxmode="$i" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + cxxmode="${i:+ -std=$i}" + break + +else case e in #( + e) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - if test -n "$cxxmode" -then : - break -fi done CXXFLAGS="$saved_CXXFLAGS" -if test -n "$cxxmode" +if test "$cxxmode" = error then : - my_CXXFLAGS="$my_CXXFLAGS -std=$cxxmode" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cxxmode" >&5 -printf "%s\n" "$cxxmode" >&6; } + as_fn_error $? "None of the -std= flags we tried led to successful compilation, but we need C++20 support." "$LINENO" 5 -else case e in #( - e) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 -printf "%s\n" "none" >&6; } - ;; -esac fi +my_CXXFLAGS="$my_CXXFLAGS${cxxmode}" # Check whether --with-asan was given. @@ -21220,7 +21225,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by gromox $as_me 2.34, which was +This file was extended by gromox $as_me 2.35, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -21288,7 +21293,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -gromox config.status 2.34 +gromox config.status 2.35 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/configure.ac new/gromox-2.35/configure.ac --- old/gromox-2.34/configure.ac 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/configure.ac 2024-10-15 13:20:17.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT([gromox], [2.34]) +AC_INIT([gromox], [2.35]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux]) AC_PREFIX_DEFAULT([/usr]) @@ -24,29 +24,36 @@ my_CFLAGS="-Wall -Wmissing-declarations -Wwrite-strings" my_CXXFLAGS="-Wall -Wmissing-declarations" my_LDFLAGS="" -AC_MSG_CHECKING([available C++ standard]) -cxxmode="" -for i in "c++26" "c++2c" "c++23" "c++2b" "c++20"; do +cxxmode="error" +AC_MSG_CHECKING([for C++ standard availability]) +echo "" +for i in "" "c++26" "c++2c" "c++23" "c++2b" "c++20"; do dnl cov-scan cannot take too high a standard AS_IF([test -n "$COVERITY" && test "$i" != "c++20"], [continue]) - CXXFLAGS="$saved_CXXFLAGS -std=$i" + AC_MSG_CHECKING([if $CXX${i:+ -std=$i} works for our code]) + CXXFLAGS="$saved_CXXFLAGS${i:+ -std=$i}" AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include <span> + #include <unordered_map> #include <vector> int main() { std::vector<int> v{1,9}; std::span s = v; + std::unordered_map<int, int> um{{}}; } - ])], [cxxmode="$i"]) - AS_IF([test -n "$cxxmode"], [break]) + ])], [ + AC_MSG_RESULT([yes]) + cxxmode="${i:+ -std=$i}" + break + ], [ + AC_MSG_RESULT([no]) + ]) done CXXFLAGS="$saved_CXXFLAGS" -AS_IF([test -n "$cxxmode"], [ - my_CXXFLAGS="$my_CXXFLAGS -std=$cxxmode" - AC_MSG_RESULT([$cxxmode]) -], [ - AC_MSG_RESULT([none]) +AS_IF([test "$cxxmode" = error], [ + AC_MSG_ERROR([None of the -std= flags we tried led to successful compilation, but we need C++20 support.]) ]) +my_CXXFLAGS="$my_CXXFLAGS${cxxmode}" AC_ARG_WITH([asan], AS_HELP_STRING([--with-asan], [Activate Address Sanitizer]), [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/doc/changelog.rst new/gromox-2.35/doc/changelog.rst --- old/gromox-2.34/doc/changelog.rst 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/doc/changelog.rst 2024-10-15 13:20:17.000000000 +0200 @@ -1,3 +1,19 @@ +Gromox 2.35 92024-10-15) +======================== + +Fixes: + +* alias_resolve: resolve nullptr deref crash +* ews: resolve nullptr deref crash +* mapi_lib: fix out-of-bounds access in PROBLEM_ARRAY::transform +* mapi_lib: rop_util_get_gc_value used the wrong mask, which caused + "Change commit failed because the object was changed separately" + +Changes: + +* exmdb: let PR_ACCESS include permissions from all group memberships + + Gromox 2.34 (2024-10-08) ======================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/emsmdb/attachment_object.cpp new/gromox-2.35/exch/emsmdb/attachment_object.cpp --- old/gromox-2.34/exch/emsmdb/attachment_object.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/emsmdb/attachment_object.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -1,10 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-only WITH linking exception +// SPDX-FileCopyrightText: 2021â2024 grommunio GmbH +// This file is part of Gromox. #include <climits> #include <cstdint> #include <cstdlib> #include <cstring> #include <memory> #include <utility> +#include <vector> #include <gromox/defs.h> #include <gromox/mapidefs.h> #include <gromox/proptag_array.hpp> @@ -16,6 +19,8 @@ #include "message_object.hpp" #include "stream_object.hpp" +using namespace gromox; + static constexpr uint32_t indet_rendering_pos = UINT32_MAX; std::unique_ptr<attachment_object> attachment_object::create(message_object *pparent, @@ -316,7 +321,7 @@ } BOOL attachment_object::set_properties(const TPROPVAL_ARRAY *ppropvals, - PROBLEM_ARRAY *pproblems) + PROBLEM_ARRAY *pproblems) try { auto pattachment = this; PROBLEM_ARRAY tmp_problems; @@ -330,9 +335,7 @@ tmp_propvals.ppropval = cu_alloc<TAGGED_PROPVAL>(ppropvals->count); if (tmp_propvals.ppropval == nullptr) return FALSE; - auto poriginal_indices = cu_alloc<uint16_t>(ppropvals->count); - if (poriginal_indices == nullptr) - return FALSE; + std::vector<uint16_t> poriginal_indices; for (unsigned int i = 0; i < ppropvals->count; ++i) { const auto &pv = ppropvals->ppropval[i]; if (is_readonly_prop(pv.proptag) || @@ -340,8 +343,8 @@ pproblems->emplace_back(i, pv.proptag, ecAccessDenied); continue; } - tmp_propvals.ppropval[tmp_propvals.count] = pv; - poriginal_indices[tmp_propvals.count++] = i; + tmp_propvals.ppropval[tmp_propvals.count++] = pv; + poriginal_indices.push_back(i); } if (tmp_propvals.count == 0) return TRUE; @@ -361,10 +364,13 @@ } } return TRUE; +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1669: ENOMEM"); + return false; } BOOL attachment_object::remove_properties(const PROPTAG_ARRAY *pproptags, - PROBLEM_ARRAY *pproblems) + PROBLEM_ARRAY *pproblems) try { auto pattachment = this; PROBLEM_ARRAY tmp_problems; @@ -378,9 +384,7 @@ tmp_proptags.pproptag = cu_alloc<uint32_t>(pproptags->count); if (tmp_proptags.pproptag == nullptr) return FALSE; - auto poriginal_indices = cu_alloc<uint16_t>(pproptags->count); - if (poriginal_indices == nullptr) - return FALSE; + std::vector<uint16_t> poriginal_indices; for (unsigned int i = 0; i < pproptags->count; ++i) { const auto tag = pproptags->pproptag[i]; if (is_readonly_prop(tag) || @@ -388,7 +392,7 @@ pproblems->emplace_back(i, tag, ecAccessDenied); continue; } - poriginal_indices[tmp_proptags.count] = i; + poriginal_indices.push_back(i); tmp_proptags.emplace_back(tag); } if (tmp_proptags.count == 0) @@ -409,6 +413,9 @@ } } return TRUE; +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1670: ENOMEM"); + return false; } BOOL attachment_object::copy_properties(attachment_object *pattachment_src, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/emsmdb/folder_object.cpp new/gromox-2.35/exch/emsmdb/folder_object.cpp --- old/gromox-2.34/exch/emsmdb/folder_object.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/emsmdb/folder_object.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -1,4 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only WITH linking exception +// SPDX-FileCopyrightText: 2021â2024 grommunio GmbH +// This file is part of Gromox. #include <algorithm> #include <climits> #include <cstdint> @@ -7,6 +9,7 @@ #include <cstring> #include <memory> #include <utility> +#include <vector> #include <gromox/defs.h> #include <gromox/ext_buffer.hpp> #include <gromox/mapidefs.h> @@ -18,6 +21,8 @@ #include "folder_object.hpp" #include "logon_object.hpp" +using namespace gromox; + std::unique_ptr<folder_object> folder_object::create(logon_object *plogon, uint64_t folder_id, uint8_t type, uint32_t tag_access) { @@ -458,7 +463,7 @@ } BOOL folder_object::set_properties(const TPROPVAL_ARRAY *ppropvals, - PROBLEM_ARRAY *pproblems) + PROBLEM_ARRAY *pproblems) try { uint16_t count; BINARY *pbin_pcl; @@ -479,17 +484,15 @@ tmp_propvals.ppropval = cu_alloc<TAGGED_PROPVAL>(count); if (tmp_propvals.ppropval == nullptr) return FALSE; - auto poriginal_indices = cu_alloc<uint16_t>(ppropvals->count); - if (poriginal_indices == nullptr) - return FALSE; + std::vector<uint16_t> poriginal_indices; auto pfolder = this; for (unsigned int i = 0; i < ppropvals->count; ++i) { const auto &pv = ppropvals->ppropval[i]; if (pfolder->is_readonly_prop(pv.proptag)) { pproblems->emplace_back(i, pv.proptag, ecAccessDenied); } else { - tmp_propvals.ppropval[tmp_propvals.count] = pv; - poriginal_indices[tmp_propvals.count++] = i; + tmp_propvals.ppropval[tmp_propvals.count++] = pv; + poriginal_indices.push_back(i); } } if (tmp_propvals.count == 0) @@ -522,6 +525,9 @@ tmp_problems.transform(poriginal_indices); *pproblems += std::move(tmp_problems); return TRUE; +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1743: ENOMEM"); + return false; } BOOL folder_object::remove_properties(const PROPTAG_ARRAY *pproptags, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/emsmdb/logon_object.cpp new/gromox-2.35/exch/emsmdb/logon_object.cpp --- old/gromox-2.34/exch/emsmdb/logon_object.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/emsmdb/logon_object.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -10,6 +10,7 @@ #include <cstring> #include <memory> #include <utility> +#include <vector> #include <libHX/string.h> #include <gromox/defs.h> #include <gromox/mapidefs.h> @@ -664,7 +665,7 @@ } BOOL logon_object::set_properties(const TPROPVAL_ARRAY *ppropvals, - PROBLEM_ARRAY *pproblems) + PROBLEM_ARRAY *pproblems) try { PROBLEM_ARRAY tmp_problems; TPROPVAL_ARRAY tmp_propvals; @@ -680,17 +681,15 @@ tmp_propvals.ppropval = cu_alloc<TAGGED_PROPVAL>(ppropvals->count); if (tmp_propvals.ppropval == nullptr) return FALSE; - auto poriginal_indices = cu_alloc<uint16_t>(ppropvals->count); - if (poriginal_indices == nullptr) - return FALSE; + std::vector<uint16_t> poriginal_indices; auto plogon = this; for (unsigned int i = 0; i < ppropvals->count; ++i) { const auto &pv = ppropvals->ppropval[i]; if (lo_is_readonly_prop(plogon, pv.proptag)) { pproblems->emplace_back(i, pv.proptag, ecAccessDenied); } else { - tmp_propvals.ppropval[tmp_propvals.count] = pv; - poriginal_indices[tmp_propvals.count++] = i; + tmp_propvals.ppropval[tmp_propvals.count++] = pv; + poriginal_indices.push_back(i); } } if (tmp_propvals.count == 0) @@ -703,6 +702,9 @@ tmp_problems.transform(poriginal_indices); *pproblems += std::move(tmp_problems); return TRUE; +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1744: ENOMEM"); + return false; } BOOL logon_object::remove_properties(const PROPTAG_ARRAY *pproptags, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/emsmdb/message_object.cpp new/gromox-2.35/exch/emsmdb/message_object.cpp --- old/gromox-2.34/exch/emsmdb/message_object.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/emsmdb/message_object.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -6,6 +6,7 @@ #include <cstdlib> #include <cstring> #include <memory> +#include <vector> #include <libHX/string.h> #include <gromox/defs.h> #include <gromox/ext_buffer.hpp> @@ -1054,7 +1055,7 @@ } static BOOL message_object_set_properties_internal(message_object *pmessage, - BOOL b_check, const TPROPVAL_ARRAY *ppropvals, PROBLEM_ARRAY *pproblems) + BOOL b_check, const TPROPVAL_ARRAY *ppropvals, PROBLEM_ARRAY *pproblems) try { uint8_t tmp_bytes[3]; PROBLEM_ARRAY tmp_problems; @@ -1072,10 +1073,8 @@ tmp_propvals.ppropval = cu_alloc<TAGGED_PROPVAL>(ppropvals->count); if (tmp_propvals.ppropval == nullptr) return FALSE; - auto poriginal_indices = cu_alloc<uint16_t>(ppropvals->count); - if (poriginal_indices == nullptr) - return FALSE; - + + std::vector<uint16_t> poriginal_indices; auto dir = pmessage->plogon->get_dir(); for (unsigned int i = 0; i < ppropvals->count; ++i) { /* if property is being open as stream object, can not be modified */ @@ -1116,8 +1115,8 @@ return FALSE; } } - tmp_propvals.ppropval[tmp_propvals.count] = pv; - poriginal_indices[tmp_propvals.count++] = i; + tmp_propvals.ppropval[tmp_propvals.count++] = pv; + poriginal_indices.push_back(i); } if (tmp_propvals.count == 0) return TRUE; @@ -1142,6 +1141,9 @@ return FALSE; } return TRUE; +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1745: ENOMEM"); + return false; } BOOL message_object::set_properties(const TPROPVAL_ARRAY *ppropvals, @@ -1153,7 +1155,7 @@ } BOOL message_object::remove_properties(const PROPTAG_ARRAY *pproptags, - PROBLEM_ARRAY *pproblems) + PROBLEM_ARRAY *pproblems) try { auto pmessage = this; PROBLEM_ARRAY tmp_problems; @@ -1169,9 +1171,7 @@ tmp_proptags.pproptag = cu_alloc<uint32_t>(pproptags->count); if (tmp_proptags.pproptag == nullptr) return FALSE; - auto poriginal_indices = cu_alloc<uint16_t>(pproptags->count); - if (poriginal_indices == nullptr) - return FALSE; + std::vector<uint16_t> poriginal_indices; /* if property is being open as stream object, can not be removed */ for (unsigned int i = 0; i < pproptags->count; ++i) { const auto tag = pproptags->pproptag[i]; @@ -1190,7 +1190,7 @@ tag, static_cast<unsigned long long>(message_id), instance_id); continue; default: - poriginal_indices[tmp_proptags.count] = i; + poriginal_indices.push_back(i); tmp_proptags.emplace_back(tag); break; } @@ -1218,6 +1218,9 @@ return FALSE; } return TRUE; +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1746: ENOMEM"); + return false; } BOOL message_object::copy_to(message_object *pmessage_src, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/emsmdb/oxcprpt.cpp new/gromox-2.35/exch/emsmdb/oxcprpt.cpp --- old/gromox-2.34/exch/emsmdb/oxcprpt.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/emsmdb/oxcprpt.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -5,6 +5,7 @@ #include <cstdint> #include <cstring> #include <utility> +#include <vector> #include <gromox/defs.h> #include <gromox/mapidefs.h> #include <gromox/proc_common.h> @@ -565,7 +566,7 @@ ec_error_t rop_copyproperties(uint8_t want_asynchronous, uint8_t copy_flags, const PROPTAG_ARRAY *pproptags, PROBLEM_ARRAY *pproblems, LOGMAP *plogmap, - uint8_t logon_id, uint32_t hsrc, uint32_t hdst) + uint8_t logon_id, uint32_t hsrc, uint32_t hdst) try { BOOL b_force; BOOL b_result; @@ -600,9 +601,7 @@ pproblems->pproblem = cu_alloc<PROPERTY_PROBLEM>(pproptags->count); if (pproblems->pproblem == nullptr) return ecServerOOM; - auto poriginal_indices = cu_alloc<uint16_t>(pproptags->count); - if (poriginal_indices == nullptr) - return ecError; + std::vector<uint16_t> poriginal_indices; switch (object_type) { case ems_objtype::folder: { auto fldsrc = static_cast<folder_object *>(pobject); @@ -626,7 +625,7 @@ } if (copy_flags & MAPI_NOREPLACE && proptags1.has(tag)) continue; - poriginal_indices[proptags.count] = i; + poriginal_indices.push_back(i); proptags.emplace_back(tag); } if (!fldsrc->get_properties(&proptags, &propvals)) @@ -676,7 +675,7 @@ } if (copy_flags & MAPI_NOREPLACE && proptags1.has(tag)) continue; - poriginal_indices[proptags.count] = i; + poriginal_indices.push_back(i); proptags.emplace_back(tag); } if (!msgsrc->get_properties(0, &proptags, &propvals)) @@ -710,7 +709,7 @@ } if (copy_flags & MAPI_NOREPLACE && proptags1.has(tag)) continue; - poriginal_indices[proptags.count] = i; + poriginal_indices.push_back(i); proptags.emplace_back(tag); } if (!atsrc->get_properties(0, &proptags, &propvals)) @@ -730,6 +729,9 @@ default: return ecNotSupported; } +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1747: ENOMEM"); + return ecServerOOM; } ec_error_t rop_copyto(uint8_t want_asynchronous, uint8_t want_subobjects, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/ews/context.cpp new/gromox-2.35/exch/ews/context.cpp --- old/gromox-2.34/exch/ews/context.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/ews/context.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -1032,8 +1032,9 @@ auto& exmdb = m_plugin.exmdb; if(special & sShape::MimeContent) { - MESSAGE_CONTENT* content; - if(!exmdb.read_message(dir.c_str(), nullptr, CP_ACP, mid, &content)) + MESSAGE_CONTENT *content = nullptr; + if (!exmdb.read_message(dir.c_str(), nullptr, CP_ACP, mid, &content) || + content == nullptr) throw EWSError::ItemNotFound(E3071); MAIL mail; auto getPropIds = [&](const PROPNAME_ARRAY* names, PROPID_ARRAY* ids) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/ews/requests.cpp new/gromox-2.35/exch/ews/requests.cpp --- old/gromox-2.34/exch/ews/requests.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/ews/requests.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -1452,8 +1452,10 @@ if(!(ctx.permissions(dir, folder.folderId) & frightsReadAny)) throw EWSError::AccessDenied(E3142); - MESSAGE_CONTENT* content; - if(!ctx.plugin().exmdb.read_message(dir.c_str(), ctx.effectiveUser(folder), CP_ACP, meid.messageId(), &content)) + MESSAGE_CONTENT *content = nullptr; + if (!ctx.plugin().exmdb.read_message(dir.c_str(), + ctx.effectiveUser(folder), CP_ACP, meid.messageId(), + &content) || content == nullptr) throw EWSError::ItemNotFound(E3143); ctx.send(dir, *content); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/exmdb/common_util.cpp new/gromox-2.35/exch/exmdb/common_util.cpp --- old/gromox-2.34/exch/exmdb/common_util.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/exmdb/common_util.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -3999,12 +3999,15 @@ auto pstmt1 = gx_sql_prep(psqlite, sql_string); if (pstmt1 == nullptr) return FALSE; + bool group_match = false; while (pstmt1.step() == SQLITE_ROW) { if (common_util_check_mlist_include(pstmt1.col_text(0), username)) { - *ppermission = sqlite3_column_int64(pstmt1, 1); - return TRUE; + *ppermission |= pstmt1.col_int64(1); + group_match = true; } } + if (group_match) + return TRUE; pstmt1.finalize(); sqlite3_reset(pstmt); sqlite3_bind_text(pstmt, 1, "default", -1, SQLITE_STATIC); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/exch/zcore/message_object.cpp new/gromox-2.35/exch/zcore/message_object.cpp --- old/gromox-2.34/exch/zcore/message_object.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/exch/zcore/message_object.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -7,6 +7,7 @@ #include <cstring> #include <memory> #include <utility> +#include <vector> #include <libHX/string.h> #include <gromox/defs.h> #include <gromox/ext_buffer.hpp> @@ -811,13 +812,12 @@ } static BOOL message_object_set_properties_internal(message_object *pmessage, - BOOL b_check, const TPROPVAL_ARRAY *ppropvals) + BOOL b_check, const TPROPVAL_ARRAY *ppropvals) try { uint8_t tmp_bytes[3]; PROBLEM_ARRAY problems; PROBLEM_ARRAY tmp_problems; TPROPVAL_ARRAY tmp_propvals; - uint16_t *poriginal_indices; TPROPVAL_ARRAY tmp_propvals1; TAGGED_PROPVAL propval_buff[3]; @@ -831,9 +831,7 @@ tmp_propvals.ppropval = cu_alloc<TAGGED_PROPVAL>(ppropvals->count); if (tmp_propvals.ppropval == nullptr) return FALSE; - poriginal_indices = cu_alloc<uint16_t>(ppropvals->count); - if (poriginal_indices == nullptr) - return FALSE; + std::vector<uint16_t> poriginal_indices; for (unsigned int i = 0; i < ppropvals->count; ++i) { const auto &pv = ppropvals->ppropval[i]; if (b_check) { @@ -870,8 +868,8 @@ return FALSE; } } - tmp_propvals.ppropval[tmp_propvals.count] = pv; - poriginal_indices[tmp_propvals.count++] = i; + tmp_propvals.ppropval[tmp_propvals.count++] = pv; + poriginal_indices.push_back(i); } if (tmp_propvals.count == 0) return TRUE; @@ -895,6 +893,9 @@ return FALSE; } return TRUE; +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1748: ENOMEM"); + return false; } BOOL message_object::set_properties(TPROPVAL_ARRAY *ppropvals) @@ -904,13 +905,12 @@ pmessage, TRUE, ppropvals); } -BOOL message_object::remove_properties(const PROPTAG_ARRAY *pproptags) +BOOL message_object::remove_properties(const PROPTAG_ARRAY *pproptags) try { auto pmessage = this; PROBLEM_ARRAY problems; PROBLEM_ARRAY tmp_problems; PROPTAG_ARRAY tmp_proptags; - uint16_t *poriginal_indices; if (!pmessage->b_writable) return FALSE; @@ -922,9 +922,7 @@ tmp_proptags.pproptag = cu_alloc<uint32_t>(pproptags->count); if (tmp_proptags.pproptag == nullptr) return FALSE; - poriginal_indices = cu_alloc<uint16_t>(pproptags->count); - if (poriginal_indices == nullptr) - return FALSE; + std::vector<uint16_t> poriginal_indices; for (unsigned int i = 0; i < pproptags->count; ++i) { const auto tag = pproptags->pproptag[i]; if (msgo_is_readonly_prop(pmessage, tag)) { @@ -932,7 +930,7 @@ continue; } tmp_proptags.pproptag[tmp_proptags.count] = tag; - poriginal_indices[tmp_proptags.count++] = i; + poriginal_indices.push_back(i); } if (tmp_proptags.count == 0) return TRUE; @@ -956,6 +954,9 @@ return FALSE; } return TRUE; +} catch (const std::bad_alloc &) { + mlog(LV_ERR, "E-1749: ENOMEM"); + return false; } BOOL message_object::copy_to(message_object *pmessage_src, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/include/gromox/exmdb_idef.hpp new/gromox-2.35/include/gromox/exmdb_idef.hpp --- old/gromox-2.34/include/gromox/exmdb_idef.hpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/include/gromox/exmdb_idef.hpp 2024-10-15 13:20:17.000000000 +0200 @@ -132,7 +132,7 @@ EXMIDL(unload_store, (const char *dir)) EXMIDL(notify_new_mail, (const char *dir, uint64_t folder_id, uint64_t message_id)) EXMIDL(store_eid_to_user, (const char *dir, const STORE_ENTRYID *store_eid, IDLOUT char **maildir, unsigned int *user_id, unsigned int *domain_id)) -EXMIDL(purge_softdelete, (const char *dir, const char *username, uint64_t folder_id, uint32_t del_flags, mapitime_t cutoff)) +EXMIDL(purge_softdelete, (const char *dir, const char *username, uint64_t folder_id, uint32_t del_flags, gromox::mapitime_t cutoff)) EXMIDL(purge_datafiles, (const char *dir)) EXMIDL(autoreply_tsquery, (const char *dir, const char *peer, uint64_t window, IDLOUT uint64_t *tdiff)) EXMIDL(autoreply_tsupdate, (const char *dir, const char *peer)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/include/gromox/exmdb_rpc.hpp new/gromox-2.35/include/gromox/exmdb_rpc.hpp --- old/gromox-2.34/include/gromox/exmdb_rpc.hpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/include/gromox/exmdb_rpc.hpp 2024-10-15 13:20:17.000000000 +0200 @@ -836,7 +836,7 @@ char *username; uint64_t folder_id = 0; uint32_t del_flags = 0; - mapitime_t cutoff = 0; + gromox::mapitime_t cutoff = 0; }; struct exreq_autoreply_tsquery final : public exreq { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/include/gromox/mapi_types.hpp new/gromox-2.35/include/gromox/mapi_types.hpp --- old/gromox-2.34/include/gromox/mapi_types.hpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/include/gromox/mapi_types.hpp 2024-10-15 13:20:17.000000000 +0200 @@ -246,7 +246,7 @@ inline void emplace_back(unsigned int i, uint32_t tag, uint32_t err) { pproblem[count++] = PROPERTY_PROBLEM{static_cast<uint16_t>(i), tag, err}; } - void transform(const uint16_t *); + void transform(const std::vector<uint16_t> &); size_t indexof(uint32_t tag) const; inline bool has(uint32_t tag) const { return indexof(tag) != npos; } static constexpr size_t npos = -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/include/gromox/mapidefs.h new/gromox-2.35/include/gromox/mapidefs.h --- old/gromox-2.34/include/gromox/mapidefs.h 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/include/gromox/mapidefs.h 2024-10-15 13:20:17.000000000 +0200 @@ -10,9 +10,19 @@ #include <type_traits> #include <gromox/defs.h> -#define PROP_ID(x) static_cast<uint16_t>((x) >> 16) -#define PROP_TYPE(x) static_cast<uint16_t>((x) & 0xFFFF) -#define CHANGE_PROP_TYPE(tag, newtype) static_cast<uint32_t>(((tag) & ~0xFFFF) | (newtype)) +namespace gromox { + +using propid_t = uint16_t; +using proptype_t = uint16_t; +using proptag_t = uint32_t; +/* N.B.: PidLids are not propids (they are also 32-bit wide) */ +using mapitime_t = uint64_t; + +} + +#define PROP_ID(x) static_cast<gromox::propid_t>((x) >> 16) +#define PROP_TYPE(x) static_cast<gromox::proptype_t>((x) & 0xFFFF) +#define CHANGE_PROP_TYPE(tag, newtype) static_cast<gromox::proptag_t>(((tag) & ~0xFFFF) | (newtype)) /* * x|y yields an unsigned result if either x or y are unsigned. @@ -20,7 +30,7 @@ * All the while | and << only make *sense* in an unsigned _context_ anyway * (i.e. the operator should have returned unsigned all the time) */ -#define PROP_TAG(type, tag) static_cast<uint32_t>((static_cast<uint32_t>(tag) << 16) | (type)) +#define PROP_TAG(type, tag) static_cast<gromox::proptag_t>((static_cast<uint32_t>(tag) << 16) | (type)) namespace { enum { /* @@ -76,11 +86,8 @@ PT_MV_CLSID = 0x1048, /* PtypMultipleGuid */ PT_MV_BINARY = 0x1102, /* PtypMultipleBinary */ }; -using proptype_t = decltype(PT_NULL); } -using mapitime_t = uint64_t; - #include "mapitags.hpp" enum { @@ -839,9 +846,14 @@ /* cf. glossary.rst "Internal Identifier" */ struct eid_t { + static constexpr uint64_t GCV_MASK = 0xFFFFFFFFFFFF; eid_t() = default; constexpr eid_t(uint64_t v) : m_value(v) {} + constexpr eid_t(uint16_t r, uint64_t v) : m_value(__builtin_bswap64(v & GCV_MASK) | r) {} constexpr operator uint64_t() const { return m_value; } + constexpr uint64_t gcv() const { return __builtin_bswap64(m_value) & GCV_MASK; } + constexpr uint16_t replid() const { return m_value & 0xFFFF; } + constexpr uint64_t raw() const { return m_value; } void operator=(uint64_t) = delete; uint64_t m_value; }; @@ -1053,7 +1065,7 @@ std::string name; }; -using PROPID_ARRAY = std::vector<uint16_t>; +using PROPID_ARRAY = std::vector<gromox::propid_t>; struct PROPNAME_ARRAY { uint16_t count; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/include/gromox/mapitags.hpp new/gromox-2.35/include/gromox/mapitags.hpp --- old/gromox-2.34/include/gromox/mapitags.hpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/include/gromox/mapitags.hpp 2024-10-15 13:20:17.000000000 +0200 @@ -1113,7 +1113,6 @@ PR_EMS_AB_PARENT_ENTRYID = PROP_TAG(PT_BINARY, 0xFFFC), /* PidTagAddressBookParentEntryId */ PR_EMS_AB_CONTAINERID = PROP_TAG(PT_LONG, 0xFFFD), /* PidTagAddressBookContainerId */ }; -using proptag_t = decltype(PR_NULL); } enum { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/lib/mapi/element_data.cpp new/gromox-2.35/lib/mapi/element_data.cpp --- old/gromox-2.34/lib/mapi/element_data.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/lib/mapi/element_data.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -1,9 +1,12 @@ // SPDX-License-Identifier: GPL-2.0-only WITH linking exception +// SPDX-FileCopyrightText: 2021â2024 grommunio GmbH +// This file is part of Gromox. #include <algorithm> #include <cstdlib> #include <cstring> #include <memory> #include <utility> +#include <vector> #include <gromox/eid_array.hpp> #include <gromox/element_data.hpp> #include <gromox/mapi_types.hpp> @@ -401,8 +404,15 @@ return *this; } -void PROBLEM_ARRAY::transform(const uint16_t *orig_indices) +void PROBLEM_ARRAY::transform(const std::vector<uint16_t> &orig_indices) { - for (size_t i = 0; i < count; ++i) + /* + * Cut off problems related to internally tacked-on properties (cf. + * emsmdb/folder_object::set_folder_properties). + */ + auto end = std::remove_if(&pproblem[0], &pproblem[count], + [=](const PROPERTY_PROBLEM &p) { return p.index >= orig_indices.size(); }); + count = end - &pproblem[0]; + for (unsigned int i = 0; i < count; ++i) pproblem[i].index = orig_indices[pproblem[i].index]; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/lib/mapi/rop_util.cpp new/gromox-2.35/lib/mapi/rop_util.cpp --- old/gromox-2.34/lib/mapi/rop_util.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/lib/mapi/rop_util.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -34,7 +34,7 @@ */ uint64_t rop_util_get_gc_value(eid_t eid) { - return __builtin_bswap64(eid.m_value) & 0xFFFFFFFF; + return __builtin_bswap64(eid.m_value) & eid_t::GCV_MASK; } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/lib/ruleproc.cpp new/gromox-2.35/lib/ruleproc.cpp --- old/gromox-2.34/lib/ruleproc.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/lib/ruleproc.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -1222,6 +1222,8 @@ if (!exmdb_client::read_message(cur.dirc(), nullptr, CP_ACP, cur.mid, &unique_tie(ctnt))) return ecError; + if (ctnt == nullptr) + return ecNotFound; for (auto &&rule : rule_list) { err = rule.extended ? opx_process(*this, rule) : op_process(*this, rule); if (err != ecSuccess) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/mda/alias_resolve.cpp new/gromox-2.35/mda/alias_resolve.cpp --- old/gromox-2.34/mda/alias_resolve.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/mda/alias_resolve.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -50,6 +50,8 @@ static std::atomic<bool> xa_notify_stop{false}; static std::condition_variable xa_thread_wake; +static alias_map xa_empty_alias_map; +static domain_set xa_empty_domain_set; static std::shared_ptr<alias_map> xa_alias_map; static std::shared_ptr<domain_set> xa_domain_set; static std::mutex xa_alias_lock; @@ -149,22 +151,27 @@ return nullptr; } +static void xa_refresh_once() +{ + auto conn = sql_make_conn(); + auto newmap = xa_refresh_aliases(conn); + auto newdom = xa_refresh_domains(conn); + std::unique_lock lk(xa_alias_lock); + if (newmap != nullptr) + xa_alias_map = std::move(newmap); + if (newdom != nullptr) + xa_domain_set = std::move(newdom); +} + static void xa_refresh_thread() { std::mutex slp_mtx; while (!xa_notify_stop) { { - auto conn = sql_make_conn(); - auto newmap = xa_refresh_aliases(conn); - auto newdom = xa_refresh_domains(conn); - std::unique_lock lk(xa_alias_lock); - if (newmap != nullptr) { - xa_alias_map = std::move(newmap); - xa_domain_set = std::move(newdom); - } + std::unique_lock slp_hold(slp_mtx); + xa_thread_wake.wait_for(slp_hold, g_cache_lifetime); } - std::unique_lock slp_hold(slp_mtx); - xa_thread_wake.wait_for(slp_hold, g_cache_lifetime); + xa_refresh_once(); } } @@ -177,8 +184,8 @@ alias_map_ptr = xa_alias_map; domset_ptr = xa_domain_set; } - auto &alias_map = *alias_map_ptr; - auto &domset = *domset_ptr; + auto &alias_map = alias_map_ptr != nullptr ? *alias_map_ptr : xa_empty_alias_map; + auto &domset = domset_ptr != nullptr ? *domset_ptr : xa_empty_domain_set; auto ctrl = &ctx->ctrl; if (strchr(ctrl->from, '@') != nullptr) { @@ -363,8 +370,10 @@ strerror(errno)); return false; } - if (!xa_reload_config(std::move(mcfg), std::move(acfg)) || - !register_hook(xa_alias_subst)) + if (!xa_reload_config(std::move(mcfg), std::move(acfg))) + return false; + xa_refresh_once(); + if (!register_hook(xa_alias_subst)) return false; try { xa_thread = std::thread(xa_refresh_thread); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/tests/exrpctest.cpp new/gromox-2.35/tests/exrpctest.cpp --- old/gromox-2.34/tests/exrpctest.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/tests/exrpctest.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -3,6 +3,7 @@ // This file is part of Gromox. #include <cstdint> #include <cstdlib> +#include <vector> #include <gromox/exmdb_client.hpp> #include <gromox/exmdb_rpc.hpp> #include <gromox/paths.h> @@ -15,6 +16,42 @@ static alloc_context g_alloc_mgr; +static int t_2209(const char *dir) +{ + static constexpr uint64_t v_zero = 0; + static constexpr BINARY v_binzero = {0, {.pc = deconst("")}}; + const TAGGED_PROPVAL pvd[] = { + {PR_COMMENT, deconst("acomment")}, + }; + TAGGED_PROPVAL qvd[std::size(pvd)+4]{}; + const TPROPVAL_ARRAY pvals = {std::size(pvd), deconst(pvd)}; + TPROPVAL_ARRAY qvals = {0, deconst(qvd)}; + std::vector<uint16_t> original_indices; + PROBLEM_ARRAY problems{}; + + for (size_t i = 0; i < pvals.count; ++i) { + const auto &pv = pvals.ppropval[i]; + if (pv.proptag == PR_ACCESS) { + problems.emplace_back(i, pv.proptag, ecAccessDenied); + } else { + qvals.ppropval[qvals.count++] = pv; + original_indices.push_back(i); + } + } + qvals.emplace_back(PidTagChangeNumber, &v_zero); + qvals.emplace_back(PR_CHANGE_KEY, &v_binzero); + qvals.emplace_back(PR_PREDECESSOR_CHANGE_LIST, &v_binzero); + qvals.emplace_back(PROP_TAG(PT_I8, 0), &v_zero); + + if (!exmdb_client::set_folder_properties(dir, CP_UTF8, + rop_util_make_eid_ex(1, PRIVATE_FID_ROOT), &qvals, &problems)) { + mlog(LV_ERR, "set_folder_properties failed unexpectedly"); + return EXIT_FAILURE; + } + problems.transform(original_indices); + return EXIT_SUCCESS; +} + int main(int argc, char **argv) { exmdb_rpc_alloc = [](size_t z) { return g_alloc_mgr.alloc(z); }; @@ -43,5 +80,6 @@ TPROPVAL_ARRAY props{}; if (!exmdb_client::get_store_properties(g_storedir, CP_UTF8, &ptags, &props)) mlog(LV_ERR, "get_store_properties failed unexpectedly"); - return 0; + + return t_2209(g_storedir); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gromox-2.34/tools/exm2eml.cpp new/gromox-2.35/tools/exm2eml.cpp --- old/gromox-2.34/tools/exm2eml.cpp 2024-10-08 17:35:13.000000000 +0200 +++ new/gromox-2.35/tools/exm2eml.cpp 2024-10-15 13:20:17.000000000 +0200 @@ -178,6 +178,8 @@ msg_id = strtoull(sep + 1, nullptr, 0); uint32_t inst_id = 0; ctnt = message_content_init(); + if (ctnt == nullptr) + throw std::bad_alloc(); if (!exmdb_client_remote::load_message_instance(g_storedir, nullptr, CP_UTF8, false, rop_util_make_eid_ex(1, folder_id), rop_util_make_eid_ex(1, msg_id), &inst_id)) { @@ -199,7 +201,7 @@ } if (ctnt == nullptr) { fprintf(stderr, "A message by the id %llxh was not found\n", - static_cast<unsigned long long>(msg_id)); + static_cast<unsigned long long>(msg_id)); return EXIT_FAILURE; } }