From 4981864e7521b68bbebdcbc4ca25aeea6ac959dd Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg@phi-gamma.net>
Date: Sun, 4 Jan 2015 23:24:06 +0100
Subject: [PATCH] mpmathdecimal.w: guard allocation of factorials cache
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

During the initialization of the decimal number system, MP sets up a
cache for factorial values already calculated. The function is called
whenever a new metapost instance is constructed, causing an existing
cache pointer to be overwritten. This empty cache store is then indexed
at invalid positions since the size info only applies to the previously
allocated array. Consequently, Luatex segfaults almost instantly.

This patch guards the initialization of the factorial cache.

Code that triggers the bug:

    \ifdefined \luatexsuppresslongerror
      \input luamplib.sty
      \mplibnumbersystem {decimal}
      \directlua {metapost = luamplib}
    \fi

    \directlua {
      metapost.load "metafun"
      metapost.load "metafun"
    }

    \mplibcode
      beginfig(0);
        draw fullcircle scaled 42pt withcolor blue;
      endfig;
    \endmplibcode

    \bye

For this to work with the Luatex-Plain format, the following patch must
be applied to force decimal arithmetic:

    --- luatex-mplib.lua.orig	2015-01-04 23:27:23.426036828 +0100
    +++ luatex-mplib.lua	2015-01-04 23:27:25.412716332 +0100
    @@ -147,6 +147,7 @@
             function metapost.load(name)
                 local mpx = mplib.new {
                     ini_version = true,
    +                math_mode = "decimal",
                     find_file = metapost.finder,
                 }
                 local result

This bug was discovered by user “franckpastor” on Github:

  https://github.com/lualatex/luamplib/issues/49

Signed-off-by: Philipp Gesang <phg@phi-gamma.net>
---
 source/texk/web2c/mplibdir/mpmathdecimal.w | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/source/texk/web2c/mplibdir/mpmathdecimal.w b/source/texk/web2c/mplibdir/mpmathdecimal.w
index b530d09..fad3f17 100644
--- a/source/texk/web2c/mplibdir/mpmathdecimal.w
+++ b/source/texk/web2c/mplibdir/mpmathdecimal.w
@@ -384,9 +384,12 @@ void * mp_initialize_decimal_math (MP mp) {
   decNumberFromString(&PI_decNumber, PI_STRING, &set);
   decNumberFromString(&epsilon_decNumber, epsilon, &set);
   decNumberFromString(&EL_GORDO_decNumber, EL_GORDO, &set);
-  factorials = (decNumber **)mp_xmalloc(mp,PRECALC_FACTORIALS_CACHESIZE,sizeof(decNumber *));
-  factorials[0] = (decNumber *)mp_xmalloc(mp,1,sizeof(decNumber));
-  decNumberCopy(factorials[0], &one);
+  if (!factorials)
+  {
+    factorials = (decNumber **)mp_xmalloc(mp,PRECALC_FACTORIALS_CACHESIZE,sizeof(decNumber *));
+    factorials[0] = (decNumber *)mp_xmalloc(mp,1,sizeof(decNumber));
+    decNumberCopy(factorials[0], &one);
+  }
 
   /* alloc */
   math->allocate = mp_new_number;
@@ -1745,4 +1748,4 @@ void mp_init_randoms (MP mp, int seed) {
 @ @c
 void mp_decimal_number_modulo (mp_number *a, mp_number b) {
    decNumberRemainder(a->data.num, a->data.num, b.data.num, &set);
-}
\ No newline at end of file
+}
-- 
2.2.1

