Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libsolv for openSUSE:Factory checked in at 2021-04-15 16:57:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libsolv (Old) and /work/SRC/openSUSE:Factory/.libsolv.new.12324 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libsolv" Thu Apr 15 16:57:06 2021 rev:84 rq:884675 version:0.7.19 Changes: -------- --- /work/SRC/openSUSE:Factory/libsolv/libsolv.changes 2021-02-23 20:20:41.279670720 +0100 +++ /work/SRC/openSUSE:Factory/.libsolv.new.12324/libsolv.changes 2021-04-15 16:57:21.158668159 +0200 @@ -1,0 +2,17 @@ +Wed Apr 7 14:56:16 CEST 2021 - [email protected] + +- fix rare segfault in resolve_jobrules() that could happen + if new rules are learnt +- fix a couple of memory leaks in error cases +- fix error handling in solv_xfopen_fd() +- bump version to 0.7.19 + +------------------------------------------------------------------- +Fri Mar 26 14:17:46 CET 2021 - [email protected] + +- fixed regex code on win32 +- fixed memory leak in choice rule generation +- repo_add_conda: add flag to skip v2 packages +- bump version to 0.7.18 + +------------------------------------------------------------------- Old: ---- libsolv-0.7.17.tar.bz2 New: ---- libsolv-0.7.19.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libsolv.spec ++++++ --- /var/tmp/diff_new_pack.Or9t6k/_old 2021-04-15 16:57:21.554668786 +0200 +++ /var/tmp/diff_new_pack.Or9t6k/_new 2021-04-15 16:57:21.558668792 +0200 @@ -52,7 +52,7 @@ %bcond_with zypp Name: libsolv -Version: 0.7.17 +Version: 0.7.19 Release: 0 Summary: Package dependency solver using a satisfiability algorithm License: BSD-3-Clause ++++++ libsolv-0.7.17.tar.bz2 -> libsolv-0.7.19.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/.travis.yml new/libsolv-0.7.19/.travis.yml --- old/libsolv-0.7.17/.travis.yml 2019-04-11 16:48:29.000000000 +0200 +++ new/libsolv-0.7.19/.travis.yml 2021-03-18 13:17:35.000000000 +0100 @@ -7,6 +7,12 @@ apt: packages: - cmake + - os: linux + arch: ppc64le + addons: + apt: + packages: + - cmake - os: osx osx_image: xcode9.4 compiler: clang diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/NEWS new/libsolv-0.7.19/NEWS --- old/libsolv-0.7.17/NEWS 2021-01-19 15:14:58.000000000 +0100 +++ new/libsolv-0.7.19/NEWS 2021-04-07 14:59:20.000000000 +0200 @@ -2,6 +2,20 @@ This file contains the major changes between libsolv versions: +Version 0.7.19 +- selected bug fixes: + * fix rare segfault in resolve_jobrules() that could happen + if new rules are learnt + * fix a couple of memory leaks in error cases + * fix error handling in solv_xfopen_fd() + +Version 0.7.18 +- selected bug fixes: + * fixed regex code on win32 + * fixed memory leak in choice rule generation +- new features: + * repo_add_conda: add flag to skip v2 packages + Version 0.7.17 - selected bug fixes: * repo_write: fix handling of nested flexarray diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/VERSION.cmake new/libsolv-0.7.19/VERSION.cmake --- old/libsolv-0.7.17/VERSION.cmake 2021-01-19 15:14:58.000000000 +0100 +++ new/libsolv-0.7.19/VERSION.cmake 2021-04-07 14:59:20.000000000 +0200 @@ -49,5 +49,5 @@ SET(LIBSOLV_MAJOR "0") SET(LIBSOLV_MINOR "7") -SET(LIBSOLV_PATCH "17") +SET(LIBSOLV_PATCH "19") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/bindings/solv.i new/libsolv-0.7.19/bindings/solv.i --- old/libsolv-0.7.17/bindings/solv.i 2020-11-16 15:14:32.000000000 +0100 +++ new/libsolv-0.7.19/bindings/solv.i 2021-04-08 16:34:29.000000000 +0200 @@ -63,7 +63,7 @@ $2 = size; } -%typemap(freearg,noblock=1,match="in") (const unsigned char *str, int len) { +%typemap(freearg,noblock=1,match="in") (const unsigned char *str, size_t len) { if (alloc$argnum == SWIG_NEWOBJ) %delete_array(buf$argnum); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/ext/repo_appdata.c new/libsolv-0.7.19/ext/repo_appdata.c --- old/libsolv-0.7.17/ext/repo_appdata.c 2018-12-11 13:59:34.000000000 +0100 +++ new/libsolv-0.7.19/ext/repo_appdata.c 2021-03-31 13:50:42.000000000 +0200 @@ -183,7 +183,7 @@ if (xmlp->lcontent + il + 1 > xmlp->acontent) { xmlp->acontent = xmlp->lcontent + il + 256; - xmlp->content = realloc(xmlp->content, xmlp->acontent); + xmlp->content = solv_realloc(xmlp->content, xmlp->acontent); } memmove(xmlp->content + l + il, xmlp->content + l, xmlp->lcontent - l + 1); for (i = 0; i < il; i++) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/ext/repo_conda.c new/libsolv-0.7.19/ext/repo_conda.c --- old/libsolv-0.7.17/ext/repo_conda.c 2020-04-24 12:00:43.000000000 +0200 +++ new/libsolv-0.7.19/ext/repo_conda.c 2021-03-02 14:50:57.000000000 +0100 @@ -258,7 +258,7 @@ } static int -parse_main(struct parsedata *pd, struct solv_jsonparser *jp) +parse_main(struct parsedata *pd, struct solv_jsonparser *jp, int flags) { int type = JP_OBJECT; while (type > 0 && (type = jsonparser_parse(jp)) > 0 && type != JP_OBJECT_END) @@ -267,9 +267,9 @@ type = parse_packages(pd, jp); else if (type == JP_ARRAY && !strcmp("packages", jp->key)) type = parse_packages2(pd, jp); - else if (type == JP_OBJECT && !strcmp("packages.conda", jp->key)) + else if (type == JP_OBJECT && !strcmp("packages.conda", jp->key) && !(flags & CONDA_ADD_USE_ONLY_TAR_BZ2)) type = parse_packages(pd, jp); - else if (type == JP_ARRAY && !strcmp("packages.conda", jp->key)) + else if (type == JP_ARRAY && !strcmp("packages.conda", jp->key) && !(flags & CONDA_ADD_USE_ONLY_TAR_BZ2)) type = parse_packages2(pd, jp); else type = jsonparser_skip(jp, type); @@ -298,7 +298,7 @@ jsonparser_init(&jp, fp); if ((type = jsonparser_parse(&jp)) != JP_OBJECT) ret = pool_error(pool, -1, "repository does not start with an object"); - else if ((type = parse_main(&pd, &jp)) != JP_OBJECT_END) + else if ((type = parse_main(&pd, &jp, flags)) != JP_OBJECT_END) ret = pool_error(pool, -1, "parse error line %d", jp.line); jsonparser_free(&jp); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/ext/repo_conda.h new/libsolv-0.7.19/ext/repo_conda.h --- old/libsolv-0.7.17/ext/repo_conda.h 2019-04-04 16:28:06.000000000 +0200 +++ new/libsolv-0.7.19/ext/repo_conda.h 2021-03-02 14:50:57.000000000 +0100 @@ -5,4 +5,6 @@ * for further information */ +#define CONDA_ADD_USE_ONLY_TAR_BZ2 (1 << 8) + extern int repo_add_conda(Repo *repo, FILE *fp, int flags); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/ext/repo_deb.c new/libsolv-0.7.19/ext/repo_deb.c --- old/libsolv-0.7.17/ext/repo_deb.c 2019-04-11 16:48:29.000000000 +0200 +++ new/libsolv-0.7.19/ext/repo_deb.c 2021-03-29 15:09:55.000000000 +0200 @@ -792,5 +792,6 @@ break; } } + solv_free(buf); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/ext/repo_helix.c new/libsolv-0.7.19/ext/repo_helix.c --- old/libsolv-0.7.17/ext/repo_helix.c 2018-11-22 12:59:31.000000000 +0100 +++ new/libsolv-0.7.19/ext/repo_helix.c 2021-03-31 13:50:42.000000000 +0200 @@ -655,7 +655,7 @@ if (xmlp->lcontent + 1 + pd->levrspace > pd->aevrspace) { pd->aevrspace = xmlp->lcontent + 1 + pd->levrspace + 256; - pd->evrspace = (char *)realloc(pd->evrspace, pd->aevrspace); + pd->evrspace = (char *)solv_realloc(pd->evrspace, pd->aevrspace); } memcpy(pd->evrspace + pd->levrspace, xmlp->content, xmlp->lcontent + 1); if (state == STATE_EPOCH) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/ext/solv_xfopen.c new/libsolv-0.7.19/ext/solv_xfopen.c --- old/libsolv-0.7.17/ext/solv_xfopen.c 2020-06-03 14:14:15.000000000 +0200 +++ new/libsolv-0.7.19/ext/solv_xfopen.c 2021-04-06 16:05:22.000000000 +0200 @@ -165,7 +165,7 @@ LZFILE *lzfile; lzma_ret ret; - if (!path && fd < 0) + if ((!path && fd < 0) || (path && fd >= 0)) return 0; for (; *mode; mode++) { @@ -176,19 +176,7 @@ else if (*mode >= '1' && *mode <= '9') level = *mode - '0'; } - if (fd != -1) - fp = fdopen(fd, encoding ? "w" : "r"); - else - fp = fopen(path, encoding ? "w" : "r"); - if (!fp) - return 0; - lzfile = calloc(1, sizeof(*lzfile)); - if (!lzfile) - { - fclose(fp); - return 0; - } - lzfile->file = fp; + lzfile = solv_calloc(1, sizeof(*lzfile)); lzfile->encoding = encoding; lzfile->eof = 0; lzfile->strm = stream_init; @@ -203,10 +191,20 @@ ret = lzma_auto_decoder(&lzfile->strm, 100 << 20, 0); if (ret != LZMA_OK) { - fclose(fp); - free(lzfile); + solv_free(lzfile); + return 0; + } + if (!path) + fp = fdopen(fd, encoding ? "w" : "r"); + else + fp = fopen(path, encoding ? "w" : "r"); + if (!fp) + { + lzma_end(&lzfile->strm); + solv_free(lzfile); return 0; } + lzfile->file = fp; return lzfile; } @@ -237,7 +235,7 @@ } lzma_end(&lzfile->strm); rc = fclose(lzfile->file); - free(lzfile); + solv_free(lzfile); return rc; } @@ -351,7 +349,7 @@ FILE *fp; ZSTDFILE *zstdfile; - if (!path && fd < 0) + if ((!path && fd < 0) || (path && fd >= 0)) return 0; for (; *mode; mode++) { @@ -362,12 +360,6 @@ else if (*mode >= '1' && *mode <= '9') level = *mode - '0'; } - if (fd != -1) - fp = fdopen(fd, encoding ? "w" : "r"); - else - fp = fopen(path, encoding ? "w" : "r"); - if (!fp) - return 0; zstdfile = solv_calloc(1, sizeof(*zstdfile)); zstdfile->encoding = encoding; if (encoding) @@ -377,14 +369,12 @@ if (!zstdfile->cstream) { solv_free(zstdfile); - fclose(fp); return 0; } if (ZSTD_isError(ZSTD_initCStream(zstdfile->cstream, level))) { ZSTD_freeCStream(zstdfile->cstream); solv_free(zstdfile); - fclose(fp); return 0; } zstdfile->out.dst = zstdfile->buf; @@ -398,13 +388,25 @@ { ZSTD_freeDStream(zstdfile->dstream); solv_free(zstdfile); - fclose(fp); return 0; } zstdfile->in.src = zstdfile->buf; zstdfile->in.pos = 0; zstdfile->in.size = 0; } + if (!path) + fp = fdopen(fd, encoding ? "w" : "r"); + else + fp = fopen(path, encoding ? "w" : "r"); + if (!fp) + { + if (encoding) + ZSTD_freeCStream(zstdfile->cstream); + else + ZSTD_freeDStream(zstdfile->dstream); + solv_free(zstdfile); + return 0; + } zstdfile->file = fp; return zstdfile; } @@ -437,7 +439,7 @@ ZSTD_freeDStream(zstdfile->dstream); } rc = fclose(zstdfile->file); - free(zstdfile); + solv_free(zstdfile); return rc; } @@ -546,9 +548,9 @@ { zckCtx *f; - if (!path && fd < 0) + if ((!path && fd < 0) || (path && fd >= 0)) return 0; - if (fd == -1) + if (path) { if (*mode != 'w') fd = open(path, O_RDONLY); @@ -560,18 +562,29 @@ f = zck_create(); if (!f) { - close(fd); + if (path) + close(fd); return 0; } if (*mode != 'w') { if(!zck_init_read(f, fd)) - return 0; + { + zck_free(&f); + if (path) + close(fd); + return 0; + } } else { if(!zck_init_write(f, fd)) - return 0; + { + zck_free(&f); + if (path) + close(fd); + return 0; + } } return cookieopen(f, mode, cookie_zckread, cookie_zckwrite, cookie_zckclose); } @@ -585,19 +598,34 @@ { FILE *fp; void *f; - if (!path && fd < 0) + if ((!path && fd < 0) || (path && fd >= 0)) return 0; - if (fd != -1) + if (strcmp(mode, "r") != 0) + return 0; + if (!path) fp = fdopen(fd, mode); else fp = fopen(path, mode); if (!fp) return 0; - if (strcmp(mode, "r") != 0) - return 0; f = solv_zchunk_open(fp, 1); if (!f) - fclose(fp); + { + if (!path) + { + /* The fd passed by user must not be closed! */ + /* Dup (save) the original fd to a temporary variable and then back. */ + /* It is ugly and thread unsafe hack (non atomical sequence fclose dup2). */ + int tmpfd = dup(fd); + fclose(fp); + dup2(tmpfd, fd); + close(tmpfd); + } + else + { + fclose(fp); + } + } return cookieopen(f, mode, (ssize_t (*)(void *, char *, size_t))solv_zchunk_read, 0, (int (*)(void *))solv_zchunk_close); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/ext/testcase.c new/libsolv-0.7.19/ext/testcase.c --- old/libsolv-0.7.17/ext/testcase.c 2020-12-14 11:20:50.000000000 +0100 +++ new/libsolv-0.7.19/ext/testcase.c 2021-03-29 15:09:55.000000000 +0200 @@ -1473,15 +1473,16 @@ SolverRuleinfo rclass; Queue q; int i; + char *prefix; queue_init(&q); for (rid = 1; (rclass = solver_ruleclass(solv, rid)) != SOLVER_RULE_UNKNOWN; rid++) { - char *prefix = solv_dupjoin("rule ", testcase_rclass2str(rclass), " "); - prefix = solv_dupappend(prefix, testcase_ruleid(solv, rid), 0); solver_ruleliterals(solv, rid, &q); if (rclass == SOLVER_RULE_FEATURE && q.count == 1 && q.elements[0] == -SYSTEMSOLVABLE) continue; + prefix = solv_dupjoin("rule ", testcase_rclass2str(rclass), " "); + prefix = solv_dupappend(prefix, testcase_ruleid(solv, rid), 0); for (i = 0; i < q.count; i++) { Id p = q.elements[i]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/package/libsolv.changes new/libsolv-0.7.19/package/libsolv.changes --- old/libsolv-0.7.17/package/libsolv.changes 2021-01-19 15:14:58.000000000 +0100 +++ new/libsolv-0.7.19/package/libsolv.changes 2021-04-07 14:59:20.000000000 +0200 @@ -1,4 +1,21 @@ ------------------------------------------------------------------- +Wed Apr 7 14:56:16 CEST 2021 - [email protected] + +- fix rare segfault in resolve_jobrules() that could happen + if new rules are learnt +- fix a couple of memory leaks in error cases +- fix error handling in solv_xfopen_fd() +- bump version to 0.7.19 + +------------------------------------------------------------------- +Fri Mar 26 14:17:46 CET 2021 - [email protected] + +- fixed regex code on win32 +- fixed memory leak in choice rule generation +- repo_add_conda: add flag to skip v2 packages +- bump version to 0.7.18 + +------------------------------------------------------------------- Tue Jan 19 15:09:12 CET 2021 - [email protected] - repo_write: fix handling of nested flexarray diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/src/repo_write.c new/libsolv-0.7.19/src/repo_write.c --- old/libsolv-0.7.17/src/repo_write.c 2020-11-06 10:31:44.000000000 +0100 +++ new/libsolv-0.7.19/src/repo_write.c 2021-03-31 13:50:42.000000000 +0200 @@ -1446,7 +1446,7 @@ reloff += 3 * target.nkeys; } - needid = calloc(reloff + pool->nrels, sizeof(*needid)); + needid = solv_calloc(reloff + pool->nrels, sizeof(*needid)); needid[0].map = reloff; /* remember size in case we need to grow */ cbdata.needid = needid; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/src/rules.c new/libsolv-0.7.19/src/rules.c --- old/libsolv-0.7.17/src/rules.c 2020-11-13 16:04:33.000000000 +0100 +++ new/libsolv-0.7.19/src/rules.c 2021-03-18 13:17:35.000000000 +0100 @@ -3339,7 +3339,6 @@ return; } now = solv_timems(0); - solv->choicerules_info = solv_calloc(solv->pkgrules_end, sizeof(Id)); queue_init(&q); queue_init(&qi); queue_init(&qcheck); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/src/solver.c new/libsolv-0.7.19/src/solver.c --- old/libsolv-0.7.17/src/solver.c 2020-10-19 13:14:38.000000000 +0200 +++ new/libsolv-0.7.19/src/solver.c 2021-03-31 13:41:34.000000000 +0200 @@ -1629,6 +1629,7 @@ } olevel = level; level = selectandinstall(solv, level, dq, disablerules, i, SOLVER_REASON_RESOLVE_JOB); + r = solv->rules + i; /* selectandinstall may have added more rules */ if (level <= olevel) { if (level == olevel) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/win32/regex.h new/libsolv-0.7.19/win32/regex.h --- old/libsolv-0.7.17/win32/regex.h 2019-04-11 16:48:30.000000000 +0200 +++ new/libsolv-0.7.19/win32/regex.h 2021-03-08 15:39:28.000000000 +0100 @@ -12,7 +12,8 @@ #define CHARCLASS_NAME_MAX 14 #define RE_DUP_MAX 255 -typedef size_t regoff_t; +#include <BaseTsd.h> +typedef SSIZE_T regoff_t; // #include <bits/alltypes.h> typedef struct re_pattern_buffer { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/win32/regexec.c new/libsolv-0.7.19/win32/regexec.c --- old/libsolv-0.7.17/win32/regexec.c 2019-04-11 16:48:30.000000000 +0200 +++ new/libsolv-0.7.19/win32/regexec.c 2021-03-19 16:09:23.000000000 +0100 @@ -231,7 +231,7 @@ pbytes = sizeof(*reach_pos) * tnfa->num_states; xbytes = sizeof(regoff_t) * num_tags; total_bytes = - (sizeof(long) - 1) * 4 /* for alignment paddings */ + (sizeof(size_t) - 1) * 4 /* for alignment paddings */ + (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes; /* Allocate the memory. */ @@ -242,16 +242,16 @@ /* Get the various pointers within tmp_buf (properly aligned). */ tmp_tags = (void *)buf; tmp_buf = buf + tbytes; - tmp_buf += ALIGN(tmp_buf, long); + tmp_buf += ALIGN(tmp_buf, size_t); reach_next = (void *)tmp_buf; tmp_buf += rbytes; - tmp_buf += ALIGN(tmp_buf, long); + tmp_buf += ALIGN(tmp_buf, size_t); reach = (void *)tmp_buf; tmp_buf += rbytes; - tmp_buf += ALIGN(tmp_buf, long); + tmp_buf += ALIGN(tmp_buf, size_t); reach_pos = (void *)tmp_buf; tmp_buf += pbytes; - tmp_buf += ALIGN(tmp_buf, long); + tmp_buf += ALIGN(tmp_buf, size_t); for (i = 0; i < tnfa->num_states; i++) { reach[i].tags = (void *)tmp_buf; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/win32/tre-mem.c new/libsolv-0.7.19/win32/tre-mem.c --- old/libsolv-0.7.17/win32/tre-mem.c 2019-04-11 16:48:30.000000000 +0200 +++ new/libsolv-0.7.19/win32/tre-mem.c 2021-03-19 16:09:23.000000000 +0100 @@ -143,7 +143,7 @@ } /* Make sure the next pointer will be aligned. */ - size += ALIGN(mem->ptr + size, long); + size += ALIGN(mem->ptr + size, size_t); /* Allocate from current block. */ ptr = mem->ptr; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.17/win32/tre.h new/libsolv-0.7.19/win32/tre.h --- old/libsolv-0.7.17/win32/tre.h 2019-04-11 16:48:30.000000000 +0200 +++ new/libsolv-0.7.19/win32/tre.h 2021-03-19 16:09:23.000000000 +0100 @@ -32,6 +32,7 @@ #include <regex.h> #include <wchar.h> #include <wctype.h> +#include <stdint.h> #undef TRE_MBSTATE @@ -77,8 +78,8 @@ /* Returns number of bytes to add to (char *)ptr to make it properly aligned for the type. */ #define ALIGN(ptr, type) \ - ((((long)ptr) % sizeof(type)) \ - ? (sizeof(type) - (((long)ptr) % sizeof(type))) \ + ((((uintptr_t)ptr) % sizeof(type)) \ + ? (sizeof(type) - (((uintptr_t)ptr) % sizeof(type))) \ : 0) #undef MAX
