Fixed bug 1953 - Crash at memcpy X11_DispatchEvent(_THIS) Function
authorSam Lantinga <slouken@libsdl.org>
Wed, 10 Jul 2013 21:57:31 -0700
changeset 7396a36ab6149a10
parent 7395 c1b80390a820
child 7397 08e4eb5cea46
Fixed bug 1953 - Crash at memcpy X11_DispatchEvent(_THIS) Function

Nitz

In Function X11_DispatchEvent(_THIS), case SelectionNotify :
static void
X11_DispatchEvent(_THIS)
{
// Some Code
case SelectionNotify: {
//Some Code
SDL_bool expect_lf = SDL_FALSE;
char *start = NULL; // Initialised with NULL
char *scan = (char*)p.data;
char *fn;
char *uri;
int length = 0;
while (p.count--) {
if (!expect_lf) {
if (*scan==0x0D) {
expect_lf = SDL_TRUE;
} else if(start == NULL) {
start = scan;
length = 0;
}
length++;
} else {
if (*scan==0x0A && length>0) {
uri = malloc(length--);

memcpy(uri, start, length); // Problem is Here, start is still NULL if control comes to else statement without initialising the start pointer, which is wrong

uri[length] = 0;
fn = X11_URIToLocal(uri);
if (fn) SDL_SendDropFile(fn);
free(uri);
}
expect_lf = SDL_FALSE;
start = NULL;
}
scan++;
}
}
As shown above how start pointer remains NULL, Patch for this issue would be:
if (*scan==0x0D) {
expect_lf = SDL_TRUE;
}
if(start == NULL) {
start = scan;
length = 0;
}
Just replace else if statement with if.
src/video/x11/SDL_x11events.c
     1.1 --- a/src/video/x11/SDL_x11events.c	Wed Jul 10 23:43:35 2013 -0400
     1.2 +++ b/src/video/x11/SDL_x11events.c	Wed Jul 10 21:57:31 2013 -0700
     1.3 @@ -778,12 +778,11 @@
     1.4  #endif
     1.5              Atom target = xevent.xselection.target;
     1.6              if (target == data->xdnd_req) {
     1.7 -
     1.8                  /* read data */
     1.9                  SDL_x11Prop p;
    1.10                  X11_ReadProperty(&p, display, data->xwindow, videodata->PRIMARY);
    1.11  
    1.12 -                if(p.format==8) {
    1.13 +                if (p.format == 8) {
    1.14                      SDL_bool expect_lf = SDL_FALSE;
    1.15                      char *start = NULL;
    1.16                      char *scan = (char*)p.data;
    1.17 @@ -792,21 +791,24 @@
    1.18                      int length = 0;
    1.19                      while (p.count--) {
    1.20                          if (!expect_lf) {
    1.21 -                            if (*scan==0x0D) {
    1.22 +                            if (*scan == 0x0D) {
    1.23                                  expect_lf = SDL_TRUE;
    1.24 -                            } else if(start == NULL) {
    1.25 +                            }
    1.26 +                            if (start == NULL) {
    1.27                                  start = scan;
    1.28                                  length = 0;
    1.29                              }
    1.30                              length++;
    1.31                          } else {
    1.32 -                            if (*scan==0x0A && length>0) {
    1.33 -                                uri = malloc(length--);
    1.34 -                                memcpy(uri, start, length);
    1.35 -                                uri[length] = 0;
    1.36 +                            if (*scan == 0x0A && length > 0) {
    1.37 +                                uri = SDL_malloc(length--);
    1.38 +                                SDL_memcpy(uri, start, length);
    1.39 +                                uri[length] = '\0';
    1.40                                  fn = X11_URIToLocal(uri);
    1.41 -                                if (fn) SDL_SendDropFile(fn);
    1.42 -                                free(uri);
    1.43 +                                if (fn) {
    1.44 +                                    SDL_SendDropFile(fn);
    1.45 +                                }
    1.46 +                                SDL_free(uri);
    1.47                              }
    1.48                              expect_lf = SDL_FALSE;
    1.49                              start = NULL;
    1.50 @@ -819,12 +821,12 @@
    1.51  
    1.52                  /* send reply */
    1.53                  XClientMessageEvent m;
    1.54 -                memset(&m, 0, sizeof(XClientMessageEvent));
    1.55 +                SDL_memset(&m, 0, sizeof(XClientMessageEvent));
    1.56                  m.type = ClientMessage;
    1.57                  m.display = display;
    1.58                  m.window = data->xdnd_source;
    1.59                  m.message_type = videodata->XdndFinished;
    1.60 -                m.format=32;
    1.61 +                m.format = 32;
    1.62                  m.data.l[0] = data->xwindow;
    1.63                  m.data.l[1] = 1;
    1.64                  m.data.l[2] = videodata->XdndActionCopy;
    1.65 @@ -835,7 +837,6 @@
    1.66              } else {
    1.67                  videodata->selection_waiting = SDL_FALSE;
    1.68              }
    1.69 -
    1.70          }
    1.71          break;
    1.72