* fixed a nasty bug in epoll_loop() and poll_loop() by which an EPOLL_HUP event
  could trigger both a read and a write calls, thus sometimes inducing headers
  being directly sent from srv to cli without modification, and leading further
  modification to crash the process by memory corruption, because
  rep.data+rep.l<rep.h so the memmove() length argument is negative. Only
  observed with epoll() and never poll(), though this one should have been
  affected too. Now, only call functions which have been allowed to.
diff --git a/haproxy.c b/haproxy.c
index a4fdd6f..6b634a9 100644
--- a/haproxy.c
+++ b/haproxy.c
@@ -2967,6 +2967,10 @@
     if (delta + b->r >= b->data + BUFSIZE)
 	return 0;  /* no space left */
 
+    if (b->data + b->l < end)
+	/* The data has been stolen, we could have crashed. Maybe we should abort() ? */
+	return 0;
+
     /* first, protect the end of the buffer */
     memmove(end + delta, end, b->data + b->l - end);
 
@@ -4194,7 +4198,10 @@
 		    if (t->proxy->options & PR_O_COOK_NOC)
 			//len += sprintf(newhdr + len, "Cache-control: no-cache=\"set-cookie\"\r\n");
 			len += sprintf(trash + len, "Cache-control: private\r\n");
-		    
+
+		    if (rep->data + rep->l < rep->h)
+			/* The data has been stolen, we will crash cleanly instead of corrupting memory */
+			*(int *)0 = 0;
 		    buffer_replace2(rep, rep->h, rep->h, trash, len);
 		}
 
@@ -5354,14 +5361,18 @@
 	  if (fdtab[fd].state == FD_STCLOSE)
 	      continue;
 	  
-	  if (epoll_events[count].events & ( EPOLLIN | EPOLLERR | EPOLLHUP ))
-	      fdtab[fd].read(fd);
+	  if (epoll_events[count].events & ( EPOLLIN | EPOLLERR | EPOLLHUP )) {
+	      if (FD_ISSET(fd, StaticReadEvent))
+		  fdtab[fd].read(fd);
+	  }
 	  
 	  if (fdtab[fd].state == FD_STCLOSE)
 	      continue;
 	  
-	  if (epoll_events[count].events & ( EPOLLOUT | EPOLLERR | EPOLLHUP ))
-	      fdtab[fd].write(fd);
+	  if (epoll_events[count].events & ( EPOLLOUT | EPOLLERR | EPOLLHUP )) {
+	      if (FD_ISSET(fd, StaticWriteEvent))
+		  fdtab[fd].write(fd);
+	  }
       }
   }
   return 1;
@@ -5475,14 +5486,18 @@
 	  if (fdtab[fd].state == FD_STCLOSE)
 	      continue;
 	  
-	  if (poll_events[count].revents & ( POLLIN | POLLERR | POLLHUP ))
-	      fdtab[fd].read(fd);
+	  if (poll_events[count].revents & ( POLLIN | POLLERR | POLLHUP )) {
+	      if (FD_ISSET(fd, StaticReadEvent))
+		  fdtab[fd].read(fd);
+	  }
 	  
 	  if (fdtab[fd].state == FD_STCLOSE)
 	      continue;
 	  
-	  if (poll_events[count].revents & ( POLLOUT | POLLERR | POLLHUP ))
-	      fdtab[fd].write(fd);
+	  if (poll_events[count].revents & ( POLLOUT | POLLERR | POLLHUP )) {
+	      if (FD_ISSET(fd, StaticWriteEvent))
+		  fdtab[fd].write(fd);
+	  }
       }
   }
   return 1;