Hi, FreeRDP team.

First, I would like to thank the FreeRDP developers for their great work.
I use FreeRDP ported by me for some not very widely used :-) operating system. Over the last ~year I have found, I think, a few problem points in the source code. All these problems have not been fixed in the original code.
Btw, sorry for my english.

Library libfreerdp
===========

Function rdp_recv_deactivate_all from core/activation.c and function rdp_client_connect from core/connection.c ,
In both of these functions there are cycles:

    while (rdp->state != CONNECTION_STATE_ACTIVE)

in which I add a call Sleep(1) (or better to use SwitchToThread()) to avoid high CPU utilization.

--------------------------------

File core/message.c.
It's a bug in update_message_WindowIcon function: in original code memory alloceted for WINDOW_ICON_ORDER which have only one field iconInfo - pointer to ICON_INFO structure. But memory was not allocated for this structure. See __OS2__ ifdef-blocks:

static BOOL update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
                                      WINDOW_ICON_ORDER* windowIcon)
{
    WINDOW_ORDER_INFO* wParam;
    WINDOW_ICON_ORDER* lParam;

    if (!context || !context->update || !orderInfo || !windowIcon)
        return FALSE;

    wParam = (WINDOW_ORDER_INFO*) malloc(sizeof(WINDOW_ORDER_INFO));

    if (!wParam)
        return FALSE;

    CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO));
#ifdef __OS2__
    /* It's a bug in original code: memory alloceted for WINDOW_ICON_ORDER
which have only one field iconInfo - pointer to ICON_INFO structure.
           But memory was not allocated for this structure. */
    lParam = (WINDOW_ICON_ORDER*) malloc(sizeof(WINDOW_ICON_ORDER));
    lParam->iconInfo = (ICON_INFO*) malloc(sizeof(ICON_INFO));

    if (!lParam->iconInfo)
    {
        free(lParam);
        free(wParam);
        return FALSE;
    }

    CopyMemory(lParam->iconInfo, windowIcon->iconInfo, sizeof(ICON_INFO));
    lParam->iconInfo->bitsMask    = NULL;
    lParam->iconInfo->colorTable  = NULL;
    lParam->iconInfo->bitsColor   = NULL;
#else
    lParam = (WINDOW_ICON_ORDER*) calloc(1, sizeof(WINDOW_ICON_ORDER));

    if (!lParam)
    {
        free(wParam);
        return FALSE;
    }

    CopyMemory(lParam, windowIcon, sizeof(WINDOW_ICON_ORDER));
#endif
    WLog_VRB(TAG,  "update_message_WindowIcon");

    if (windowIcon->iconInfo->cbBitsColor > 0)
    {
lParam->iconInfo->bitsColor = (BYTE*) malloc(windowIcon->iconInfo->cbBitsColor);

        if (!lParam->iconInfo->bitsColor)
            goto out_fail;

CopyMemory(lParam->iconInfo->bitsColor, windowIcon->iconInfo->bitsColor,
                   windowIcon->iconInfo->cbBitsColor);
    }

    if (windowIcon->iconInfo->cbBitsMask > 0)
    {
lParam->iconInfo->bitsMask = (BYTE*) malloc(windowIcon->iconInfo->cbBitsMask);

        if (!lParam->iconInfo->bitsMask)
            goto out_fail;

CopyMemory(lParam->iconInfo->bitsMask, windowIcon->iconInfo->bitsMask,
                   windowIcon->iconInfo->cbBitsMask);
    }

    if (windowIcon->iconInfo->cbColorTable > 0)
    {
lParam->iconInfo->colorTable = (BYTE*) malloc(windowIcon->iconInfo->cbColorTable);

        if (!lParam->iconInfo->colorTable)
            goto out_fail;

CopyMemory(lParam->iconInfo->colorTable, windowIcon->iconInfo->colorTable,
                   windowIcon->iconInfo->cbColorTable);
    }

    return MessageQueue_Post(context->update->queue, (void*) context,
MakeMessageId(WindowUpdate, WindowIcon), (void*) wParam, (void*) lParam);
out_fail:
#ifdef __OS2__
    if ( lParam->iconInfo->bitsMask != NULL )
        free( lParam->iconInfo->bitsMask );
    if ( lParam->iconInfo->colorTable != NULL )
        free( lParam->iconInfo->colorTable );
    if ( lParam->iconInfo->bitsColor != NULL )
        free( lParam->iconInfo->bitsColor );
    free( lParam->iconInfo );
