https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112783

Jiang ChuanGang <jiangchuanganghw at outlook dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jiangchuanganghw at outlook 
dot co
                   |                            |m

--- Comment #9 from Jiang ChuanGang <jiangchuanganghw at outlook dot com> ---
(In reply to Andrew Pinski from comment #3)
> The problem is not in GCC but rather a bad assumption on the code part.
> 
> Basically we have:
> 
> memcpy(nbuf, name, nlen);
> ...
> 
> 
> if (!name)
> ...
> 
> 
> But the check after a memcpy can be removed as passing a null pointer to
> memcpy is undefined even if nlen is 0 here.
> 
> 
> This patch to the sources fixes the issue for me:
> ```
> diff --git a/libxo/libxo.c b/libxo/libxo.c
> index 916a111..ea71723 100644
> --- a/libxo/libxo.c
> +++ b/libxo/libxo.c
> @@ -4300,7 +4300,8 @@ xo_format_value (xo_handle_t *xop, const char *name,
> ssize_t nlen,
>         if ((xsp->xs_flags & (XSF_EMIT | XSF_EMIT_KEY))
>             || !(xsp->xs_flags & XSF_EMIT_LEAF_LIST)) {
>             char nbuf[nlen + 1];
> -           memcpy(nbuf, name, nlen);
> +            if (name)
> +             memcpy(nbuf, name, nlen);
>             nbuf[nlen] = '\0';
> 
>             ssize_t rc = xo_transition(xop, 0, nbuf, XSS_EMIT_LEAF_LIST);
> @@ -4324,7 +4325,8 @@ xo_format_value (xo_handle_t *xop, const char *name,
> ssize_t nlen,
> 
>         } else if (!(xsp->xs_flags & XSF_EMIT_KEY)) {
>             char nbuf[nlen + 1];
> -           memcpy(nbuf, name, nlen);
> +            if (name)
> +             memcpy(nbuf, name, nlen);
>             nbuf[nlen] = '\0';
> 
>             ssize_t rc = xo_transition(xop, 0, nbuf, XSS_EMIT);
> @@ -4342,7 +4344,8 @@ xo_format_value (xo_handle_t *xop, const char *name,
> ssize_t nlen,
>         if ((xsp->xs_flags & XSF_EMIT_LEAF_LIST)
>             || !(xsp->xs_flags & XSF_EMIT)) {
>             char nbuf[nlen + 1];
> -           memcpy(nbuf, name, nlen);
> +            if (name)
> +             memcpy(nbuf, name, nlen);
>             nbuf[nlen] = '\0';
> 
>             ssize_t rc = xo_transition(xop, 0, nbuf, XSS_EMIT);
> 
> ```

I've encountered the same bug, and your solution does fix it.
But strangely enough, I can't reproduce it with code like the following.
The inevitable condition of this bug still puzzles me. Do you have any thoughts
on this.


#include <stdio.h>
#include <string.h>

static const char *xo_xml_leader_len(const char *name, int len)
{
    if (name == NULL || name[0] == '_')
            return "";
        return "_";
}

void test()
{
    char *name = NULL;
        int len = 0;
        char mbuf[len + 1];
        memcpy(mbuf, name, len);
        mbuf[len] = '\0';
        const char *leader = xo_xml_leader_len(name, len);
        printf("leader: %s", leader);
}

int main()
{
    test();
        return 0;
}
  • [Bug ipa/112783] core dum... jiangchuanganghw at outlook dot com via Gcc-bugs

Reply via email to