Use XIL/XLI instead of make_number/XINT for converting descriptor to a ptr.
authorEli Zaretskii <eliz@gnu.org>
Thu, 18 Oct 2012 05:13:29 +0000 (07:13 +0200)
committerEli Zaretskii <eliz@gnu.org>
Thu, 18 Oct 2012 05:13:29 +0000 (07:13 +0200)
More safety checks in using the pointer obtained from descriptor.
Not tested yet.

src/w32inevt.c
src/w32notify.c
src/w32term.c
src/w32term.h

index 878106d..06629d3 100644 (file)
@@ -599,7 +599,7 @@ handle_file_notifications (struct input_event *hold_quit)
     {
       DWORD info_size = notifications_size;
       Lisp_Object cs = intern ("utf-16le");
-      Lisp_Object obj = w32_get_watch_object (make_number (notifications_desc));
+      Lisp_Object obj = w32_get_watch_object (notifications_desc);
 
       /* notifications_size could be zero when the buffer of
         notifications overflowed on the OS level, or when the
index 244b0b8..f146210 100644 (file)
@@ -103,12 +103,12 @@ struct notification {
   char *watchee;       /* the file we are interested in */
   HANDLE dir;          /* handle to the watched directory */
   HANDLE thr;          /* handle to the thread that watches */
-  int terminate;       /* if non-zero, request for the thread to terminate */
+  volatile int terminate; /* if non-zero, request for the thread to terminate */
   unsigned signature;
 };
 
 /* Used for communicating notifications to the main thread.  */
-int notification_buffer_in_use;
+volatile int notification_buffer_in_use;
 BYTE file_notifications[16384];
 DWORD notifications_size;
 void *notifications_desc;
@@ -120,7 +120,8 @@ static Lisp_Object Qsecurity_desc, Qsubtree, watch_list;
 /* Signal to the main thread that we have file notifications for it to
    process.  */
 static void
-send_notifications (BYTE *info, DWORD info_size, void *desc, int *terminate)
+send_notifications (BYTE *info, DWORD info_size, void *desc,
+                   volatile int *terminate)
 {
   int done = 0;
   FRAME_PTR f = SELECTED_FRAME ();
@@ -557,7 +558,7 @@ FILE is the name of the file whose event is being reported.  */)
        report_file_error ("Cannot watch file", Fcons (file, Qnil));
     }
   /* Store watch object in watch list. */
-  watch_descriptor = make_number (dirwatch);
+  watch_descriptor = XIL ((EMACS_INT)dirwatch);
   watch_object = Fcons (watch_descriptor, callback);
   watch_list = Fcons (watch_object, watch_list);
 
@@ -572,17 +573,22 @@ WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'.  */)
      (Lisp_Object watch_descriptor)
 {
   Lisp_Object watch_object;
-  struct notification *dirwatch =
-    (struct notification *)XINT (watch_descriptor);
+  struct notification *dirwatch;
+  int status = -1;
 
   /* Remove the watch object from watch list.  Do this before freeing
      the object, do that even if we fail to free it, watch_list is
      kept free of junk.  */
   watch_object = Fassoc (watch_descriptor, watch_list);
   if (!NILP (watch_object))
-    watch_list = Fdelete (watch_object, watch_list);
+    {
+      watch_list = Fdelete (watch_object, watch_list);
+      dirwatch = (struct notification *)XLI (watch_descriptor);
+      if (w32_valid_pointer_p (dirwatch, sizeof(struct notification)))
+       status = remove_watch (dirwatch);
+    }
 
-  if (remove_watch (dirwatch) == -1)
+  if (status == -1)
     report_file_error ("Invalid watch descriptor", Fcons (watch_descriptor,
                                                          Qnil));
 
@@ -590,9 +596,13 @@ WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'.  */)
 }
 
 Lisp_Object
-w32_get_watch_object (Lisp_Object desc)
+w32_get_watch_object (void *desc)
 {
-  return NILP (watch_list) ? Qnil : assoc_no_quit (desc, watch_list);
+  Lisp_Object descriptor = XIL ((EMACS_INT)desc);
+
+  /* This is called from the input queue handling code, so we cannot
+     possibly QUIT if watch_list is not in the right condition.  */
+  return NILP (watch_list) ? Qnil : assoc_no_quit (descriptor, watch_list);
 }
 
 void
index 1285b5a..c00bbe0 100644 (file)
@@ -3282,7 +3282,7 @@ queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
     {
       DWORD info_size = notifications_size;
       Lisp_Object cs = intern ("utf-16le");
-      Lisp_Object obj = w32_get_watch_object (make_number (notifications_desc));
+      Lisp_Object obj = w32_get_watch_object (notifications_desc);
 
       /* notifications_size could be zero when the buffer of
         notifications overflowed on the OS level, or when the
index 94ef962..14b3d1f 100644 (file)
@@ -683,11 +683,11 @@ extern BOOL parse_button (int, int, int *, int *);
 extern void w32_sys_ring_bell (struct frame *f);
 extern void x_delete_display (struct w32_display_info *dpyinfo);
 
-extern int notification_buffer_in_use;
+extern volatile int notification_buffer_in_use;
 extern BYTE file_notifications[16384];
 extern DWORD notifications_size;
 extern void *notifications_desc;
-extern Lisp_Object w32_get_watch_object (Lisp_Object);
+extern Lisp_Object w32_get_watch_object (void *);
 extern Lisp_Object lispy_file_action (DWORD);
 
 extern void w32_initialize_display_info (Lisp_Object);