This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, master has been updated
       via  309bce4842a9845ed0bd189c2bb932e8107502b8 (commit)
       via  54dcb9ce9d6f266f591613e1844670fa6e8a77c0 (commit)
       via  d53aeb132ba88cb42a0514ec3f8c83cfd27ab2b1 (commit)
       via  a9d53b2c9c5c7ebf89da0ed82e8a5107b041f5d9 (commit)
       via  d61575c6c0ba5f80d371a6a74f762fd4a32a96ff (commit)
       via  13f0da02ae64d8b2f27156bb20901e781b038aef (commit)
       via  fbc3d4f9a3f4c41184d250c58b0a031a44075e62 (commit)
       via  c47cf1cf76cd9c120881ca552ec34890014d1cf6 (commit)
       via  5f5b45d3915b5b3b1660db4f3f3e2a2564377fb1 (commit)
       via  fcfc96a351704dedbfa1c476b3791f431045fa72 (commit)
       via  44e481fc6c362efdf59e7f46e3873292cbb1a278 (commit)
       via  5fd6948620c22e6e2dce2988738b928a8a000748 (commit)
       via  6ae5df09e1e72395bc9f2f9946ba8cbf2b88a393 (commit)
       via  9dfa4394f1410c7eac4fa30a03a4e3e108cd5a2c (commit)
       via  66433e4902ecdb1c988f6577bc86e930c474b022 (commit)
       via  b5974e32cf3b4b1f740c1bfd6229f225fb12671d (commit)
       via  73fee0fc450df7c4ce29b90a252247f35f68b4f6 (commit)
       via  466073989f6fc20b56e2c2d77b5676bbf7b3c36f (commit)
       via  31377f63785917dced78bcf973997d756e321f66 (commit)
       via  e508c939f80dfbd0fd3473e94b5dd66a9c8f1fcd (commit)
       via  4bb2c05c4232ea35dc59e60f5e7bf23ea206af50 (commit)
       via  73f6d7db4eddf19317e52bea4ae35b90eb23d4e4 (commit)
       via  d82963884953e3ce8d759eea8f228fd8d141032d (commit)
       via  4a3ca5f0768682f16550a92086fa1292b3c3e617 (commit)
       via  e457547e15c5a7815f6bf5ea86bdd26934376018 (commit)
       via  ea850cdc31a338298187e018d18389cdf5a1a807 (commit)
      from  1db485dbb1e039dd9753b4a5171852d66d7f79ea (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=309bce4842a9845ed0bd189c2bb932e8107502b8

commit 309bce4842a9845ed0bd189c2bb932e8107502b8
Author: mirabilos <[email protected]>
Date:   Thu Jun 11 03:53:42 2020 +0200

    Update minijson and its testsuite from hello-php-world
    
    Brings back PHP 5.0 compatibility, adds a test and makes the
    testsuite more reliable, and 15–20% speed boost with PHP 7.4

diff --git a/src/common/include/minijson.php b/src/common/include/minijson.php
index bfb5310..ecb18c7 100644
--- a/src/common/include/minijson.php
+++ b/src/common/include/minijson.php
@@ -1,10 +1,12 @@
 <?php
-if (count(get_included_files()) <= 1 && !defined('__main__'))
+if (!defined('__main__') && count(get_included_files()) <= 1 && 
count(debug_backtrace()) < 1)
        define('__main__', __FILE__);
 /**
  * Minimal complete JSON generator and parser for FusionForge/Evolvis
  * and SimKolab, including for debugging output serialisation
  *
+ * Copyright © 2020
+ *     mirabilos <[email protected]>
  * Copyright © 2010, 2011, 2012, 2014, 2016, 2017
  *     mirabilos <[email protected]>
  *
@@ -29,7 +31,7 @@ if (count(get_included_files()) <= 1 && !defined('__main__'))
  *
  * Call as CLI script to filter input as JSON pretty-printer. Options
  * are -c (compact output, no indentation or spaces), -d depth (parse
- * depth defaulting to 32), -r (pretty-print resources as string) and
+ * depth defaulting to 32), -r (pretty-print resources as object) and
  * -t truncsz (truncation size).
  */
 
@@ -42,7 +44,9 @@ if (count(get_included_files()) <= 1 && !defined('__main__'))
 /**
  * Encodes an array (indexed or associative) or any value as JSON.
  * See minijson_encode_ob_string() for limitations on strings;
- * strings not encoded in UTF-8 and resources may not round-trip.
+ * strings not encoded in UTF-8 and resources do not round-trip.
+ *
+ * Optional arguments use the default value if NULL is passed for each.
  *
  * in: array   x (Value to be encoded)
  * in: string  (optional) or bool false to skip beautification (default: '')
@@ -54,7 +58,8 @@ if (count(get_included_files()) <= 1 && !defined('__main__'))
  */
 function minijson_encode($x, $ri='', $depth=32, $truncsz=0, $dumprsrc=false) {
        ob_start();
-       minijson_encode_ob($x, $ri, $depth, $truncsz, $dumprsrc);
+       minijson_encode_ob($x, !is_null($ri) ? $ri : '', $depth ? $depth : 32,
+           $truncsz ? $truncsz : 0, $dumprsrc ? $dumprsrc : false);
        return ob_get_clean();
 }
 
@@ -65,9 +70,10 @@ function minijson_encode($x, $ri='', $depth=32, $truncsz=0, 
$dumprsrc=false) {
  * in: string  x (Value to be encoded)
  * in: integer (optional) truncation size (default 0 to not truncate),
  *             makes output invalid JSON
+ * in:  string  (optional) always '"'
  * out:        stdout  encoded
  */
-function minijson_encode_ob_string($x, $truncsz=0) {
+function minijson_encode_ob_string($x, $truncsz=0, $leader='"') {
        if (!is_string($x))
                $x = strval($x);
 
@@ -77,95 +83,92 @@ function minijson_encode_ob_string($x, $truncsz=0) {
                echo 'TOO_LONG_STRING_TRUNCATED:';
                $Sx = $truncsz;
        }
-       echo '"';
+       echo $leader;
 
        /* assume UTF-8 first, for sanity */
        ob_start();     /* in case a restart is needed */
 
        $Sp = 0;
- minijson_encode_string_utf8:
-       if ($Sp >= $Sx) {
-               ob_end_flush();
-               echo '"';
-               return;
-       }
+       while (true) {
+               if ($Sp >= $Sx) {
+                       echo '"';
+                       ob_end_flush();
+                       return;
+               }
 
-       /* read next octet */
-       $c = ord(($ch = $x[$Sp++]));
+               /* read next octet */
+               $c = ord(($ch = $x[$Sp++]));
 
-       if ($c === 0x5C) {
-               /* just backslash */
-               echo "\\\\";
-               goto minijson_encode_string_utf8;
-       }
+               if ($c > 0x22 && $c < 0x7F) {
+                       /* printable ASCII except space, !, " */
+                       if ($c === 0x5C)
+                               echo $ch;
+                       echo $ch;
+                       continue;
+               }
 
-       if ($c > 0x22 && $c < 0x7F) {
-               /* printable ASCII except space, !, " and backslash */
-               echo $ch;
-               goto minijson_encode_string_utf8;
-       }
+               if ($c < 0x80) {
+                       /* C0 control character, space, !, " or DEL */
+                       if (($c & 0x7E) === 0x20)
+                               echo $ch;
+                       elseif ($c === 0x22)
+                               echo '\"';
+                       elseif ($c === 0x08)
+                               echo '\b';
+                       elseif ($c === 0x09)
+                               echo '\t';
+                       elseif ($c === 0x0A)
+                               echo '\n';
+                       elseif ($c === 0x0C)
+                               echo '\f';
+                       elseif ($c === 0x0D)
+                               echo '\r';
+                       elseif (!$c)
+                               $Sp = $Sx;
+                       else
+                               printf('\u%04X', $c);
+                       continue;
+               }
 
-       if ($c < 0x80) {
-               /* C0 control character, space, !, " or DEL */
-               if (($c & 0x7E) === 0x20)
-                       echo $ch;
-               elseif ($c === 0x22)
-                       echo '\"';
-               elseif ($c === 0x08)
-                       echo '\b';
-               elseif ($c === 0x09)
-                       echo '\t';
-               elseif ($c === 0x0A)
-                       echo '\n';
-               elseif ($c === 0x0C)
-                       echo '\f';
-               elseif ($c === 0x0D)
-                       echo '\r';
-               elseif (!$c)
-                       $Sp = $Sx;
-               else
-                       printf('\u%04X', $c);
-               goto minijson_encode_string_utf8;
-       }
+               /* UTF-8 lead byte */
+               if ($c < 0xE0) {
+                       if ($c < 0xC2)
+                               break;
+                       $wc = ($c & 0x1F) << 6;
+                       $wmin = 0x80;
+                       $Ss = 1;
+               } elseif ($c < 0xF0) {
+                       $wc = ($c & 0x0F) << 12;
+                       $wmin = 0x800;
+                       $Ss = 2;
+               } elseif ($c < 0xF8) {
+                       $wc = ($c & 0x07) << 18;
+                       $wmin = 0x10000;
+                       $Ss = 3;
+               } else {
+                       break;
+               }
+               $u = $ch;
+               /* UTF-8 trail bytes */
+               if ($Sp + $Ss > $Sx)
+                       break;
+               while ($Ss--)
+                       if (($c = ord(($ch = $x[$Sp++])) ^ 0x80) <= 0x3F) {
+                               $wc |= $c << (6 * $Ss);
+                               $u .= $ch;
+                       } else
+                               break 2;
+               /* complete wide character */
+               if ($wc < $wmin)
+                       break;
 
-       /* UTF-8 lead byte */
-       if ($c < 0xC2 || $c >= 0xF8) {
-               goto minijson_encode_string_latin1;
-       } elseif ($c < 0xE0) {
-               $wc = ($c & 0x1F) << 6;
-               $wmin = 0x80;
-               $Ss = 1;
-       } elseif ($c < 0xF0) {
-               $wc = ($c & 0x0F) << 12;
-               $wmin = 0x800;
-               $Ss = 2;
-       } else {
-               $wc = ($c & 0x07) << 18;
-               $wmin = 0x10000;
-               $Ss = 3;
-       }
-       /* UTF-8 trail bytes */
-       if ($Sp + $Ss > $Sx)
-               goto minijson_encode_string_latin1;
-       while ($Ss--)
-               if (($c = ord($x[$Sp++]) ^ 0x80) <= 0x3F)
-                       $wc |= $c << (6 * $Ss);
-               else
-                       goto minijson_encode_string_latin1;
-       /* complete wide character */
-       if ($wc < $wmin)
-               goto minijson_encode_string_latin1;
-
-       if ($wc < 0x00A0)
-               printf('\u%04X', $wc);
-       elseif ($wc < 0x0800)
-               echo chr(0xC0 | ($wc >> 6)) .
-                   chr(0x80 | ($wc & 0x3F));
-       elseif ($wc > 0xFFFD || ($wc >= 0xD800 && $wc <= 0xDFFF) ||
-           ($wc >= 0x2028 && $wc <= 0x2029)) {
-               if ($wc > 0xFFFF) {
+               if (($wc >= 0x00A0 && $wc < 0x2028) ||
+                   ($wc > 0x2029 && $wc < 0xD800) ||
+                   ($wc > 0xDFFF && $wc <= 0xFFFD))
+                       echo $u;
+               elseif ($wc > 0xFFFF) {
                        if ($wc > 0x10FFFF)
-                               goto minijson_encode_string_latin1;
+                               break;
                        /* UTF-16 */
                        $wc -= 0x10000;
                        printf('\u%04X\u%04X',
@@ -173,15 +176,10 @@ function minijson_encode_ob_string($x, $truncsz=0) {
                            0xDC00 | ($wc & 0x03FF));
                } else
                        printf('\u%04X', $wc);
-       } else
-               echo chr(0xE0 | ($wc >> 12)) .
-                   chr(0x80 | (($wc >> 6) & 0x3F)) .
-                   chr(0x80 | ($wc & 0x3F));
 
-       /* process next char */
-       goto minijson_encode_string_utf8;
+               /* process next char */
+       }
 
- minijson_encode_string_latin1:
        /* failed, interpret as sorta latin1 but display only ASCII */
        ob_end_clean();
 
@@ -190,9 +188,8 @@ function minijson_encode_ob_string($x, $truncsz=0) {
                /* similar logic as above, just not as golfed for speed */
                if ($c >= 0x20 && $c < 0x7F) {
                        if ($c === 0x22 || $c === 0x5C)
-                               echo "\\" . $ch;
-                       else
-                               echo $ch;
+                               echo "\\";
+                       echo $ch;
                } else switch ($c) {
                case 0x08:
                        echo '\b';
@@ -229,8 +226,7 @@ function minijson_encode_ob_string($x, $truncsz=0) {
  * out:        stdout  encoded
  */
 function minijson_encode_ob($x, $ri, $depth, $truncsz, $dumprsrc) {
-       if (!$depth-- || !isset($x) || is_null($x) || (is_float($x) &&
-           (is_nan($x) || is_infinite($x)))) {
+       if (!$depth-- || !isset($x) || is_null($x)) {
                echo 'null';
                return;
        }
@@ -244,37 +240,36 @@ function minijson_encode_ob($x, $ri, $depth, $truncsz, 
$dumprsrc) {
                return;
        }
 
-       if (is_int($x)) {
-               $y = (int)$x;
-               $z = strval($y);
-               if (strval($x) === $z) {
-                       echo $z;
+       if (is_int($x) || is_float($x)) {
+               if (is_int($x)) {
+                       $y = (int)$x;
+                       $z = strval($y);
+                       if (strval($x) === $z) {
+                               echo $z;
+                               return;
+                       }
+               } else if (is_nan($x) || is_infinite($x)) {
+                       echo 'null';
                        return;
                }
-               goto minijson_encode_number;
-       }
-
-       if (is_float($x)) {
- minijson_encode_number:
                $rs = sprintf('%.14e', $x);
                $v = explode('e', $rs);
                $rs = rtrim($v[0], '0');
-               if (substr($rs, -1) === '.')
-                       $rs .= '0';
-               if ($v[1] !== '-0' && $v[1] !== '+0')
-                       $rs .= 'E' . $v[1];
                echo $rs;
+               if ($rs[strlen($rs) - 1] === '.')
+                       echo '0';
+               if ($v[1] !== '-0' && $v[1] !== '+0')
+                       echo 'E' . $v[1];
                return;
        }
 
-       /* strings or unknown scalars */
-       if (is_string($x) ||
-           (!is_array($x) && !is_object($x) && is_scalar($x))) {
+       /* strings */
+       if (is_string($x)) {
                minijson_encode_ob_string($x, $truncsz);
                return;
        }
 
-       /* arrays, objects, resources, unknown non-scalars */
+       /* arrays, objects, resources, unknown scalars and nōn-scalars */
 
        if ($ri === false) {
                $si = false;
@@ -296,27 +291,47 @@ function minijson_encode_ob($x, $ri, $depth, $truncsz, 
$dumprsrc) {
                        return;
                }
                ob_start();
-               echo '[';
+               echo '['/*]*/;
+               $isarr = true;
                for ($v = 0; $v < $n; ++$v) {
                        if (!array_key_exists($v, $x)) {
                                /* failed — sparse or associative */
-                               ob_end_clean();
-                               goto minijson_encode_object;
+                               $isarr = false;
+                               break;
                        }
                        echo $xi;
                        minijson_encode_ob($x[$v],
                            $si, $depth, $truncsz, $dumprsrc);
                        $xi = $Si;
                }
-               ob_end_flush();
-               echo $xr . ']';
-               return;
-       }
-
-       /* http://de2.php.net/manual/en/function.is-resource.php#103942 */
-       if (!is_object($x) && !is_null($rsrctype = @get_resource_type($x))) {
+               if ($isarr) {
+                       ob_end_flush();
+                       echo $xr . /*[*/']';
+                       return;
+               }
+               ob_end_clean();
+               /* sparse or associative array */
+       } elseif (is_object($x)) {
+               /* PHP objects are mostly like associative arrays */
+               if (!($x = (array)$x)) {
+                       echo '{}';
+                       return;
+               }
+               /* converted into nōn-empty associative array */
+       /* https://www.php.net/manual/en/function.is-resource.php#103942 */
+       } elseif (!is_null($rsrctype = @get_resource_type($x))) {
                if (!$dumprsrc) {
-                       minijson_encode_ob_string($x, $truncsz);
+                       $rs = (int)$x;
+                       $x = strval($x);
+                       $rsrctype = 'resource('/*)*/ . $rs . ($rsrctype ?
+                           (/*(*/')<' . $rsrctype . '>') : /*(*/'?)');
+                       if ($x === ('Resource id #' . $rs))
+                               $x = $rsrctype . ';';
+                       elseif (strncmp($x, 'Resource ', 9) === 0)
+                               $x = $rsrctype . substr($x, 8);
+                       else
+                               $x = $rsrctype . '{' . $x . '}';
+                       minijson_encode_ob_string($x, $truncsz, '"\u0000');
                        return;
                }
                $rs = array(
@@ -349,20 +364,24 @@ function minijson_encode_ob($x, $ri, $depth, $truncsz, 
$dumprsrc) {
                        $rs['status'] = pg_result_status($x, 
PGSQL_STATUS_STRING);
                        break;
                }
-               echo '{' . $xi . '"\u0000resource"' . $Sd;
+               echo '{'/*}*/ . $xi . '"\u0000resource:"' . $Sd;
                minijson_encode_ob($rs, $si, $depth + 1, $truncsz, $dumprsrc);
-               echo $xr . '}';
+               echo $xr . /*{*/'}';
+               return;
+       } elseif (is_scalar($x)) {
+               /* unknown scalar (treat as String) */
+               minijson_encode_ob_string($x, $truncsz);
                return;
+       } else {
+               /* unknown nōn-scalar (treat as Object and cast, see above) */
+               if (!($x = (array)$x)) {
+                       echo '{}';
+                       return;
+               }
        }
 
-       /* treat everything else as Object */
+       /* array, object or unknown nōn-scalar, cast as associative array */
 
-       /* PHP objects are mostly like associative arrays */
-       if (!($x = (array)$x)) {
-               echo '{}';
-               return;
-       }
- minijson_encode_object:
        $s = array();
        foreach (array_keys($x) as $k) {
                $v = $k;
@@ -374,7 +393,7 @@ function minijson_encode_ob($x, $ri, $depth, $truncsz, 
$dumprsrc) {
                $s[$k] = $v;
        }
        asort($s, SORT_STRING);
-       echo '{';
+       echo '{'/*}*/;
        foreach ($s as $k => $v) {
                echo $xi;
                minijson_encode_ob_string($v, $truncsz);
@@ -382,7 +401,7 @@ function minijson_encode_ob($x, $ri, $depth, $truncsz, 
$dumprsrc) {
                minijson_encode_ob($x[$k], $si, $depth, $truncsz, $dumprsrc);
                $xi = $Si;
        }
-       echo $xr . '}';
+       echo $xr . /*{*/'}';
 }
 
 /**
@@ -406,7 +425,7 @@ function minijson_decode($s, &$ov, $depth=32) {
        $rv = false;
 
        /* skip Byte Order Mark if present */
-       if (substr($s, 0, 3) === "\xEF\xBB\xBF")
+       if (strncmp($s, "\xEF\xBB\xBF", 3) === 0)
                $Sp = 3;
 
        /* skip leading whitespace */
@@ -423,7 +442,7 @@ function minijson_decode($s, &$ov, $depth=32) {
                minijson_skip_wsp($s, $Sp, $Sx);
                /* end of string? */
                if ($Sp < $Sx) {
-                       $ov = 'expected EOS';
+                       $ov = 'unexpected trailing garbage';
                        $rv = false;
                }
        }
@@ -438,382 +457,380 @@ function minijson_decode($s, &$ov, $depth=32) {
 /* skip all characters that are JSON whitespace */
 function minijson_skip_wsp($s, &$Sp, $Sx) {
        while ($Sp < $Sx)
-               switch (ord($s[$Sp])) {
-               default:
-                       return;
-               case 0x09:
-               case 0x0A:
-               case 0x0D:
-               case 0x20:
+               if (($c = ord($s[$Sp])) === 0x20 ||
+                   $c === 0x0A || $c === 0x09 || $c === 0x0D)
                        ++$Sp;
-               }
+               else
+                       return $c;
+       return -1;
 }
 
 function minijson_decode_array($s, &$Sp, $Sx, &$ov, $depth) {
        $ov = array();
 
        /* skip optional whitespace between tokens */
-       minijson_skip_wsp($s, $Sp, $Sx);
+       $c = minijson_skip_wsp($s, $Sp, $Sx);
 
        /* check for end of array or first member */
-       if ($Sp >= $Sx) {
- minijson_decode_array_eos:
-               $ov = 'unexpected EOS in Array';
-               return false;
-       }
-       switch ($s[$Sp]) {
-       case ',':
-               $ov = 'unexpected leading comma in Array';
-               return false;
-       case ']':
+       if ($c === 0x5D) {
                ++$Sp;
                return true;
+       } elseif ($c === -1) {
+               $ov = 'unexpected EOS after ['/*]*/;
+               return false;
        }
 
-       goto minijson_decode_array_member;
-
- minijson_decode_array_loop:
-       /* skip optional whitespace between tokens */
-       minijson_skip_wsp($s, $Sp, $Sx);
+       while (true) {
+               /* parse the member value */
+               $v = NULL;
+               if (!minijson_decode_value($s, $Sp, $Sx, $v, $depth)) {
+                       /* pass through error code */
+                       $ov = $v;
+                       return false;
+               }
+               /* consume, rinse, repeat */
+               $ov[] = $v;
 
-       /* check for end of array or next member */
-       if ($Sp >= $Sx)
-               goto minijson_decode_array_eos;
-       switch ($s[$Sp++]) {
-       case ']':
-               return true;
-       case ',':
-               break;
-       default:
-               --$Sp;
-               $ov = 'missing comma in Array';
-               return false;
-       }
+               /* skip optional whitespace between tokens */
+               $c = minijson_skip_wsp($s, $Sp, $Sx);
 
- minijson_decode_array_member:
-       /* parse the member value */
-       $v = NULL;
-       if (!minijson_decode_value($s, $Sp, $Sx, $v, $depth)) {
-               /* pass through error code */
-               $ov = $v;
-               return false;
+               /* check for end of array or next member */
+               if ($c === 0x2C) {
+                       ++$Sp;
+               } elseif ($c === 0x5D) {
+                       ++$Sp;
+                       return true;
+               } else {
+                       $ov = /*[*/'comma (,) or ] expected';
+                       return false;
+               }
        }
-       /* consume, rinse, repeat */
-       $ov[] = $v;
-       goto minijson_decode_array_loop;
 }
 
 function minijson_decode_object($s, &$Sp, $Sx, &$ov, $depth) {
        $ov = array();
        /* skip optional whitespace between tokens */
-       minijson_skip_wsp($s, $Sp, $Sx);
+       $c = minijson_skip_wsp($s, $Sp, $Sx);
 
        /* check for end of object or first member */
-       if ($Sp >= $Sx) {
- minijson_decode_object_eos:
-               $ov = 'unexpected EOS in Object';
-               return false;
-       }
-       switch ($s[$Sp]) {
-       case ',':
-               $ov = 'unexpected leading comma in Object';
-               return false;
-       case '}':
+       if ($c === 0x7D) {
                ++$Sp;
                return true;
+       } elseif ($c === -1) {
+               $ov = 'unexpected EOS after {'/*}*/;
+               return false;
        }
 
-       goto minijson_decode_object_member;
+       while (true) {
+               /* skip optional whitespace between tokens */
+               $c = minijson_skip_wsp($s, $Sp, $Sx);
 
- minijson_decode_object_loop:
-       /* skip optional whitespace between tokens */
-       minijson_skip_wsp($s, $Sp, $Sx);
-
-       /* check for end of object or next member */
-       if ($Sp >= $Sx)
-               goto minijson_decode_object_eos;
-       switch ($s[$Sp++]) {
-       case '}':
-               return true;
-       case ',':
-               break;
-       default:
-               --$Sp;
-               $ov = 'missing comma in Object';
-               return false;
-       }
+               /* look for the member key */
+               if ($c !== 0x22) {
+                       $ov = 'key string for Object member expected';
+                       return false;
+               }
+               ++$Sp;
+               if (($k = minijson_decode_string($s, $Sp, $Sx)) !== true) {
+                       ob_end_clean();
+                       /* pass through error code */
+                       $ov = $k;
+                       return false;
+               }
+               $k = ob_get_clean();
 
- minijson_decode_object_member:
-       /* skip optional whitespace between tokens */
-       minijson_skip_wsp($s, $Sp, $Sx);
+               /* skip optional whitespace between tokens */
+               $c = minijson_skip_wsp($s, $Sp, $Sx);
 
-       /* look for the member key */
-       if ($Sp >= $Sx)
-               goto minijson_decode_object_eos;
-       if ($s[$Sp++] !== '"') {
-               --$Sp;
-               $ov = 'expected key string for Object member';
-               return false;
-       }
-       if (($k = minijson_decode_string($s, $Sp, $Sx)) !== true) {
-               ob_end_clean();
-               /* pass through error code */
-               $ov = $k;
-               return false;
-       }
-       $k = ob_get_clean();
+               /* check for separator between key and value */
+               if ($c !== 0x3A) {
+                       $ov = 'colon (:) expected';
+                       return false;
+               }
+               ++$Sp;
 
-       /* skip optional whitespace between tokens */
-       minijson_skip_wsp($s, $Sp, $Sx);
+               /* parse the member value */
+               $v = NULL;
+               if (!minijson_decode_value($s, $Sp, $Sx, $v, $depth)) {
+                       /* pass through error code */
+                       $ov = $v;
+                       return false;
+               }
+               /* consume, rinse, repeat */
+               $ov[$k] = $v;
 
-       /* check for separator between key and value */
-       if ($Sp >= $Sx)
-               goto minijson_decode_object_eos;
-       if ($s[$Sp++] !== ':') {
-               --$Sp;
-               $ov = 'expected colon in Object member';
-               return false;
-       }
+               /* skip optional whitespace between tokens */
+               $c = minijson_skip_wsp($s, $Sp, $Sx);
 
-       /* parse the member value */
-       $v = NULL;
-       if (!minijson_decode_value($s, $Sp, $Sx, $v, $depth)) {
-               /* pass through error code */
-               $ov = $v;
-               return false;
+               /* check for end of object or next member */
+               if ($c === 0x2C) {
+                       ++$Sp;
+               } elseif ($c === 0x7D) {
+                       ++$Sp;
+                       return true;
+               } else {
+                       $ov = /*{*/'comma (,) or } expected';
+                       return false;
+               }
        }
-       /* consume, rinse, repeat */
-       $ov[$k] = $v;
-       goto minijson_decode_object_loop;
 }
 
 function minijson_decode_value($s, &$Sp, $Sx, &$ov, $depth) {
        /* skip optional whitespace between tokens */
-       minijson_skip_wsp($s, $Sp, $Sx);
-
-       /* parse begin of Value token */
-       if ($Sp >= $Sx) {
-               $ov = 'unexpected EOS, Value expected';
-               return false;
-       }
-       $c = $s[$Sp++];
+       $c = minijson_skip_wsp($s, $Sp, $Sx);
 
-       /* style: falling through exits with false */
-       if ($c === 'n') {
+       /* parse start of Value token; falling through exits with false */
+       if ($c === 0x22) {
+               ++$Sp;
+               if (($ov = minijson_decode_string($s, $Sp, $Sx)) !== true) {
+                       ob_end_clean();
+                       return false;
+               }
+               $ov = ob_get_clean();
+               return true;
+       } elseif ($c === 0x7B) {
+               if (--$depth > 0) {
+                       ++$Sp;
+                       return minijson_decode_object($s, $Sp, $Sx, $ov, 
$depth);
+               }
+               $ov = 'recursion limit exceeded by Object';
+       } elseif ($c === 0x5B) {
+               if (--$depth > 0) {
+                       ++$Sp;
+                       return minijson_decode_array($s, $Sp, $Sx, $ov, $depth);
+               }
+               $ov = 'recursion limit exceeded by Array';
+       } elseif ($c <= 0x39 && ($c >= 0x30 || $c === 0x2D)) {
+               return minijson_decode_number($s, $Sp, $Sx, $ov);
+       } elseif ($c === 0x6E) {
                /* literal null? */
-               if (substr($s, $Sp, 3) === 'ull') {
-                       $Sp += 3;
+               if (substr_compare($s, 'null', $Sp, 4) === 0) {
+                       $Sp += 4;
                        $ov = NULL;
                        return true;
                }
-               --$Sp;
-               $ov = 'expected “ull” after “n”';
-       } elseif ($c === 't') {
+               $ov = 'after “n”, “ull” expected';
+       } elseif ($c === 0x74) {
                /* literal true? */
-               if (substr($s, $Sp, 3) === 'rue') {
-                       $Sp += 3;
+               if (substr_compare($s, 'true', $Sp, 4) === 0) {
+                       $Sp += 4;
                        $ov = true;
                        return true;
                }
-               --$Sp;
-               $ov = 'expected “rue” after “t”';
-       } elseif ($c === 'f') {
+               $ov = 'after “t”, “rue” expected';
+       } elseif ($c === 0x66) {
                /* literal false? */
-               if (substr($s, $Sp, 4) === 'alse') {
-                       $Sp += 4;
+               if (substr_compare($s, 'false', $Sp, 5) === 0) {
+                       $Sp += 5;
                        $ov = false;
                        return true;
                }
-               --$Sp;
-               $ov = 'expected “alse” after “f”';
-       } elseif ($c === '[') {
-               if (--$depth > 0)
-                       return minijson_decode_array($s, $Sp, $Sx, $ov, $depth);
-               --$Sp;
-               $ov = 'recursion limit exceeded by Array';
-       } elseif ($c === '{') {
-               if (--$depth > 0)
-                       return minijson_decode_object($s, $Sp, $Sx, $ov, 
$depth);
-               --$Sp;
-               $ov = 'recursion limit exceeded by Object';
-       } elseif ($c === '"') {
-               if (($ov = minijson_decode_string($s, $Sp, $Sx)) !== true) {
-                       ob_end_clean();
-                       return false;
-               }
-               $ov = ob_get_clean();
-               return true;
-       } elseif ($c === '-' || (ord($c) >= 0x30 && ord($c) <= 0x39)) {
-               --$Sp;
-               return minijson_decode_number($s, $Sp, $Sx, $ov);
-       } elseif (ord($c) >= 0x20 && ord($c) <= 0x7E) {
-               --$Sp;
-               $ov = "unexpected “{$c}”, Value expected";
+               $ov = 'after “f”, “alse” expected';
+       } elseif ($c <= 0x7E && $c >= 0x20) {
+               $ov = 'unexpected “' . chr($c) . '”, Value expected';
+       } elseif ($c !== -1) {
+               $ov = sprintf('unexpected 0x%02X, Value expected', $c);
        } else {
-               --$Sp;
-               $ov = sprintf('unexpected 0x%02X, Value expected', ord($c));
+               $ov = 'unexpected EOS, Value expected';
        }
        return false;
 }
 
 function minijson_decode_string($s, &$Sp, $Sx) {
        ob_start();
- minijson_decode_string_loop:
-       if ($Sp >= $Sx)
-               return 'unexpected EOS in String';
-       /* get next octet; switch on what to do with it */
-       if (($ch = $s[$Sp++]) === '"') {
-               /* regular exit point for the loop */
-               return true;
-       }
-       /* backslash escape? */
-       if ($ch === "\\") {
-               if ($Sp >= $Sx)
-                       return 'unexpected EOS after backslash in String';
-               $ch = $s[$Sp++];
-               if ($ch === '"' || $ch === '/' || $ch === "\\")
-                       echo $ch;
-               elseif ($ch === 't')
-                       echo "\x09";
-               elseif ($ch === 'n')
-                       echo "\x0A";
-               elseif ($ch === 'r')
-                       echo "\x0D";
-               elseif ($ch === 'b')
-                       echo "\x08";
-               elseif ($ch === 'f')
-                       echo "\x0C";
-               elseif ($ch !== 'u') {
-                       $Sp -= 2;
-                       return "invalid escape '\\$ch' in String";
-               } else {
-                       $surrogate = 0;
- minijson_decode_string_unicode_escape:
-                       $wc = 0;
-                       if ($Sp + 4 > $Sx) {
+       while ($Sp < $Sx) {
+               /* get next octet; switch on what to do with it */
+               if (($c = ord(($ch = $s[$Sp++]))) === 0x22) {
+                       /* regular exit point for the loop */
+                       return true;
+               }
+               /* backslash escape? */
+               if ($c === 0x5C) {
+                       if ($Sp >= $Sx)
+                               return 'incomplete escape sequence';
+                       $c = ord(($ch = $s[$Sp++]));
+                       if ($c === 0x22 || $c === 0x5C || $c === 0x2F)
+                               echo $ch;
+                       elseif ($c === 0x74)
+                               echo "\x09";
+                       elseif ($c === 0x6E)
+                               echo "\x0A";
+                       elseif ($c === 0x75) {
+                               $c = minijson_decode_uescape($s, $Sp, $Sx, $ch);
+                               if ($c >= 0xD800 && $c <= 0xDFFF)
+                                       $c = minijson_decode_surrogate($s, $Sp,
+                                           $Sx, $c, $ch);
+                               if ($c === 0)
+                                       return $ch;
+                               if ($c < 0x80)
+                                       echo chr($c);
+                               elseif ($c < 0x0800)
+                                       echo chr(0xC0 | ($c >> 6)) .
+                                           chr(0x80 | ($c & 0x3F));
+                               elseif ($c <= 0xFFFF)
+                                       echo chr(0xE0 | ($c >> 12)) .
+                                           chr(0x80 | (($c >> 6) & 0x3F)) .
+                                           chr(0x80 | ($c & 0x3F));
+                               else
+                                       echo chr(0xF0 | ($c >> 18)) .
+                                           chr(0x80 | (($c >> 12) & 0x3F)) .
+                                           chr(0x80 | (($c >> 6) & 0x3F)) .
+                                           chr(0x80 | ($c & 0x3F));
+                       } elseif ($c === 0x72)
+                               echo "\x0D";
+                       elseif ($c === 0x62)
+                               echo "\x08";
+                       elseif ($c === 0x66)
+                               echo "\x0C";
+                       else {
                                $Sp -= 2;
-                               return 'unexpected EOS in Unicode escape 
sequence';
+                               return "invalid escape sequence “\\{$ch}”";
                        }
-                       for ($tmp = 1; $tmp <= 4; $tmp++) {
-                               $wc <<= 4;
-                               switch (ord($s[$Sp++])) {
-                               case 0x30:                         break;
-                               case 0x31:              $wc +=  1; break;
-                               case 0x32:              $wc +=  2; break;
-                               case 0x33:              $wc +=  3; break;
-                               case 0x34:              $wc +=  4; break;
-                               case 0x35:              $wc +=  5; break;
-                               case 0x36:              $wc +=  6; break;
-                               case 0x37:              $wc +=  7; break;
-                               case 0x38:              $wc +=  8; break;
-                               case 0x39:              $wc +=  9; break;
-                               case 0x41: case 0x61:   $wc += 10; break;
-                               case 0x42: case 0x62:   $wc += 11; break;
-                               case 0x43: case 0x63:   $wc += 12; break;
-                               case 0x44: case 0x64:   $wc += 13; break;
-                               case 0x45: case 0x65:   $wc += 14; break;
-                               case 0x46: case 0x66:   $wc += 15; break;
-                               default:
-                                       --$Sp;
-                                       return "invalid hex digit #$tmp/4 in 
Unicode escape sequence";
-                               }
+                       continue;
+               }
+               echo $ch;
+               if ($c < 0x80) {
+                       if ($c >= 0x20)
+                               continue;
+                       --$Sp;
+                       return sprintf('unexpected C0 control 0x%02X', $c);
+               }
+               /* UTF-8 BMP sequence (unrolled) */
+               if ($c < 0xE0) {
+                       if ($c < 0xC2) {
+                               --$Sp;
+                               return sprintf('invalid UTF-8 lead octet 
0x%02X',
+                                   $c);
                        }
-                       if ($surrogate) {
-                               if ($wc < 0xDC00 || $wc > 0xDFFF) {
-                                       $Sp -= 6;
-                                       return sprintf('expected low surrogate, 
not %04X, after high surrogate %04X', $wc, $surrogate);
-                               }
-                               $wc = 0x10000 + (($surrogate & 0x03FF) << 10) + 
($wc & 0x03FF);
-                       } elseif ($wc >= 0xD800 && $wc <= 0xDBFF) {
-                               $surrogate = $wc;
-                               /* UTF-16 expects the low surrogate */
-                               if (substr($s, $Sp, 2) !== '\u')
-                                       return 'expected Unicode escape after 
high surrogate';
-                               $Sp += 2;
-                               goto minijson_decode_string_unicode_escape;
-                       } elseif ($wc >= 0xDC00 && $wc <= 0xDFFF) {
-                               $Sp -= 6;
-                               return sprintf('loose low surrogate %04X', $wc);
-                       } elseif ($wc < 1 || $wc > 0xFFFD) {
-                               $Sp -= 6;
-                               return sprintf('non-Unicode escape %04X', $wc);
+                       if ($Sp + 1 > $Sx) {
+                               --$Sp;
+                               return 'incomplete UTF-8 sequence';
                        }
-                       if ($wc < 0x80) {
-                               echo chr($wc);
-                               goto minijson_decode_string_loop;
+                       if (($c = ord(($ch = $s[$Sp++])) ^ 0x80) > 0x3F) {
+                               --$Sp;
+                               return sprintf('invalid UTF-8 trail octet 
0x%02X',
+                                   $c ^ 0x80);
                        }
- minijson_decode_string_unicode_char:
-                       if ($wc < 0x0800)
-                               echo chr(0xC0 | ($wc >> 6)) .
-                                   chr(0x80 | ($wc & 0x3F));
-                       elseif ($wc <= 0xFFFF)
-                               echo chr(0xE0 | ($wc >> 12)) .
-                                   chr(0x80 | (($wc >> 6) & 0x3F)) .
-                                   chr(0x80 | ($wc & 0x3F));
-                       else
-                               echo chr(0xF0 | ($wc >> 18)) .
-                                   chr(0x80 | (($wc >> 12) & 0x3F)) .
-                                   chr(0x80 | (($wc >> 6) & 0x3F)) .
-                                   chr(0x80 | ($wc & 0x3F));
+                       echo $ch;
+                       continue;
+               } elseif ($c >= 0xF0) {
+                       --$Sp;
+                       return sprintf('invalid UTF-8 lead octet 0x%02X', $c);
+               }
+               if ($Sp + 2 > $Sx) {
+                       --$Sp;
+                       return 'incomplete UTF-8 sequence';
                }
-               goto minijson_decode_string_loop;
-       }
-       if (($c = ord($ch)) < 0x20) {
-               --$Sp;
-               return sprintf('unescaped control character 0x%02X in String', 
$c);
-       }
-       if ($c < 0x80) {
-               echo $ch;
-               goto minijson_decode_string_loop;
-       }
-       /* decode UTF-8 */
-       if ($c < 0xC2 || $c >= 0xF0) {
-               --$Sp;
-               return sprintf('invalid UTF-8 lead octet 0x%02X in String', $c);
-       }
-       if ($c < 0xE0) {
-               $wc = ($c & 0x1F) << 6;
-               $wmin = 0x80; /* redundant */
-               $Ss = 1;
-       } else {
                $wc = ($c & 0x0F) << 12;
-               $wmin = 0x800;
-               $Ss = 2;
-       }
-       if ($Sp + $Ss > $Sx) {
-               --$Sp;
-               return 'unexpected EOS after UTF-8 lead byte in String';
-       }
-       while ($Ss--)
-               if (($c = ord($s[$Sp++]) ^ 0x80) <= 0x3F)
-                       $wc |= $c << (6 * $Ss);
-               else {
+               if (($c = ord(($ch = $s[$Sp++])) ^ 0x80) <= 0x3F) {
+                       $wc |= $c << 6;
+                       echo $ch;
+               } else {
+                       --$Sp;
+                       return sprintf('invalid UTF-8 trail octet 0x%02X',
+                           $c ^ 0x80);
+               }
+               if (($c = ord(($ch = $s[$Sp++])) ^ 0x80) <= 0x3F) {
+                       $wc |= $c;
+                       echo $ch;
+               } else {
                        --$Sp;
-                       return sprintf('invalid UTF-8 trail octet 0x%02X in 
String', $c ^ 0x80);
+                       return sprintf('invalid UTF-8 trail octet 0x%02X',
+                           $c ^ 0x80);
+               }
+               if ($wc < 0x0800) {
+                       $Sp -= 3;
+                       return sprintf('non-minimal encoding for %04X', $wc);
+               }
+               if ($wc >= 0xD800 && $wc <= 0xDFFF) {
+                       $Sp -= 3;
+                       return sprintf('unescaped surrogate %04X', $wc);
+               }
+               if ($wc > 0xFFFD) {
+                       $Sp -= 3;
+                       return sprintf('unescaped non-character %04X', $wc);
                }
-       if ($wc < $wmin) {
-               $Sp -= 3; /* only for E0‥EF-led sequence */
-               return sprintf('non-minimalistic encoding for Unicode char %04X 
in String', $wc);
        }
+       return 'unexpected EOS in String';
+}
 
-       if ($wc >= 0xD800 && $wc <= 0xDFFF) {
-               $Sp -= 3;
-               return sprintf('unescaped surrogate %04X in String', $wc);
+/* decodes the four nybbles after “\u” */
+function minijson_decode_uescape($s, &$Sp, $Sx, &$e) {
+       if ($Sp + 4 > $Sx) {
+               $Sp -= 2;
+               $e = 'incomplete escape sequence';
+               return 0;
+       }
+       $wc = 0;
+       for ($tmp = 1; $tmp <= 4; $tmp++) {
+               $wc <<= 4;
+               switch (ord($s[$Sp++])) {
+               case 0x30:                         break;
+               case 0x31:              $wc +=  1; break;
+               case 0x32:              $wc +=  2; break;
+               case 0x33:              $wc +=  3; break;
+               case 0x34:              $wc +=  4; break;
+               case 0x35:              $wc +=  5; break;
+               case 0x36:              $wc +=  6; break;
+               case 0x37:              $wc +=  7; break;
+               case 0x38:              $wc +=  8; break;
+               case 0x39:              $wc +=  9; break;
+               case 0x41: case 0x61:   $wc += 10; break;
+               case 0x42: case 0x62:   $wc += 11; break;
+               case 0x43: case 0x63:   $wc += 12; break;
+               case 0x44: case 0x64:   $wc += 13; break;
+               case 0x45: case 0x65:   $wc += 14; break;
+               case 0x46: case 0x66:   $wc += 15; break;
+               default:
+                       --$Sp;
+                       $e = 'hexadecimal digit expected';
+                       return 0;
+               }
        }
-       if ($wc <= 0xFFFD)
-               goto minijson_decode_string_unicode_char;
-       $Sp -= 3;
-       return sprintf('non-Unicode char %04X in String', $wc);
+       if ($wc < 1 || $wc > 0xFFFD) {
+               $Sp -= 6;
+               $e = sprintf('invalid escape \\u%04X', $wc);
+               return 0;
+       }
+       return $wc;
+}
+
+/* called if decoding the above resulted in a surrogate */
+function minijson_decode_surrogate($s, &$Sp, $Sx, $wc, &$e) {
+       /* loose low surrogate? */
+       if ($wc >= 0xDC00) {
+               $Sp -= 6;
+               $e = sprintf('unexpected low surrogate \\u%04X', $wc);
+               return 0;
+       }
+       /* wc is a high surrogate */
+       if ($Sp + 6 > $Sx || $s[$Sp] !== '\\' || $s[$Sp + 1] !== 'u') {
+               $e = 'escaped low surrogate expected';
+               return 0;
+       }
+       $Sp += 2;
+       if (($lc = minijson_decode_uescape($s, $Sp, $Sx, $e)) === 0)
+               return 0;
+       if ($lc < 0xDC00 || $lc > 0xDFFF) {
+               $Sp -= 6;
+               $e = sprintf('unexpected \\u%04X, low surrogate expected', $lc);
+               return 0;
+       }
+       return 0x10000 + (($wc & 0x03FF) << 10) + ($lc & 0x03FF);
 }
 
 function minijson_decode_number($s, &$Sp, $Sx, &$ov) {
        $matches = array('');
        if 
(!preg_match('/-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[Ee][+-]?[0-9]+)?/A',
-           $s, $matches, 0, $Sp) || strlen($matches[0]) < 1) {
-               $ov = 'expected Number';
+           $s, $matches, 0, $Sp) || ($Ss = strlen($matches[0])) < 1) {
+               $ov = 'Number expected';
+               return false;
+       }
+       if ($Sp + $Ss > $Sx) {
+               $ov = 'unexpected EOS in Number';
                return false;
        }
-       $Sp += strlen($matches[0]);
+       $Sp += $Ss;
        if (strpos($matches[0], '.') === false) {
                /* possible integer */
                $ov = (int)$matches[0];
diff --git a/tests/unit/common/minijsonTest.php 
b/tests/unit/common/minijsonTest.php
index 3857e1f..24f733e 100644
--- a/tests/unit/common/minijsonTest.php
+++ b/tests/unit/common/minijsonTest.php
@@ -25,14 +25,17 @@
  */
 
 require_once('PHPUnit/Framework/TestCase.php');
-require_once(dirname(__FILE__) . '/../../../src/common/include/minijson.php');
 
 class Minijson_Tests extends PHPUnit\Framework\TestCase {
+       public function testMiniJson() {
+               $s = error_reporting(-1);
+               require_once(dirname(__FILE__) . 
'/../../../src/common/include/minijson.php');
+
        /****************************************************************/
        /* $s_orig [parse] print_r->$s_printr [encode] $s_ecompact or 
$s_epadded */
        /* $s_e* [decode] print_r ->$s_printrs (due to Object key sorting) */
 
-       var $s_orig = '[
+       $s_orig = '[
     "JSON Test Pattern pass1",
     {"object with 1 member":["array with 1 element"]},
     {},
@@ -91,7 +94,7 @@ class Minijson_Tests extends PHPUnit\Framework\TestCase {
 1e00,2e+00,2e-00
 ,"rosebud"]';
 
-       var $s_printr = 'Array
+       $s_printr = 'Array
 (
     [0] => JSON Test Pattern pass1
     [1] => Array
@@ -127,8 +130,7 @@ class Minijson_Tests extends PHPUnit\Framework\TestCase {
             [space] =>  ' . '
             [quote] => "
             [backslash] => \\
-            [controls] => ' . '
-
        ' . '
+            [controls] => ' . "\x08\x0C\x0A\x0D\x09" . '
             [slash] => / & /
             [alpha] => abcdefghijklmnopqrstuvwyz
             [ALPHA] => ABCDEFGHIJKLMNOPQRSTUVWYZ
@@ -175,8 +177,7 @@ class Minijson_Tests extends PHPUnit\Framework\TestCase {
 
             [jsontext] => {"object with 1 member":["array with 1 element"]}
             [quotes] => &#34; " %22 0x22 034 &#x22;
-            [/\\"쫾몾ꮘﳞ볚' . '
-
        `1~!@#$%^&*()_+-=[]{}|;:\',./<>?] => A key can be any string
+            [/\\"쫾몾ꮘﳞ볚' . "\x0A\x0D\x09" . 
'`1~!@#$%^&*()_+-=[]{}|;:\',./<>?] => A key can be any string
         )
 
     [9] => 0.5
@@ -193,7 +194,7 @@ class Minijson_Tests extends PHPUnit\Framework\TestCase {
 )
 ';
 
-       var $s_printrs = 'Array
+       $s_printrs = 'Array
 (
     [0] => JSON Test Pattern pass1
     [1] => Array
@@ -232,8 +233,7 @@ class Minijson_Tests extends PHPUnit\Framework\TestCase {
                 )
 
             [# -- --> */] =>  ' . '
-            [/\\"쫾몾ꮘﳞ볚' . '
-
        `1~!@#$%^&*()_+-=[]{}|;:\',./<>?] => A key can be any string
+            [/\\"쫾몾ꮘﳞ볚' . "\x08\x0C\x0A\x0D\x09" . 
'`1~!@#$%^&*()_+-=[]{}|;:\',./<>?] => A key can be any string
             [0123456789] => digit
             [ALPHA] => ABCDEFGHIJKLMNOPQRSTUVWYZ
             [E] => 1.23456789E+34
@@ -256,8 +256,7 @@ class Minijson_Tests extends PHPUnit\Framework\TestCase {
                     [6] => 7
                 )
 
-            [controls] => ' . '
-
        ' . '
+            [controls] => ' . "\x08\x0C\x0A\x0D\x09" . '
             [digit] => 0123456789
             [e] => 1.23456789E-13
             [false] => ' . '
@@ -295,8 +294,8 @@ class Minijson_Tests extends PHPUnit\Framework\TestCase {
 )
 ';
 
-       var $s_ecompact = '["JSON Test Pattern pass1",{"object with 1 
member":["array with 1 
element"]},[],[],-42,true,false,null,{"":2.3456789012E+76," s p a c e d 
":[1,2,3,4,5,6,7],"# -- --> */":" 
","/\\\\\\"쫾몾ꮘﳞ볚\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?":"A key can be 
any 
string","0123456789":"digit","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","E":1.23456789E+34,"address":"50
 St. James 
Street","alpha":"abcdefghijklmnopqrstuvwyz","array":[],"backslash":"\\\\","comment":"//
 /* <!-- 
--","compact":[1,2,3,4,5,6,7],"controls":"\\b\\f\\n\\r\\t","digit":"0123456789","e":1.23456789E-13,"false":false,"hex":"ģ䕧覫췯ꯍ","integer":1234567890,"jsontext":"{\\"object
 with 1 member\\":[\\"array with 1 
element\\"]}","null":null,"object":[],"one":1,"quote":"\\"","quotes":"&#34; \\" 
%22 0x22 034 &#x22;","real":-9.87654321E+3,"slash":"/ & /","space":" 
","special":"`1~!@#$%^&*()_+-={\':[,]}|;.</>?","true":true,"url":"http://www.JSON.org/","zero":0},5.0E-1,9.86E+1,9.944E+1,1066,1.0E+1,1.0,1.0E-1,1.0,2.0,2.0,"rosebud";]';
-       var $s_epadded = '[
+       $s_ecompact = '["JSON Test Pattern pass1",{"object with 1 
member":["array with 1 
element"]},[],[],-42,true,false,null,{"":2.3456789012E+76," s p a c e d 
":[1,2,3,4,5,6,7],"# -- --> */":" 
","/\\\\\\"쫾몾ꮘﳞ볚\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?":"A key can be 
any 
string","0123456789":"digit","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","E":1.23456789E+34,"address":"50
 St. James 
Street","alpha":"abcdefghijklmnopqrstuvwyz","array":[],"backslash":"\\\\","comment":"//
 /* <!-- 
--","compact":[1,2,3,4,5,6,7],"controls":"\\b\\f\\n\\r\\t","digit":"0123456789","e":1.23456789E-13,"false":false,"hex":"ģ䕧覫췯ꯍ","integer":1234567890,"jsontext":"{\\"object
 with 1 member\\":[\\"array with 1 
element\\"]}","null":null,"object":[],"one":1,"quote":"\\"","quotes":"&#34; \\" 
%22 0x22 034 &#x22;","real":-9.87654321E+3,"slash":"/ & /","space":" 
","special":"`1~!@#$%^&*()_+-={\':[,]}|;.</>?","true":true,"url":"http://www.JSON.org/","zero":0},5.0E-1,9.86E+1,9.944E+1,1066,1.0E+1,1.0,1.0E-1,1.0,2.0,2.0,"rosebud";]';
+       $s_epadded = '[
   "JSON Test Pattern pass1",
   {
     "object with 1 member": [
@@ -374,33 +373,40 @@ class Minijson_Tests extends PHPUnit\Framework\TestCase {
 
 /****************************************************************/
 
-       public function testMiniJson() {
                $parsed = 'bla';
-               $presult = minijson_decode($this->s_orig, $parsed);
+               $presult = minijson_decode($s_orig, $parsed);
                $this->assertTrue($presult);
                $this->assertEquals('array', gettype($parsed), 'FAIL 
parse-basic');
 
                $printrd = print_r($parsed, true);
-               $this->assertEquals($this->s_printr, $printrd, 'parsed');
+               $this->assertEquals($s_printr, $printrd, 'parsed');
 
                $encoded = minijson_encode($parsed, false);
-               $this->assertEquals($this->s_ecompact, $encoded, 
'encode-compact');
+               $this->assertEquals($s_ecompact, $encoded, 'encode-compact');
                $reparsed = 'bla';
                $presult = minijson_decode($encoded, $reparsed);
                $this->assertTrue($presult, 'can-reparse-compact');
                $this->assertEquals('array', gettype($reparsed), 'FAIL 
reparse-compact-basic');
 
                $printrd = print_r($reparsed, true);
-               $this->assertEquals($this->s_printrs, $printrd, 
'reparsed-compact');
+               $this->assertEquals($s_printrs, $printrd, 'reparsed-compact');
 
                $encoded = minijson_encode($parsed);
-               $this->assertEquals($this->s_epadded, $encoded, 
'encode-padded');
+               $this->assertEquals($s_epadded, $encoded, 'encode-padded');
                $reparsed = 'bla';
                $presult = minijson_decode($encoded, $reparsed);
                $this->assertTrue($presult, 'can-reparse-padded');
                $this->assertEquals('array', gettype($reparsed), 'FAIL 
reparse-padded-basic');
 
                $printrd = print_r($reparsed, true);
-               $this->assertEquals($this->s_printrs, $printrd, 
'reparsed-padded');
+               $this->assertEquals($s_printrs, $printrd, 'reparsed-padded');
+
+               $encoded = '0';
+               $reparsed = 'bla';
+               $presult = minijson_decode($encoded, $reparsed);
+               $this->assertTrue($presult, 'can-parse-0');
+               $this->assertEquals(0, $reparsed);
+
+               error_reporting($s);
        }
 }

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=54dcb9ce9d6f266f591613e1844670fa6e8a77c0

commit 54dcb9ce9d6f266f591613e1844670fa6e8a77c0
Merge: 1db485d d53aeb1
Author: mirabilos <[email protected]>
Date:   Thu Jun 11 03:45:24 2020 +0200

    Update post-receive-email to latest version
    
    • fix typos
    • enable UTF-8 filenames in output; from an IRC question by madduck
    • rework Subject header encoding to be more reliable
      (this merges the FusionForge-local change to prefer PHP over Perl)
    • detect whether git rev-list actually outputted anything;
      issue a "no new revisions added by this update" message if not
    • sort out logs in eMails when multiple branches are pushed at once
    • diff showing in branch creation mail (with empty-tree even on new 
histories)
    • update header
    • move to C.UTF-8 from en_US.UTF-8 (more widespread by now)
    • update list of requirements to include cURL; indicate PHP preference
      (cURL is only needed if curlhooks are used, of course)
    • indicate multiple recipients convention
      elaborate more on one vs. multiple addresses
    • skip diff if no new revisions
    • attempt to clean up the first eMail paragraph a little
    
    Merge branch 'standalone' of 
git+ssh://evolvis.org/scmrepos/git/evolvis-platfrm/recvhook


https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=d53aeb132ba88cb42a0514ec3f8c83cfd27ab2b1

commit d53aeb132ba88cb42a0514ec3f8c83cfd27ab2b1
Author: mirabilos <[email protected]>
Date:   Sat May 9 18:06:31 2020 +0200

    attempt to clean up the first eMail paragraph a little

diff --git a/post-receive-email b/post-receive-email
index 38f6cac..abde17e 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -1,11 +1,13 @@
 #!/bin/mksh
 #
+# Copyright © 2016, 2020
+#      mirabilos <[email protected]>
 # Copyright © 2013
 #      Thorsten “mirabilos” Glaser <[email protected]>
 # Copyright © 2011, 2012, 2013, 2014, 2015, 2018, 2019
 #      Thorsten “mirabilos” Glaser <[email protected]>
 # Copyright © 2016
-#      martin f krafft (madduck), Thorsten Glaser (mirabilos)
+#      martin f krafft (madduck)
 #
 # Copyright (c) 2007 Andy Parkins
 #
@@ -288,6 +290,7 @@ generate_email()
 generate_email_header()
 {
        local routing_headers subj senc failc=0
+       local repolabel
 
        # --- Email (all stdout will be the email)
        # Generate header
@@ -330,6 +333,12 @@ generate_email_header()
                senc="Subject: post-receive-email: no Subject, RFC2047 MIME 
encoding failed"
        fi
 
+       if [[ $shortdesc = "$projectdesc" ]]; then
+               repolabel=$PWD
+       else
+               repolabel=$shortdesc
+       fi
+
        cat <<-EOF
        MIME-Version: 1.0
        Content-Type: text/plain; charset=UTF-8
@@ -342,9 +351,10 @@ generate_email_header()
        $senc
        Auto-Submitted: auto-generated
 
-       This is an automated email from the git hooks/post-receive script. It 
was
-       generated because a ref change was pushed to the repository containing
-       the project "$projectdesc".
+       This is an automated email from the git hooks/post-receive script.
+       It was generated because a ref change was pushed to the repository
+       "$repolabel" containing the project
+       "$projectdesc".
 
        The $refname_type, $short_refname has been ${change_type}d
        EOF

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=a9d53b2c9c5c7ebf89da0ed82e8a5107b041f5d9

commit a9d53b2c9c5c7ebf89da0ed82e8a5107b041f5d9
Author: mirabilos <[email protected]>
Date:   Mon Nov 11 00:14:41 2019 +0100

    skip diff if no new revisions

diff --git a/post-receive-email b/post-receive-email
index c5ccc28..38f6cac 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -551,19 +551,20 @@ generate_update_branch_email()
        [[ -n $rewind_only ]] || newrevs=$(show_new_revisions)
 
        echo ""
-       if [[ -n $newrevs ]]; then
-               echo "Those revisions listed above that are new to this 
repository have"
-               echo "not appeared on any other notification email; so we list 
those"
-               echo "revisions in full, below."
-
-               echo ""
-               echo $LOGBEGIN
-               print -r -- "$newrevs"
-               echo $LOGEND
-       else
+       if [[ -z $newrevs ]]; then
                echo "No new revisions were added by this update."
+               return 0
        fi
 
+       echo "Those revisions listed above that are new to this repository have"
+       echo "not appeared on any other notification email; so we list those"
+       echo "revisions in full, below."
+
+       echo ""
+       echo $LOGBEGIN
+       print -r -- "$newrevs"
+       echo $LOGEND
+
        # The diffstat is shown from the old revision to the new revision.
        # This is to show the truth of what happened in this change.
        # There's no point showing the stat from the base to the new

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=d61575c6c0ba5f80d371a6a74f762fd4a32a96ff

commit d61575c6c0ba5f80d371a6a74f762fd4a32a96ff
Author: mirabilos <[email protected]>
Date:   Fri Jan 25 18:08:06 2019 +0100

    elaborate more on one vs. multiple addresses

diff --git a/post-receive-email b/post-receive-email
index a8c2b46..c5ccc28 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -70,10 +70,10 @@
 #   it blank to default to the mailinglist field. The announce emails list
 #   the short log summary of the changes since the last annotated tag.
 # hooks.replyto
-#   If set, replies are requested to be directed to this eMail address.
+#   If set, replies are requested to be directed to this eMail address(es).
 # hooks.envelopesender
 #   If set then the -f option is passed to sendmail to allow the envelope
-#   sender address to be set. This is also used as From header.
+#   sender to be set (one address only). This is also used as From header.
 # hooks.emailprefix
 #   If set, e.g. to '[SCM] ', all eMails have their subjects prefixed
 #   with this string to aid filtering.

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=13f0da02ae64d8b2f27156bb20901e781b038aef

commit 13f0da02ae64d8b2f27156bb20901e781b038aef
Author: mirabilos <[email protected]>
Date:   Fri Jan 25 18:07:16 2019 +0100

    typos

diff --git a/post-receive-email b/post-receive-email
index b88a27b..a8c2b46 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -67,13 +67,13 @@
 #   multiple recipients (but please only use addresses, not full names).
 # hooks.announcelist
 #   This is the list(s) that all pushes of annotated tags will go to. Leave
-#   it blank to default to the mailinglist field. The announce emails lists
+#   it blank to default to the mailinglist field. The announce emails list
 #   the short log summary of the changes since the last annotated tag.
 # hooks.replyto
 #   If set, replies are requested to be directed to this eMail address.
 # hooks.envelopesender
 #   If set then the -f option is passed to sendmail to allow the envelope
-#   sender address to be set.  This is also used as Header From.
+#   sender address to be set. This is also used as From header.
 # hooks.emailprefix
 #   If set, e.g. to '[SCM] ', all eMails have their subjects prefixed
 #   with this string to aid filtering.

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=fbc3d4f9a3f4c41184d250c58b0a031a44075e62

commit fbc3d4f9a3f4c41184d250c58b0a031a44075e62
Author: mirabilos <[email protected]>
Date:   Fri Jan 25 18:06:00 2019 +0100

    indicate multiple recipients convention

diff --git a/post-receive-email b/post-receive-email
index 6d8cc76..b88a27b 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -63,10 +63,11 @@
 # ------
 # hooks.mailinglist
 #   This is the list that all pushes will go to; leave it blank to not send
-#   emails for every ref update.
+#   emails for every ref update. This fills the To header, so use comma for
+#   multiple recipients (but please only use addresses, not full names).
 # hooks.announcelist
-#   This is the list that all pushes of annotated tags will go to.  Leave it
-#   blank to default to the mailinglist field.  The announce emails lists
+#   This is the list(s) that all pushes of annotated tags will go to. Leave
+#   it blank to default to the mailinglist field. The announce emails lists
 #   the short log summary of the changes since the last annotated tag.
 # hooks.replyto
 #   If set, replies are requested to be directed to this eMail address.

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=c47cf1cf76cd9c120881ca552ec34890014d1cf6

commit c47cf1cf76cd9c120881ca552ec34890014d1cf6
Author: mirabilos <[email protected]>
Date:   Fri Jan 25 18:02:25 2019 +0100

    update list of requirements to include cURL; indicate PHP preference

diff --git a/post-receive-email b/post-receive-email
index 49598ad..6d8cc76 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -42,8 +42,9 @@
 #  # but that can only be used for a Forge-controlled repository
 #
 # This hook script needs the “C.UTF-8” locale set up (or change below).
-# The MirBSD Korn Shell (mksh) must be installed as /bin/mksh and usable.
-# Perl or PHP with the Multibyte extension are required as well.
+# Other requirementa are: The MirBSD Korn Shell (mksh) as /bin/mksh;
+# PHP with the mbstring extension (preferred) or Perl 5; curl, if you
+# wish to use the curltrigger functionality.
 #
 # This hook script assumes it is enabled on the central repository of a
 # project, with all users pushing only to it and not between each other.  It

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=5f5b45d3915b5b3b1660db4f3f3e2a2564377fb1

commit 5f5b45d3915b5b3b1660db4f3f3e2a2564377fb1
Author: mirabilos <[email protected]>
Date:   Fri Jan 25 17:58:51 2019 +0100

    move to C.UTF-8 from en_US.UTF-8 (more widespread by now)

diff --git a/post-receive-email b/post-receive-email
index e347b9a..49598ad 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -2,7 +2,7 @@
 #
 # Copyright © 2013
 #      Thorsten “mirabilos” Glaser <[email protected]>
-# Copyright © 2011, 2012, 2013, 2014, 2015, 2018
+# Copyright © 2011, 2012, 2013, 2014, 2015, 2018, 2019
 #      Thorsten “mirabilos” Glaser <[email protected]>
 # Copyright © 2016
 #      martin f krafft (madduck), Thorsten Glaser (mirabilos)
@@ -41,7 +41,7 @@
 #  ln -sf /etc/gforge/plugins/scmgit/post-receive-email.sh hooks/post-receive
 #  # but that can only be used for a Forge-controlled repository
 #
-# This hook script needs the “en_US.UTF-8” locale set up on the server.
+# This hook script needs the “C.UTF-8” locale set up (or change below).
 # The MirBSD Korn Shell (mksh) must be installed as /bin/mksh and usable.
 # Perl or PHP with the Multibyte extension are required as well.
 #
@@ -120,7 +120,7 @@
 nl='
 '
 unset LANGUAGE LC_ALL
-export LANG=C LC_ADDRESS=C LC_COLLATE=C LC_CTYPE=en_US.UTF-8 \
+export LANG=C LC_ADDRESS=C LC_COLLATE=C LC_CTYPE=C.UTF-8 \
     LC_IDENTIFICATION=C LC_MEASUREMENT=C LC_MESSAGES=C \
     LC_MONETARY=C LC_NAME=C LC_NUMERIC=C LC_PAPER=C \
     LC_TELEPHONE=C LC_TIME=C

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=fcfc96a351704dedbfa1c476b3791f431045fa72

commit fcfc96a351704dedbfa1c476b3791f431045fa72
Author: mirabilos <[email protected]>
Date:   Wed Sep 5 19:34:31 2018 +0200

    update header

diff --git a/post-receive-email b/post-receive-email
index 171881f..e347b9a 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -15,12 +15,12 @@
 #
 # An example hook script to mail out commit update information.
 #
-# NOTE: This script is no longer under active development.  There
-# is another script, git-multimail, which is more capable and
-# configurable and is largely backwards-compatible with this script;
-# please see "contrib/hooks/multimail/".  For instructions on how to
-# migrate from post-receive-email to git-multimail, please see
-# "README.migrate-from-post-receive-email" in that directory.
+# This script is not under active development by the git team, with
+# git-multimail being suggested as replacement. It has downsides,
+# of course; this script is maintained as a fork, by mirabilos, for
+# 100% compatibility with the old version, plus bugfixes (encoding)
+# and new features (more and better diffs shown; cURL triggers and
+# “KGB” bot support, etc.) and optional FusionForge integration.
 #
 # This hook sends emails listing new revisions to the repository
 # introduced by the change being reported.  The rule is that (for
@@ -43,6 +43,7 @@
 #
 # This hook script needs the “en_US.UTF-8” locale set up on the server.
 # The MirBSD Korn Shell (mksh) must be installed as /bin/mksh and usable.
+# Perl or PHP with the Multibyte extension are required as well.
 #
 # This hook script assumes it is enabled on the central repository of a
 # project, with all users pushing only to it and not between each other.  It

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=44e481fc6c362efdf59e7f46e3873292cbb1a278

commit 44e481fc6c362efdf59e7f46e3873292cbb1a278
Author: mirabilos <[email protected]>
Date:   Wed Sep 5 19:22:05 2018 +0200

    fix branch creation diff (with empty-tree even on new histories);
    
    it’s only still wonky when a non-new created branch starts with
    a merge commit (the left/first parent is used, but things can
    get weird, depending on what is already known history)

diff --git a/post-receive-email b/post-receive-email
index a0f387a..171881f 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -379,8 +379,7 @@ generate_create_branch_email()
 
        echo "Below, we list all revisions that are new to this repository and"
        echo "have not appeared on any other notification email. The diff below"
-       echo "represents the summarised changes, except those from an initial"
-       echo "commit (i.e. diffing starts with the first commit’s tree)."
+       echo "represents the summarised changes from the first known parent:"
 
        echo ""
        echo $LOGBEGIN
@@ -389,10 +388,12 @@ generate_create_branch_email()
        # experimental summarised changes diff
        echo ""
        echo "Summary of changes:"
-       echo $(git rev-parse --not "${other_branches[@]}" | \
-           git rev-list --stdin $newrev) | \
-           git -c core.quotePath=false diff-tree --stdin $diffopts | \
-           sed 1d
+       git rev-parse --not "${other_branches[@]}" | \
+           git rev-list --parents --topo-order --reverse --stdin $newrev | \
+           head -n 1 |&
+       read -p commit parent otherparents
+       git -c core.quotePath=false diff-tree $diffopts \
+           "${parent:-$(:|git hash-object -t tree --stdin)}" "$newrev"
 }
 
 #

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=5fd6948620c22e6e2dce2988738b928a8a000748

commit 5fd6948620c22e6e2dce2988738b928a8a000748
Author: mirabilos <[email protected]>
Date:   Wed Sep 5 19:13:16 2018 +0200

    this did not work (see also git diff-tree -c | --cc)

diff --git a/post-receive-email b/post-receive-email
index 02d9d66..a0f387a 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -389,9 +389,8 @@ generate_create_branch_email()
        # experimental summarised changes diff
        echo ""
        echo "Summary of changes:"
-set -x # --parents --topo-order also doesn’t work
        echo $(git rev-parse --not "${other_branches[@]}" | \
-           git rev-list --parents --topo-order --stdin $newrev) | \
+           git rev-list --stdin $newrev) | \
            git -c core.quotePath=false diff-tree --stdin $diffopts | \
            sed 1d
 }

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=6ae5df09e1e72395bc9f2f9946ba8cbf2b88a393

commit 6ae5df09e1e72395bc9f2f9946ba8cbf2b88a393
Author: mirabilos <[email protected]>
Date:   Wed Sep 5 19:10:31 2018 +0200

    experimental diff showing in branch creation mail, needs work…

diff --git a/post-receive-email b/post-receive-email
index f2a89da..02d9d66 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -377,9 +377,23 @@ generate_create_branch_email()
                return 0
        fi
 
+       echo "Below, we list all revisions that are new to this repository and"
+       echo "have not appeared on any other notification email. The diff below"
+       echo "represents the summarised changes, except those from an initial"
+       echo "commit (i.e. diffing starts with the first commit’s tree)."
+
+       echo ""
        echo $LOGBEGIN
        print -r -- "$newrevs"
        echo $LOGEND
+       # experimental summarised changes diff
+       echo ""
+       echo "Summary of changes:"
+set -x # --parents --topo-order also doesn’t work
+       echo $(git rev-parse --not "${other_branches[@]}" | \
+           git rev-list --parents --topo-order --stdin $newrev) | \
+           git -c core.quotePath=false diff-tree --stdin $diffopts | \
+           sed 1d
 }
 
 #

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=9dfa4394f1410c7eac4fa30a03a4e3e108cd5a2c

commit 9dfa4394f1410c7eac4fa30a03a4e3e108cd5a2c
Author: mirabilos <[email protected]>
Date:   Wed Sep 5 18:02:06 2018 +0200

    sort out logs in eMails when multiple branches are pushed at once

diff --git a/post-receive-email b/post-receive-email
index aee0363..f2a89da 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -750,7 +750,7 @@ show_new_revisions()
        # (see generate_update_branch_email for the explanation of this
        # command)
 
-       local revspec other_branches onerev
+       local revspec onerev
 
        # Revision range passed to rev-list differs for new vs. updated
        # branches.
@@ -763,9 +763,7 @@ show_new_revisions()
                revspec=$oldrev..$newrev
        fi
 
-       other_branches=$(git for-each-ref --format='%(refname)' refs/heads/ |
-           grep -F -v $refname)
-       git rev-parse --not $other_branches |
+       git rev-parse --not "${other_branches[@]}" |
        if [ -z "$custom_showrev" ]
        then
                git rev-list --pretty --stdin $revspec
@@ -856,15 +854,40 @@ if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
        # themselves
        prep_for_email $2 $3 $1 && PAGER= generate_email
 else
-       ilines=
-       while read oldrev newrev refname
-       do
-               ilines="$ilines$oldrev $newrev $refname$nl"
+       # get a list of all branches
+       set -A other_branches -- $(git for-each-ref \
+           --format='%(refname)' refs/heads/)
+       set -A ilines
+       while IFS= read -r line; do
+               # store for later
+               ilines+=("$line")
+               # check if refname is a branch name
+               refname=${line##* }
+               [[ $refname = refs/heads/* ]] || continue
+               # filter out from other_branches if matching
+               i=-1 j=${#other_branches[@]}
+               while (( ++i < j )); do
+                       [[ ${other_branches[i]} = "$refname" ]] || continue
+                       unset other_branches[i]
+                       break
+               done
+               set -A other_branches -- "${other_branches[@]}"
+       done
+       # process one by one for eMails
+       for line in "${ilines[@]}"; do
+               oldrev=${line%% *}
+               newrev=${line#* }
+               newrev=${newrev%% *}
+               refname=${line##* }
                prep_for_email $oldrev $newrev $refname || continue
                generate_email $maxlines | send_mail
+               # append to list of branches for which eMails have been sent
+               [[ $refname = refs/heads/* ]] && other_branches+=("$refname")
        done
        if [[ -n $kgbconffile && -s $kgbconffile ]]; then
-               print -nr -- "$ilines" | kgb-client \
+               for line in "${ilines[@]}"; do
+                       print -r -- "$line"
+               done | kgb-client \
                    --conf "$kgbconffile" --repository git --git-reflog -
        fi
        set -o noglob

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=66433e4902ecdb1c988f6577bc86e930c474b022

commit 66433e4902ecdb1c988f6577bc86e930c474b022
Author: mirabilos <[email protected]>
Date:   Wed Sep 5 17:48:57 2018 +0200

    detect whether git rev-list actually outputted anything;
    issue a "no new revisions added by this update" message if not

diff --git a/post-receive-email b/post-receive-email
index dd864c9..aee0363 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -370,8 +370,15 @@ generate_create_branch_email()
        echo "        at  $newrev ($newrev_type)"
        echo ""
 
+       local newrevs=$(show_new_revisions)
+
+       if [[ -z $newrevs ]]; then
+               echo "No new revisions were added by this update."
+               return 0
+       fi
+
        echo $LOGBEGIN
-       show_new_revisions
+       print -r -- "$newrevs"
        echo $LOGEND
 }
 
@@ -523,20 +530,18 @@ generate_update_branch_email()
                fi
        fi
 
+       local newrevs=
+       [[ -n $rewind_only ]] || newrevs=$(show_new_revisions)
+
        echo ""
-       if [ -z "$rewind_only" ]; then
+       if [[ -n $newrevs ]]; then
                echo "Those revisions listed above that are new to this 
repository have"
                echo "not appeared on any other notification email; so we list 
those"
                echo "revisions in full, below."
 
                echo ""
                echo $LOGBEGIN
-               show_new_revisions
-
-               # XXX: Need a way of detecting whether git rev-list actually
-               # outputted anything, so that we can issue a "no new
-               # revisions added by this update" message
-
+               print -r -- "$newrevs"
                echo $LOGEND
        else
                echo "No new revisions were added by this update."
@@ -745,6 +750,8 @@ show_new_revisions()
        # (see generate_update_branch_email for the explanation of this
        # command)
 
+       local revspec other_branches onerev
+
        # Revision range passed to rev-list differs for new vs. updated
        # branches.
        if [ "$change_type" = create ]

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=b5974e32cf3b4b1f740c1bfd6229f225fb12671d

commit b5974e32cf3b4b1f740c1bfd6229f225fb12671d
Author: mirabilos <[email protected]>
Date:   Wed Sep 5 17:26:34 2018 +0200

    rework Subject header encoding to be more reliable:
    
    • strongly prefer PHP over Perl, now that sid’s is totally unusable
      (although I expect that will be fixed in time)
    • output debugging for what failed
    • if encoding failed still send the eMail (with fixed-string Subject)

diff --git a/post-receive-email b/post-receive-email
index 3e8a7b3..dd864c9 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -2,7 +2,7 @@
 #
 # Copyright © 2013
 #      Thorsten “mirabilos” Glaser <[email protected]>
-# Copyright © 2011, 2012, 2013, 2014, 2015
+# Copyright © 2011, 2012, 2013, 2014, 2015, 2018
 #      Thorsten “mirabilos” Glaser <[email protected]>
 # Copyright © 2016
 #      martin f krafft (madduck), Thorsten Glaser (mirabilos)
@@ -284,7 +284,7 @@ generate_email()
 
 generate_email_header()
 {
-       local routing_headers subj
+       local routing_headers subj senc failc=0
 
        # --- Email (all stdout will be the email)
        # Generate header
@@ -295,14 +295,36 @@ generate_email_header()
 
        subj="Subject: ${emailprefix}$shortdesc $refname_type $short_refname 
${change_type}d. $describe"
 
-       # Note: the Perl call is known to occasionally insert extra whitespace
-       # cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=787513
-       subj=$(print -nr -- "$subj" | \
-           perl -C7 -0777 -Mutf8 -MEncode -e "print encode('MIME-Q', <>);")
-
-       if [[ -z $subj ]]; then
+       # Try to encode. Strongly prefer PHP over Perl and Python, sadly;
+       # evidence provided in Debian bugs #787511, #787512, #787513,
+       # #819155, #879204, #879205, #881955, #907891 though.
+       senc=$(print -nr -- "$subj" | php -r '
+               mb_internal_encoding("UTF-8");
+               echo mb_encode_mimeheader(file_get_contents("php://stdin"),
+                   "UTF-8", "Q", "\012");
+           ' 2>/dev/null) || { (( failc |= 1 )); senc=; }
+       [[ $senc = Subject:?("$nl")' '* ]] || { (( failc |= 2 )); senc=; }
+       [[ -n $senc ]] || senc=$(print -nr -- "$subj" | perl \
+           -C7 -0777 -Mutf8 -MEncode -e "
+               print encode('MIME-Q', <>);
+           " 2>/dev/null) || { (( failc |= 4 )); senc=; }
+       [[ $senc = Subject:?("$nl")' '* ]] || { (( failc |= 8 )); senc=; }
+
+       if [[ -z $senc ]]; then
                print -u2 "E: Subject empty, RFC2047 MIME encoding failed"
-               exit 1
+               if ! whence -p php >/dev/null 2>&1; then
+                       : show only the Perl-related error messages below
+               elif (( failc & 1 )); then
+                       print -u2 "N: PHP encoding failed, perhaps install 
php-mbstring."
+               elif (( failc & 2 )); then
+                       print -u2 "N: PHP encoding produced bad output, WTF‽"
+               fi
+               if (( failc & 4 )); then
+                       print -u2 "N: Perl encoding failed, WTF‽ Also, install 
PHP."
+               elif (( failc & 8 )); then
+                       print -u2 "N: Perl encoding produced bad output, 
install PHP!"
+               fi
+               senc="Subject: post-receive-email: no Subject, RFC2047 MIME 
encoding failed"
        fi
 
        cat <<-EOF
@@ -314,7 +336,7 @@ generate_email_header()
        X-Git-Reftype: $refname_type
        X-Git-Oldrev: $oldrev
        X-Git-Newrev: $newrev
-       $subj
+       $senc
        Auto-Submitted: auto-generated
 
        This is an automated email from the git hooks/post-receive script. It 
was

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=73fee0fc450df7c4ce29b90a252247f35f68b4f6

commit 73fee0fc450df7c4ce29b90a252247f35f68b4f6
Author: mirabilos <[email protected]>
Date:   Thu Jul 14 17:53:28 2016 +0200

    enable UTF-8 filenames in output; from an IRC question by madduck

diff --git a/post-receive-email b/post-receive-email
index 17245c2..3e8a7b3 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -4,6 +4,8 @@
 #      Thorsten “mirabilos” Glaser <[email protected]>
 # Copyright © 2011, 2012, 2013, 2014, 2015
 #      Thorsten “mirabilos” Glaser <[email protected]>
+# Copyright © 2016
+#      martin f krafft (madduck), Thorsten Glaser (mirabilos)
 #
 # Copyright (c) 2007 Andy Parkins
 #
@@ -527,7 +529,7 @@ generate_update_branch_email()
        # non-fast-forward updates.
        echo ""
        echo "Summary of changes:"
-       git diff-tree $diffopts $oldrev..$newrev
+       git -c core.quotePath=false diff-tree $diffopts $oldrev..$newrev
 }
 
 #

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=466073989f6fc20b56e2c2d77b5676bbf7b3c36f

commit 466073989f6fc20b56e2c2d77b5676bbf7b3c36f
Author: mirabilos <[email protected]>
Date:   Thu Oct 29 13:06:43 2015 +0100

    fix typo

diff --git a/post-receive-email b/post-receive-email
index 0a44c21..17245c2 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -96,7 +96,7 @@
 # hooks.diffopts
 #   Alternate options for the git diff-tree invocation that shows changes.
 #   Default is "-p --stat --summary --find-copies-harder". Remove -p from
-#   those options to skil including a unified diff of changes in addition
+#   those options to skip including a unified diff of changes in addition
 #   to the summary output. See hooks.showrev for more discussion on this.
 # hooks.kgbconffile
 #   Full path to a configuration file for kgb-client, or unset/empty.

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=31377f63785917dced78bcf973997d756e321f66

commit 31377f63785917dced78bcf973997d756e321f66
Author: Thorsten Glaser <[email protected]>
Date:   Tue Jun 2 14:30:19 2015 +0200

    SECURITY: avoid globbing dot arguments

diff --git a/post-receive-email b/post-receive-email
index 95d0080..0a44c21 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -810,11 +810,11 @@ emailprefix=$(git config hooks.emailprefix)
 custom_showrev=$(git config hooks.showrev)
 maxlines=$(git config hooks.emailmaxlines)
 diffopts=$(git config hooks.diffopts)
-: ${diffopts:="-p --stat --summary --find-copies-harder"}
+: "${diffopts:="-p --stat --summary --find-copies-harder"}"
 kgbconffile=$(git config hooks.kgbconffile)
 replyto=$(git config hooks.replyto)
 shortdesc=$(git config hooks.shortdesc)
-: ${shortdesc:=$projectdesc}
+: "${shortdesc:=$projectdesc}"
 
 # --- Main loop
 # Allow dual mode: run from the command line just like the update hook, or

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=e508c939f80dfbd0fd3473e94b5dd66a9c8f1fcd

commit e508c939f80dfbd0fd3473e94b5dd66a9c8f1fcd
Author: Thorsten Glaser <[email protected]>
Date:   Tue Jun 2 14:17:54 2015 +0200

    add note about debbugs #787513; verify all changes from upstream are merged

diff --git a/post-receive-email b/post-receive-email
index 356b0e7..95d0080 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -292,6 +292,9 @@ generate_email_header()
        [[ -n $replyto ]] && routing_headers="$routing_headers${nl}Reply-To: 
$replyto"
 
        subj="Subject: ${emailprefix}$shortdesc $refname_type $short_refname 
${change_type}d. $describe"
+
+       # Note: the Perl call is known to occasionally insert extra whitespace
+       # cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=787513
        subj=$(print -nr -- "$subj" | \
            perl -C7 -0777 -Mutf8 -MEncode -e "print encode('MIME-Q', <>);")
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=4bb2c05c4232ea35dc59e60f5e7bf23ea206af50

commit 4bb2c05c4232ea35dc59e60f5e7bf23ea206af50
Author: Thorsten Glaser <[email protected]>
Date:   Tue Jun 2 14:17:33 2015 +0200

    pull Subject encoding out of the here document and add a sanity check

diff --git a/post-receive-email b/post-receive-email
index 133bc66..356b0e7 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -292,6 +292,13 @@ generate_email_header()
        [[ -n $replyto ]] && routing_headers="$routing_headers${nl}Reply-To: 
$replyto"
 
        subj="Subject: ${emailprefix}$shortdesc $refname_type $short_refname 
${change_type}d. $describe"
+       subj=$(print -nr -- "$subj" | \
+           perl -C7 -0777 -Mutf8 -MEncode -e "print encode('MIME-Q', <>);")
+
+       if [[ -z $subj ]]; then
+               print -u2 "E: Subject empty, RFC2047 MIME encoding failed"
+               exit 1
+       fi
 
        cat <<-EOF
        MIME-Version: 1.0
@@ -302,8 +309,7 @@ generate_email_header()
        X-Git-Reftype: $refname_type
        X-Git-Oldrev: $oldrev
        X-Git-Newrev: $newrev
-       $(print -nr -- "$subj" | \
-           perl -C7 -0777 -Mutf8 -MEncode -e "print encode('MIME-Q', <>);")
+       $subj
        Auto-Submitted: auto-generated
 
        This is an automated email from the git hooks/post-receive script. It 
was

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=73f6d7db4eddf19317e52bea4ae35b90eb23d4e4

commit 73f6d7db4eddf19317e52bea4ae35b90eb23d4e4
Author: Thorsten Glaser <[email protected]>
Date:   Tue Jun 2 13:39:10 2015 +0200

    pass Subject to RFC2047 Perl encoder by stdin; fixes bug with single quotes
    
    Bug reported in FusionForge by Sylvain Beucler (beuc-inria)
    Corrected bugfix by me ipso; also sets Perl stdio to UTF-8

diff --git a/post-receive-email b/post-receive-email
index 0a3cc7d..133bc66 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -302,7 +302,8 @@ generate_email_header()
        X-Git-Reftype: $refname_type
        X-Git-Oldrev: $oldrev
        X-Git-Newrev: $newrev
-       $(perl -Mutf8 -MEncode -e "print encode('MIME-Q', '$subj');")
+       $(print -nr -- "$subj" | \
+           perl -C7 -0777 -Mutf8 -MEncode -e "print encode('MIME-Q', <>);")
        Auto-Submitted: auto-generated
 
        This is an automated email from the git hooks/post-receive script. It 
was

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=d82963884953e3ce8d759eea8f228fd8d141032d

commit d82963884953e3ce8d759eea8f228fd8d141032d
Author: Thorsten Glaser <[email protected]>
Date:   Tue Jun 2 13:38:10 2015 +0200

    pull mail subject generation out of here document

diff --git a/post-receive-email b/post-receive-email
index 8385a47..0a3cc7d 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -282,7 +282,7 @@ generate_email()
 
 generate_email_header()
 {
-       local routing_headers
+       local routing_headers subj
 
        # --- Email (all stdout will be the email)
        # Generate header
@@ -291,6 +291,8 @@ generate_email_header()
        [[ -n $envelopesender ]] && routing_headers="From: 
$envelopesender${nl}$routing_headers"
        [[ -n $replyto ]] && routing_headers="$routing_headers${nl}Reply-To: 
$replyto"
 
+       subj="Subject: ${emailprefix}$shortdesc $refname_type $short_refname 
${change_type}d. $describe"
+
        cat <<-EOF
        MIME-Version: 1.0
        Content-Type: text/plain; charset=UTF-8
@@ -300,7 +302,7 @@ generate_email_header()
        X-Git-Reftype: $refname_type
        X-Git-Oldrev: $oldrev
        X-Git-Newrev: $newrev
-       $(perl -Mutf8 -MEncode -e "print encode('MIME-Q', 'Subject: 
${emailprefix}$shortdesc $refname_type $short_refname ${change_type}d. 
$describe');")
+       $(perl -Mutf8 -MEncode -e "print encode('MIME-Q', '$subj');")
        Auto-Submitted: auto-generated
 
        This is an automated email from the git hooks/post-receive script. It 
was

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=4a3ca5f0768682f16550a92086fa1292b3c3e617

commit 4a3ca5f0768682f16550a92086fa1292b3c3e617
Author: Thorsten Glaser <[email protected]>
Date:   Tue Jun 2 13:36:38 2015 +0200

    use “local” for newly introduced function-local variables

diff --git a/post-receive-email b/post-receive-email
index 9494217..8385a47 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -282,6 +282,8 @@ generate_email()
 
 generate_email_header()
 {
+       local routing_headers
+
        # --- Email (all stdout will be the email)
        # Generate header
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=e457547e15c5a7815f6bf5ea86bdd26934376018

commit e457547e15c5a7815f6bf5ea86bdd26934376018
Author: Thorsten Glaser <[email protected]>
Date:   Wed Apr 1 17:58:50 2015 +0200

    also announce the URI used

diff --git a/post-receive-email b/post-receive-email
index 79a5ebc..9494217 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -824,6 +824,7 @@ else
        fi
        set -o noglob
        for uri in $(git config hooks.curltrigger); do
+               print -r -- "‣‣‣ $uri"
                curl "$uri"
        done
 fi

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=ea850cdc31a338298187e018d18389cdf5a1a807

commit ea850cdc31a338298187e018d18389cdf5a1a807
Author: Thorsten Glaser <[email protected]>
Date:   Wed Apr 1 17:51:11 2015 +0200

    cURL trigger

diff --git a/post-receive-email b/post-receive-email
index e083bbb..79a5ebc 100755
--- a/post-receive-email
+++ b/post-receive-email
@@ -2,7 +2,7 @@
 #
 # Copyright © 2013
 #      Thorsten “mirabilos” Glaser <[email protected]>
-# Copyright © 2011, 2012, 2013, 2014
+# Copyright © 2011, 2012, 2013, 2014, 2015
 #      Thorsten “mirabilos” Glaser <[email protected]>
 #
 # Copyright (c) 2007 Andy Parkins
@@ -101,6 +101,9 @@
 # hooks.kgbconffile
 #   Full path to a configuration file for kgb-client, or unset/empty.
 #   If set, kgb-client will be invoked.
+# hooks.curltrigger
+#   List (expanded by shell “for”, so be careful) of URIs to trigger on
+#   each push to be accessed with cURL.
 #
 # Notes
 # -----
@@ -819,4 +822,8 @@ else
                print -nr -- "$ilines" | kgb-client \
                    --conf "$kgbconffile" --repository git --git-reflog -
        fi
+       set -o noglob
+       for uri in $(git config hooks.curltrigger); do
+               curl "$uri"
+       done
 fi

-----------------------------------------------------------------------

Summary of changes:
 src/common/include/minijson.php                    | 889 +++++++++++----------
 .../hooks/postreceiveemail/post-receive-email      | 187 +++--
 tests/unit/common/minijsonTest.php                 |  48 +-
 3 files changed, 615 insertions(+), 509 deletions(-)


hooks/post-receive
-- 
FusionForge

_______________________________________________
Fusionforge-commits mailing list
[email protected]
http://lists.fusionforge.org/cgi-bin/mailman/listinfo/fusionforge-commits

Reply via email to