1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
Description: Fix https://bugs.debian.org/886496
* Patched pogl_glut.xs to fix pointer truncation in glutTimerFunc
(Closes: #886496)
Author: Thomas Kremer <bugs.debian@xorg.c-informatik.de>
Bug-Debian: https://bugs.debian.org/886496
Last-Update: 2019-01-23
--- a/pogl_glut.xs
+++ b/pogl_glut.xs
@@ -441,10 +441,27 @@
DO_perl_call_sv(handler, G_DISCARD);
}
+/* glut_timer_handlers is an allocation buffer.
+ All unused elements are SVivs forming a linked-list,
+ starting at glut_timer_handlers_next_free.
+ The end of the list is marked by a -1.
+ If no element is free when one is needed, the buffer will grow.
+*/
+static AV * glut_timer_handlers = 0;
+static int glut_timer_handlers_next_free = -1;
+
/* Callback for glutTimerFunc */
static void generic_glut_timer_handler(int value)
{
- AV * handler_data = (AV*)value;
+ if (!glut_timer_handlers)
+ croak("Timer handler called, but no timers have ever been set up");
+ SV** h = av_fetch(glut_timer_handlers,value,FALSE);
+ if (!h || !SvOK(*h) || !SvROK(*h))
+ croak("Timer handler called for unregistered timer");
+ AV * handler_data = (AV*)SvRV(*h);
+ sv_setiv(*h,glut_timer_handlers_next_free);
+ glut_timer_handlers_next_free = value;
+
SV * handler;
int i;
dSP;
@@ -1017,8 +1034,24 @@
AV * handler_data = newAV();
PackCallbackST(handler_data, 1);
+ SV * handler_data_sv = newRV_inc((SV*)handler_data);
- glutTimerFunc(msecs, generic_glut_timer_handler, (int)handler_data);
+ if (!glut_timer_handlers)
+ glut_timer_handlers = newAV();
+
+ int handler_id = glut_timer_handlers_next_free;
+ if (handler_id == -1) {
+ handler_id = ((int) av_top_index(glut_timer_handlers))+1;
+ if (handler_id < 0)
+ croak("Limit of concurrent timers reached (MAX_INT)");
+ av_push(glut_timer_handlers, handler_data_sv);
+ } else {
+ SV** entry = av_fetch(glut_timer_handlers,handler_id,FALSE);
+ glut_timer_handlers_next_free = SvIV(*entry);
+ sv_setsv(*entry,sv_2mortal(handler_data_sv));
+ }
+
+ glutTimerFunc(msecs, generic_glut_timer_handler, handler_id);
}
ENSURE_callback_thread;}
|