#else
    free(lParam->iconInfo->bitsColor);
    free(lParam->iconInfo->bitsMask);
    free(lParam->iconInfo->colorTable);
#endif
    free(lParam);
    free(wParam);
    return FALSE;
}

And the corresponding fixes in function update_message_free_window_update_class. See __OS2__ ifdef-block:

static BOOL update_message_free_window_update_class(wMessage* msg, int type)
{
    if (!msg)
        return FALSE;

    switch (type)
    {
        case WindowUpdate_WindowCreate:
            free(msg->wParam);
            free(msg->lParam);
            break;

        case WindowUpdate_WindowUpdate:
            free(msg->wParam);
            free(msg->lParam);
            break;

        case WindowUpdate_WindowIcon:
            {
WINDOW_ORDER_INFO* orderInfo = (WINDOW_ORDER_INFO*) msg->wParam; WINDOW_ICON_ORDER* windowIcon = (WINDOW_ICON_ORDER*) msg->lParam;

                if (windowIcon->iconInfo->cbBitsColor > 0)
                {
                    free(windowIcon->iconInfo->bitsColor);
                }

                if (windowIcon->iconInfo->cbBitsMask > 0)
                {
                    free(windowIcon->iconInfo->bitsMask);
                }

                if (windowIcon->iconInfo->cbColorTable > 0)
                {
                    free(windowIcon->iconInfo->colorTable);
                }

                free(orderInfo);
#ifdef __OS2__
                /* See __OS2__ in update_message_WindowIcon() */
                free(windowIcon->iconInfo);
#endif
                free(windowIcon);
.....

--------------------------------

Library libwinpr
=========

File path/shell.c.
Full paths for OS/2 and Windows begin with a drive letter, colon and slash. I think, this must be taken into account in PathMakePathA. It seems that __OS2__ blocks will be fair for Windows too.

BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes)
{
#if defined(_UWP)
    return FALSE;
#elif defined(_WIN32)
return (SHCreateDirectoryExA(NULL, path, lpAttributes) == ERROR_SUCCESS);
#else
    const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
    char* dup;
    char* p;
    BOOL result = TRUE;

    /* we only operate on a non-null, absolute path */
#ifdef __OS2__
    if (!path)
        return FALSE;
#else
    if (!path || *path != delim)
        return FALSE;
#endif

    if (!(dup = _strdup(path)))
        return FALSE;

#ifdef __OS2__
    p = dup[1] == ':' && dup[2] == delim ? &dup[3] : dup;
    while(p)
#else
    for (p = dup; p;)
#endif
    {
        if ((p = strchr(p + 1, delim)))
            * p = '\0';

        if (mkdir(dup, 0777) != 0)
            if (errno != EEXIST)
            {
                result = FALSE;
                break;
            }

        if (p)
            *p = delim;
    }

    free(dup);
    return (result);
#endif
}

--------------------------------

File thread/thread.c.
Here, the return code of sched_yield() is interpreted incorrectly.

BOOL SwitchToThread(VOID)
{
    /**
     * Note: on some operating systems sched_yield is a stub returning -1.
* usleep should at least trigger a context switch if any thread is waiting.
     */
#ifdef __OS2__
    /* [Digi] Linux Programmer's Manual:
       On success, sched_yield() returns 0.  On error, -1 is returned, and
       errno is set appropriately.
    */
    if ( sched_yield() != 0 )
#else
    if (!sched_yield())
#endif
        usleep(1);

    return TRUE;
}


_______________________________________________
FreeRDP-devel mailing list
FreeRDP-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freerdp-devel

Reply via email to