[Libreoffice-commits] core.git: Branch 'feature/cib_contract136' - 13 commits - configure.ac external/curl external/liborcus include/o3tl vcl/inc vcl/source

Thorsten Behrens Thorsten.Behrens at CIB.de
Fri Jun 1 14:01:56 UTC 2018


Rebased ref, commits from common ancestor:
commit f8b409433c3f2fa69a7a87d746688f472731f7ab
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Fri Jun 1 14:27:41 2018 +0200

    Bump version to 5.2.7.6
    
    Change-Id: I0bbcaca0e6113f2fca7af73369e64f5152d41fce

diff --git a/configure.ac b/configure.ac
index 95d0bd52c77f..a4534231b499 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@ dnl in order to create a configure script.
 # several non-alphanumeric characters, those are split off and used only for the
 # ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no idea.
 
-AC_INIT([LibreOffice],[5.2.7.5],[],[],[http://documentfoundation.org/])
+AC_INIT([LibreOffice],[5.2.7.6],[],[],[http://documentfoundation.org/])
 
 AC_PREREQ([2.59])
 
commit fb885579b9ca441ecfc08677b367fbdaa8b15f5d
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Feb 21 20:08:23 2018 -0500

    Patch liborcus to avoid incorrect parsing of XML.
    
    Found by Antti Levomäki and Christian Jalio from Forcepoint.
    
    This one is not a backport from the master branch.  On the master
    branch the same fix will come from updating liborcus from 0.13.3
    to 0.13.4.
    
    (cherry picked from commit 160350de5f07024b22fb5a9b596918ccc7f22c75)
    
     Conflicts:
            external/liborcus/UnpackedTarball_liborcus.mk
    
    Reviewed-on: https://gerrit.libreoffice.org/50147
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    (cherry picked from commit f25bc1254782589af5d24471599260b65558154a)
    
    Conflicts:
            external/liborcus/UnpackedTarball_liborcus.mk
    
    Change-Id: I701c5a65ff67d77767913f8d056682b9db549f84

diff --git a/external/liborcus/0001-protect-the-self-closing-xml-element-code-against-se.patch b/external/liborcus/0001-protect-the-self-closing-xml-element-code-against-se.patch
new file mode 100644
index 000000000000..990665f9c383
--- /dev/null
+++ b/external/liborcus/0001-protect-the-self-closing-xml-element-code-against-se.patch
@@ -0,0 +1,30 @@
+From 12e5d89cbd7101c61fbdf063322203a1590a0ef5 Mon Sep 17 00:00:00 2001
+From: Markus Mohrhard <markus.mohrhard at googlemail.com>
+Date: Wed, 21 Feb 2018 00:29:03 +0100
+Subject: [PATCH] protect the self-closing xml element code against
+ self-closing root elements
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Found by Antti Levomäki and Christian Jalio from Forcepoint.
+---
+ include/orcus/sax_parser.hpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/orcus/sax_parser.hpp b/include/orcus/sax_parser.hpp
+index ba5ebcd..67d5943 100644
+--- a/include/orcus/sax_parser.hpp
++++ b/include/orcus/sax_parser.hpp
+@@ -171,6 +171,8 @@ void sax_parser<_Handler,_Config>::element_open(std::ptrdiff_t begin_pos)
+             m_handler.start_element(elem);
+             reset_buffer_pos();
+             m_handler.end_element(elem);
++            if (!m_nest_level)
++                m_root_elem_open = false;
+ #if ORCUS_DEBUG_SAX_PARSER
+             cout << "element_open: ns='" << elem.ns << "', name='" << elem.name << "' (self-closing)" << endl;
+ #endif
+-- 
+2.7.4
+
diff --git a/external/liborcus/UnpackedTarball_liborcus.mk b/external/liborcus/UnpackedTarball_liborcus.mk
index 08f3423f2424..51f6e55e1de1 100644
--- a/external/liborcus/UnpackedTarball_liborcus.mk
+++ b/external/liborcus/UnpackedTarball_liborcus.mk
@@ -16,6 +16,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,liborcus,1))
 $(eval $(call gb_UnpackedTarball_add_patches,liborcus,\
 	external/liborcus/0001-workaround-a-linking-problem-on-windows.patch \
 	external/liborcus/rpath.patch.0 \
+	external/liborcus/0001-protect-the-self-closing-xml-element-code-against-se.patch \
 ))
 
 ifeq ($(OS),WNT)
commit 66b690bc0137a8fcf351987837a007b3d7994883
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Jan 24 22:24:03 2018 +0100

    curl: fix CVE-2018-1000005/1000007
    
    * don't upgrade to new release, no idea how the new windows
      build system likes targeting Win XP which is still supported in 5.4
    
    Change-Id: I4fbd7f1c5f1f0563895f6f8ede10063621d10a4b
    Reviewed-on: https://gerrit.libreoffice.org/48542
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit ed497921314ebd41fce3483c92ca433b502628ca)

diff --git a/external/curl/CVE-2018-1000005.patch b/external/curl/CVE-2018-1000005.patch
new file mode 100644
index 000000000000..7b5578b1aacc
--- /dev/null
+++ b/external/curl/CVE-2018-1000005.patch
@@ -0,0 +1,36 @@
+From fa3dbb9a147488a2943bda809c66fc497efe06cb Mon Sep 17 00:00:00 2001
+From: Zhouyihai Ding <ddyihai at ddyihai.svl.corp.google.com>
+Date: Wed, 10 Jan 2018 10:12:18 -0800
+Subject: [PATCH] http2: fix incorrect trailer buffer size
+
+Prior to this change the stored byte count of each trailer was
+miscalculated and 1 less than required. It appears any trailer
+after the first that was passed to Curl_client_write would be truncated
+or corrupted as well as the size. Potentially the size of some
+subsequent trailer could be erroneously extracted from the contents of
+that trailer, and since that size is used by client write an
+out-of-bounds read could occur and cause a crash or be otherwise
+processed by client write.
+
+The bug appears to have been born in 0761a51 (precedes 7.49.0).
+
+Closes https://github.com/curl/curl/pull/2231
+---
+ lib/http2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/http2.c b/lib/http2.c
+index 8e2fc71996..699287940e 100644
+--- a/lib/http2.c
++++ b/lib/http2.c
+@@ -925,8 +925,8 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
+ 
+   if(stream->bodystarted) {
+     /* This is trailer fields. */
+-    /* 3 is for ":" and "\r\n". */
+-    uint32_t n = (uint32_t)(namelen + valuelen + 3);
++    /* 4 is for ": " and "\r\n". */
++    uint32_t n = (uint32_t)(namelen + valuelen + 4);
+ 
+     DEBUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
+                  value));
diff --git a/external/curl/CVE-2018-1000007.patch b/external/curl/CVE-2018-1000007.patch
new file mode 100644
index 000000000000..c474370c78ad
--- /dev/null
+++ b/external/curl/CVE-2018-1000007.patch
@@ -0,0 +1,110 @@
+From af32cd3859336ab963591ca0df9b1e33a7ee066b Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel at haxx.se>
+Date: Fri, 19 Jan 2018 13:19:25 +0100
+Subject: [PATCH] http: prevent custom Authorization headers in redirects
+
+... unless CURLOPT_UNRESTRICTED_AUTH is set to allow them. This matches how
+curl already handles Authorization headers created internally.
+
+Note: this changes behavior slightly, for the sake of reducing mistakes.
+
+Added test 317 and 318 to verify.
+
+Reported-by: Craig de Stigter
+Bug: https://curl.haxx.se/docs/adv_2018-b3bf.html
+---
+ docs/libcurl/opts/CURLOPT_HTTPHEADER.3 | 12 ++++-
+ lib/http.c                             | 10 +++-
+ lib/setopt.c                           |  2 +-
+ lib/urldata.h                          |  2 +-
+ tests/data/Makefile.inc                |  2 +-
+ tests/data/test317                     | 94 +++++++++++++++++++++++++++++++++
+ tests/data/test318                     | 95 ++++++++++++++++++++++++++++++++++
+ 7 files changed, 212 insertions(+), 5 deletions(-)
+ create mode 100644 tests/data/test317
+ create mode 100644 tests/data/test318
+
+diff --git a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
+index c5ccb1a53d..c9f29e393e 100644
+--- a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
++++ b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
+@@ -5,7 +5,7 @@
+ .\" *                            | (__| |_| |  _ <| |___
+ .\" *                             \___|\___/|_| \_\_____|
+ .\" *
+-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel at haxx.se>, et al.
++.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel at haxx.se>, et al.
+ .\" *
+ .\" * This software is licensed as described in the file COPYING, which
+ .\" * you should have received as part of this distribution. The terms
+@@ -77,6 +77,16 @@ the headers. They may be private or otherwise sensitive to leak.
+ 
+ Use \fICURLOPT_HEADEROPT(3)\fP to make the headers only get sent to where you
+ intend them to get sent.
++
++Custom headers are sent in all requests done by the easy handles, which
++implies that if you tell libcurl to follow redirects
++(\fBCURLOPT_FOLLOWLOCATION(3)\fP), the same set of custom headers will be sent
++in the subsequent request. Redirects can of course go to other hosts and thus
++those servers will get all the contents of your custom headers too.
++
++Starting in 7.58.0, libcurl will specifically prevent "Authorization:" headers
++from being sent to other hosts than the first used one, unless specifically
++permitted with the \fBCURLOPT_UNRESTRICTED_AUTH(3)\fP option.
+ .SH DEFAULT
+ NULL
+ .SH PROTOCOLS
+diff --git a/lib/http.c b/lib/http.c
+index c1cdf2da02..a5007670d7 100644
+--- a/lib/http.c
++++ b/lib/http.c
+@@ -714,7 +714,7 @@ Curl_http_output_auth(struct connectdata *conn,
+   if(!data->state.this_is_a_follow ||
+      conn->bits.netrc ||
+      !data->state.first_host ||
+-     data->set.http_disable_hostname_check_before_authentication ||
++     data->set.allow_auth_to_other_hosts ||
+      strcasecompare(data->state.first_host, conn->host.name)) {
+     result = output_auth_headers(conn, authhost, request, path, FALSE);
+   }
+@@ -1636,6 +1636,14 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
+                   checkprefix("Transfer-Encoding:", headers->data))
+             /* HTTP/2 doesn't support chunked requests */
+             ;
++          else if(checkprefix("Authorization:", headers->data) &&
++                  /* be careful of sending this potentially sensitive header to
++                     other hosts */
++                  (data->state.this_is_a_follow &&
++                   data->state.first_host &&
++                   !data->set.allow_auth_to_other_hosts &&
++                   !strcasecompare(data->state.first_host, conn->host.name)))
++            ;
+           else {
+             CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
+                                                headers->data);
+diff --git a/lib/setopt.c b/lib/setopt.c
+index 66f30ea653..a5ef75c722 100644
+--- a/lib/url.c
++++ b/lib/url.c
+@@ -976,7 +976,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
+      * Send authentication (user+password) when following locations, even when
+      * hostname changed.
+      */
+-    data->set.http_disable_hostname_check_before_authentication =
++    data->set.allow_auth_to_other_hosts =
+       (0 != va_arg(param, long)) ? TRUE : FALSE;
+     break;
+ 
+diff --git a/lib/urldata.h b/lib/urldata.h
+index 4dcd1a322c..5c04ad1720 100644
+--- a/lib/urldata.h
++++ b/lib/urldata.h
+@@ -1599,7 +1599,7 @@ struct UserDefined {
+   bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */
+   bool http_follow_location; /* follow HTTP redirects */
+   bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
+-  bool http_disable_hostname_check_before_authentication;
++  bool allow_auth_to_other_hosts;
+   bool include_header;   /* include received protocol headers in data output */
+   bool http_set_referer; /* is a custom referer used */
+   bool http_auto_referer; /* set "correct" referer when following location: */
diff --git a/external/curl/UnpackedTarball_curl.mk b/external/curl/UnpackedTarball_curl.mk
index 4cabf2f1b80b..f9f3a8bf6016 100644
--- a/external/curl/UnpackedTarball_curl.mk
+++ b/external/curl/UnpackedTarball_curl.mk
@@ -24,6 +24,8 @@ $(eval $(call gb_UnpackedTarball_add_patches,curl,\
 	external/curl/curl-7.26.0_win-proxy.patch \
 	external/curl/curl-xp.patch.1 \
 	external/curl/CVE-2017-8816.patch \
+	external/curl/CVE-2018-1000005.patch \
+	external/curl/CVE-2018-1000007.patch \
 ))
 
 ifeq ($(SYSTEM_NSS),)
commit 32587c2be718f66ef92f15bb043af2f3f2f55339
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Nov 29 12:28:03 2017 +0100

    curl: fix CVE-2017-8816
    
    * don't upgrade to new release, no idea how the new windows
      build system likes targeting Win XP which is still supported in 5.4
    * CVE-2017-8817 doesn't affect LO as CURLOPT_WILDCARDMATCH isn't used
    * CVE-2017-8818 doesn't affect the old 7.52 version
    
    Change-Id: I49ddb771ccdb93d5fe8f4b3544f74ab9b171c156
    Reviewed-on: https://gerrit.libreoffice.org/45487
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit aa0f44de5b260b2b2a39bdd2de9445d72ab14265)

diff --git a/external/curl/CVE-2017-8816.patch b/external/curl/CVE-2017-8816.patch
new file mode 100644
index 000000000000..dd4fa677e03f
--- /dev/null
+++ b/external/curl/CVE-2017-8816.patch
@@ -0,0 +1,67 @@
+From 7947c50bcd09cf471c95511739bc66d2cb506ee2 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel at haxx.se>
+Date: Mon, 6 Nov 2017 23:51:52 +0100
+Subject: [PATCH] ntlm: avoid integer overflow for malloc size
+
+Reported-by: Alex Nichols
+Assisted-by: Kamil Dudka and Max Dymond
+
+CVE-2017-8816
+
+Bug: https://curl.haxx.se/docs/adv_2017-11e7.html
+---
+ lib/curl_ntlm_core.c | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
+index 1309bf0d9..e8962769c 100644
+--- a/lib/curl_ntlm_core.c
++++ b/lib/curl_ntlm_core.c
+@@ -644,23 +644,42 @@ CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
+   Curl_HMAC_final(ctxt, output);
+ 
+   return CURLE_OK;
+ }
+ 
++#ifndef SIZE_T_MAX
++/* some limits.h headers have this defined, some don't */
++#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
++#define SIZE_T_MAX 18446744073709551615U
++#else
++#define SIZE_T_MAX 4294967295U
++#endif
++#endif
++
+ /* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
+  * (uppercase UserName + Domain) as the data
+  */
+ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
+                                        const char *domain, size_t domlen,
+                                        unsigned char *ntlmhash,
+                                        unsigned char *ntlmv2hash)
+ {
+   /* Unicode representation */
+-  size_t identity_len = (userlen + domlen) * 2;
+-  unsigned char *identity = malloc(identity_len);
++  size_t identity_len;
++  unsigned char *identity;
+   CURLcode result = CURLE_OK;
+ 
++  /* we do the length checks below separately to avoid integer overflow risk
++     on extreme data lengths */
++  if((userlen > SIZE_T_MAX/2) ||
++     (domlen > SIZE_T_MAX/2) ||
++     ((userlen + domlen) > SIZE_T_MAX/2))
++    return CURLE_OUT_OF_MEMORY;
++
++  identity_len = (userlen + domlen) * 2;
++  identity = malloc(identity_len);
++
+   if(!identity)
+     return CURLE_OUT_OF_MEMORY;
+ 
+   ascii_uppercase_to_unicode_le(identity, user, userlen);
+   ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
+-- 
+2.15.0
+
diff --git a/external/curl/UnpackedTarball_curl.mk b/external/curl/UnpackedTarball_curl.mk
index 6a5720d78459..4cabf2f1b80b 100644
--- a/external/curl/UnpackedTarball_curl.mk
+++ b/external/curl/UnpackedTarball_curl.mk
@@ -23,6 +23,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,curl,\
 	external/curl/curl-7.26.0_mingw.patch \
 	external/curl/curl-7.26.0_win-proxy.patch \
 	external/curl/curl-xp.patch.1 \
+	external/curl/CVE-2017-8816.patch \
 ))
 
 ifeq ($(SYSTEM_NSS),)
commit 4590df12e310866aefc35c8a7994644f082cb65c
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Feb 9 10:35:33 2018 +0000

    various sft fixes
    
    backport removing unneeded code
    
    use ptr diff rather than int
    
    (cherry picked from commit 5b426038a7befcaf0d05824ffb20200ff8833ad3)
    
    fix mem leak
    
    (cherry picked from commit 603cb6cf31a5212d03736a552770e5734b0e8066)
    
    check more table sizes
    
    (cherry picked from commit 1828490bb22f1c8273c4a9f5b1db819b173ca70d)
    
    check cmap offset
    
    (cherry picked from commit 683d9883ad8fd6568e6a7832e5bb347c1d043e4b)
    
    check tableoffset against size
    
    (cherry picked from commit ae73c3ff112e1ed38eb4678ac5745990661a2e66)
    
    check ntables offset
    
    (cherry picked from commit 75a171a405afd6eac236af93aa9d29a9c3ec9c64)
    
    use safeint on calculations
    
    (cherry picked from commit 139b6c6cf898467098f3a6f29fa84013a182285f)
    
    simplify returns
    
    (cherry picked from commit e8b2aad1cb2107304761e68aa380b5c29d8ef22f)
    
    extend to cover the last byte needed
    
    (cherry picked from commit c7b0117f26a386c98a721ff3897479c268103d74)
    
    bounds check
    
    (cherry picked from commit bb32616bdd6e3b327654bab0e1d790d8d50b893d)
    
    move largest bounds check to start
    
    (cherry picked from commit f832198e6a33052c7cc86b25843badfb962a2ae8)
    
    android:update safeint header to use the else implementation with clang
    
    Clang toolchain does not defines the __builtin_mul_overflow for 32-bit
    ARM. So, fallback to else implementation of checked_multiply when
    building Android with Clang
    
    Reviewed-on: https://gerrit.libreoffice.org/39005
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 2149d4a88e9dc88c30e7475f8ea317e5c7b78529)
    
    add checked_add
    
    Reviewed-on: https://gerrit.libreoffice.org/43779
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 9cfb27ae6cb94f0a853ff70e9ad9f3109d305a94)
    
    Change-Id: I0b59f1b93d31a7cb5b8db2a21736db11aed46536
    a174fd94c57cc3c899c10e1c0dc5968965a50427
    0d329357ac282d4652b0f7ebc401cbd51963461b
    004a6d322f60d916cc4635b362ce948e8a10d7c7
    5aae26c38f3645020f0e1d6d7b6877c2727af1b4
    a79be052dd3f6b6ed38fb326558924c853af5fff
    d75f5f4b578fd176c17e5763569f1403260c6594
    c063786ba41aa9a985f505e62b43d3d543a0d48f
    1a67cb2f1c686032438852fec1267a59fbd04d7f
    5177d42b47a4bca614878dce4a69ab16b5cfe163
    6d32a6b6f1dd91db42a3f154700ea55603f0e4dd
    03fe80f9568759b829fac4e9bcfd496efebe6a26
    6120606f521ce121541a5b7f1150229258012d55
    10cba898bba528f5f1bfbd583e27a6821c789ab9
    Reviewed-on: https://gerrit.libreoffice.org/49485
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/include/o3tl/safeint.hxx b/include/o3tl/safeint.hxx
new file mode 100644
index 000000000000..5ebf353b6bd6
--- /dev/null
+++ b/include/o3tl/safeint.hxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_O3TL_SAFEINT_HXX
+#define INCLUDED_O3TL_SAFEINT_HXX
+
+#include <limits>
+#if defined(_MSC_VER)
+#include <safeint.h>
+#else
+#ifndef __has_builtin
+#   define __has_builtin(x) 0
+#endif
+#endif
+
+namespace o3tl
+{
+
+#if defined(_MSC_VER)
+
+template<typename T> inline bool checked_multiply(T a, T b, T& result)
+{
+    return !msl::utilities::SafeMultiply(a, b, result);
+}
+
+template<typename T> inline bool checked_add(T a, T b, T& result)
+{
+    return !msl::utilities::SafeAdd(a, b, result);
+}
+
+#elif (defined __GNUC__ && __GNUC__ >= 5) || (__has_builtin(__builtin_mul_overflow) && !(defined ANDROID && defined __clang__))
+
+template<typename T> inline bool checked_multiply(T a, T b, T& result)
+{
+    return __builtin_mul_overflow(a, b, &result);
+}
+
+template<typename T> inline bool checked_add(T a, T b, T& result)
+{
+    return __builtin_add_overflow(a, b, &result);
+}
+
+#else
+
+//https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
+template<typename T> inline typename std::enable_if<std::is_signed<T>::value, bool>::type checked_multiply(T a, T b, T& result)
+{
+  if (a > 0) {  /* a is positive */
+    if (b > 0) {  /* a and b are positive */
+      if (a > (std::numeric_limits<T>::max() / b)) {
+        return true; /* Handle error */
+      }
+    } else { /* a positive, b nonpositive */
+      if (b < (std::numeric_limits<T>::min() / a)) {
+        return true; /* Handle error */
+      }
+    } /* a positive, b nonpositive */
+  } else { /* a is nonpositive */
+    if (b > 0) { /* a is nonpositive, b is positive */
+      if (a < (std::numeric_limits<T>::min() / b)) {
+        return true; /* Handle error */
+      }
+    } else { /* a and b are nonpositive */
+      if ( (a != 0) && (b < (std::numeric_limits<T>::max() / a))) {
+        return true; /* Handle error */
+      }
+    } /* End if a and b are nonpositive */
+  } /* End if a is nonpositive */
+
+  result = a * b;
+
+  return false;
+}
+
+//https://www.securecoding.cert.org/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
+template<typename T> inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type checked_multiply(T a, T b, T& result)
+{
+    if (b && a > std::numeric_limits<T>::max() / b) {
+        return true;/* Handle error */
+    }
+
+    result = a * b;
+
+    return false;
+}
+
+//https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
+template<typename T> inline typename std::enable_if<std::is_signed<T>::value, bool>::type checked_add(T a, T b, T& result)
+{
+    if (((b > 0) && (a > (std::numeric_limits<T>::max() - b))) ||
+        ((b < 0) && (a < (std::numeric_limits<T>::min() - b)))) {
+        return true;
+    }
+
+    result = a + b;
+
+    return false;
+}
+
+//https://www.securecoding.cert.org/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
+template<typename T> inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type checked_add(T a, T b, T& result)
+{
+    if (std::numeric_limits<T>::max() - a < b) {
+        return true;/* Handle error */
+    }
+
+    result = a + b;
+
+    return false;
+}
+
+#endif
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index 80c62c11b878..0b3c3afcfbef 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -189,21 +189,15 @@ namespace vcl
         int   descender;          /**< typographic descent.                                    */
         int   linegap;            /**< typographic line gap.\ Negative values are treated as
                                      zero in Win 3.1, System 6 and System 7.                 */
-        int   vascent;            /**< typographic ascent for vertical writing mode            */
-        int   vdescent;           /**< typographic descent for vertical writing mode           */
         int   typoAscender;       /**< OS/2 portable typographic ascender                      */
         int   typoDescender;      /**< OS/2 portable typographic descender                     */
         int   typoLineGap;        /**< OS/2 portable typographic line gap                       */
         int   winAscent;          /**< ascender metric for Windows                             */
         int   winDescent;         /**< descender metric for Windows                            */
         bool  symbolEncoded;      /**< true: MS symbol encoded */
-        int   rangeFlag;          /**< if set to 1 Unicode Range flags are applicable          */
-        sal_uInt32 ur1;               /**< bits 0 - 31 of Unicode Range flags                      */
-        sal_uInt32 ur2;               /**< bits 32 - 63 of Unicode Range flags                     */
-        sal_uInt32 ur3;               /**< bits 64 - 95 of Unicode Range flags                     */
-        sal_uInt32 ur4;               /**< bits 96 - 127 of Unicode Range flags                    */
-        sal_uInt8   panose[10];        /**< PANOSE classification number                            */
-        sal_uInt32 typeFlags;         /**< type flags (copyright bits + PS-OpenType flag)       */
+        sal_uInt8  panose[10];    /**< PANOSE classification number                            */
+        sal_uInt32 typeFlags;     /**< type flags (copyright bits + PS-OpenType flag)       */
+        sal_uInt16 fsSelection;   /**< OS/2 fsSelection */
     } TTGlobalFontInfo;
 
 #define TYPEFLAG_INVALID        0x8000000
@@ -521,8 +515,6 @@ namespace vcl
 /*- private definitions */
 
     struct TrueTypeFont {
-        sal_uInt32 tag;
-
         char        *fname;
         sal_Int32   fsize;
         sal_uInt8   *ptr;
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 150b21ec676a..e6bfd7509da3 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -39,7 +39,7 @@
 #include "xlat.hxx"
 #include <rtl/crc.h>
 #include <rtl/ustring.hxx>
-
+#include <o3tl/safeint.hxx>
 #include <osl/endian.h>
 #include <algorithm>
 
@@ -104,9 +104,6 @@ typedef struct {
     sal_uInt32 *offs;             /* array of nGlyphs offsets */
 } GlyphOffsets;
 
-/* private tags */
-static const sal_uInt32 TTFontClassTag = 0x74746663;  /* 'ttfc' */
-
 static const sal_uInt32 T_true = 0x74727565;        /* 'true' */
 static const sal_uInt32 T_ttcf = 0x74746366;        /* 'ttcf' */
 static const sal_uInt32 T_otto = 0x4f54544f;        /* 'OTTO' */
@@ -1341,6 +1338,13 @@ static void FindCmap(TrueTypeFont *ttf)
     }
 
     if (ttf->cmapType != CMAP_NOT_USABLE) {
+        if( (ttf->cmap - ttf->ptr + 2U) > static_cast<sal_uInt32>(ttf->fsize) ) {
+            ttf->cmapType = CMAP_NOT_USABLE;
+            ttf->cmap = nullptr;
+        }
+    }
+
+    if (ttf->cmapType != CMAP_NOT_USABLE) {
         switch (GetUInt16(ttf->cmap, 0, 1)) {
             case 0: ttf->mapper = getGlyph0; break;
             case 2: ttf->mapper = getGlyph2; break;
@@ -1461,7 +1465,6 @@ static void allocTrueTypeFont( TrueTypeFont** ttf )
     *ttf = static_cast<TrueTypeFont*>(calloc(1,sizeof(TrueTypeFont)));
     if( *ttf != nullptr )
     {
-        (*ttf)->tag = 0;
         (*ttf)->fname = nullptr;
         (*ttf)->fsize = -1;
         (*ttf)->ptr = nullptr;
@@ -1546,10 +1549,41 @@ int OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, T
     return doOpenTTFont( facenum, *ttf );
 }
 
+namespace {
+
+bool withinBounds(sal_uInt32 tdoffset, sal_uInt32 moreoffset, sal_uInt32 len, sal_uInt32 available)
+{
+    sal_uInt32 result;
+    if (o3tl::checked_add(tdoffset, moreoffset, result))
+        return false;
+    if (o3tl::checked_add(result, len, result))
+        return false;
+    return result <= available;
+}
+
+class TTFontCloser
+{
+    TrueTypeFont* m_font;
+public:
+    TTFontCloser(TrueTypeFont* t)
+        : m_font(t)
+    {
+    }
+    void clear() { m_font = nullptr; }
+    ~TTFontCloser()
+    {
+        if (m_font)
+            CloseTTFont(m_font);
+    }
+};
+
+}
+
 static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
 {
+    TTFontCloser aCloseGuard(t);
+
     if (t->fsize < 4) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
     int i;
@@ -1563,27 +1597,28 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     } else if (TTCTag == T_otto) {                         /* PS-OpenType font */
         tdoffset = 0;
     } else if (TTCTag == T_ttcf) {                         /* TrueType collection */
+        if (!withinBounds(12, 4 * facenum, sizeof(sal_uInt32), t->fsize)) {
+            return SF_FONTNO;
+        }
         sal_uInt32 Version = GetUInt32(t->ptr, 4, 1);
         if (Version != 0x00010000 && Version != 0x00020000) {
-            CloseTTFont(t);
             return SF_TTFORMAT;
         }
         if (facenum >= GetUInt32(t->ptr, 8, 1)) {
-            CloseTTFont(t);
             return SF_FONTNO;
         }
         tdoffset = GetUInt32(t->ptr, 12 + 4 * facenum, 1);
     } else {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
-    /* magic number */
-    t->tag = TTFontClassTag;
+    if (withinBounds(tdoffset, 0, 4 + sizeof(sal_uInt16), t->fsize)) {
+        t->ntables = GetUInt16(t->ptr + tdoffset, 4, 1);
+    }
 
-    t->ntables = GetUInt16(t->ptr + tdoffset, 4, 1);
-    if( t->ntables >= 128 )
+    if (t->ntables >= 128 || t->ntables == 0) {
         return SF_TTFORMAT;
+    }
 
     t->tables = static_cast<const sal_uInt8**>(calloc(NUM_TAGS, sizeof(sal_uInt8 *)));
     assert(t->tables != nullptr);
@@ -1595,7 +1630,7 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         int nIndex;
         const sal_uInt32 nStart = tdoffset + 12;
         const sal_uInt32 nOffset = 16 * i;
-        if (nStart + nOffset + sizeof(sal_uInt32) <=  static_cast<sal_uInt32>(t->fsize))
+        if (withinBounds(nStart, nOffset, sizeof(sal_uInt32), t->fsize))
             tag = GetUInt32(t->ptr + nStart, nOffset, 1);
         else
             tag = static_cast<sal_uInt32>(-1);
@@ -1620,9 +1655,10 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
             case T_CFF:  nIndex = O_CFF; break;
             default: nIndex = -1; break;
         }
-        if( nIndex >= 0 ) {
-            sal_uInt32 nTableOffset = GetUInt32(t->ptr + tdoffset + 12, 16 * i + 8, 1);
-            length = GetUInt32(t->ptr + tdoffset + 12, 16 * i + 12, 1);
+
+        if ((nIndex >= 0) && withinBounds(nStart, nOffset, 12 + sizeof(sal_uInt32), t->fsize)) {
+            sal_uInt32 nTableOffset = GetUInt32(t->ptr + nStart, nOffset + 8, 1);
+            length = GetUInt32(t->ptr + nStart, nOffset + 12, 1);
             t->tables[nIndex] = t->ptr + nTableOffset;
             t->tlens[nIndex] = length;
         }
@@ -1631,8 +1667,9 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     /* Fixup offsets when only a TTC extract was provided */
     if( facenum == (sal_uInt32)~0 ) {
         sal_uInt8* pHead = const_cast<sal_uInt8*>(t->tables[O_head]);
-        if( !pHead )
+        if (!pHead) {
             return SF_TTFORMAT;
+        }
         /* limit Head candidate to TTC extract's limits */
         if( pHead > t->ptr + (t->fsize - 54) )
             pHead = t->ptr + (t->fsize - 54);
@@ -1648,8 +1685,9 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
                 break;
             }
         }
-        if( p <= t->ptr )
+        if (p <= t->ptr) {
             return SF_TTFORMAT;
+        }
     }
 
     /* Check the table offsets after TTC correction */
@@ -1671,7 +1709,7 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         }
         else if( const_cast<sal_uInt8*>(t->tables[i]) + t->tlens[i] > t->ptr + t->fsize )
         {
-            int nMaxLen = (t->ptr + t->fsize) - t->tables[i];
+            sal_PtrDiff nMaxLen = (t->ptr + t->fsize) - t->tables[i];
             if( nMaxLen < 0 )
                 nMaxLen = 0;
             t->tlens[i] = nMaxLen;
@@ -1689,7 +1727,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
      */
 
     if( !(getTable(t, O_maxp) && getTable(t, O_head) && getTable(t, O_name) && getTable(t, O_cmap)) ) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
@@ -1700,14 +1737,12 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     table = getTable(t, O_head);
     table_size = getTableSize(t, O_head);
     if (table_size < 52) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
     t->unitsPerEm = GetUInt16(table, 18, 1);
     int indexfmt = GetInt16(table, 50, 1);
 
     if( ((indexfmt != 0) && (indexfmt != 1)) || (t->unitsPerEm <= 0) ) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
@@ -1731,7 +1766,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         /* TODO: implement to get subsetting */
         assert(t->goffsets != nullptr);
     } else {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
@@ -1748,6 +1782,8 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     GetKern(t);
     ReadGSUB( t, 0, 0 );
 
+    aCloseGuard.clear();
+
     return SF_OK;
 }
 
@@ -2590,13 +2626,6 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
             if( info->winDescent > 5*UPEm )
                 info->winDescent = XUnits(UPEm, GetInt16(table, 76,1));
         }
-        if (ttf->cmapType == CMAP_MS_Unicode) {
-            info->rangeFlag = 1;
-            info->ur1 = GetUInt32(table, 42, 1);
-            info->ur2 = GetUInt32(table, 46, 1);
-            info->ur3 = GetUInt32(table, 50, 1);
-            info->ur4 = GetUInt32(table, 54, 1);
-        }
         memcpy(info->panose, table + 32, 10);
         info->typeFlags = GetUInt16( table, 8, 1 );
         if( getTable(ttf, O_CFF) )
@@ -2610,24 +2639,24 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
     }
 
     table = getTable(ttf, O_head);      /* 'head' tables is always there */
-    info->xMin = XUnits(UPEm, GetInt16(table, 36, 1));
-    info->yMin = XUnits(UPEm, GetInt16(table, 38, 1));
-    info->xMax = XUnits(UPEm, GetInt16(table, 40, 1));
-    info->yMax = XUnits(UPEm, GetInt16(table, 42, 1));
-    info->macStyle = GetInt16(table, 44, 1);
+    table_size = getTableSize(ttf, O_head);
+    if (table_size >= 46) {
+        info->xMin = XUnits(UPEm, GetInt16(table, 36, 1));
+        info->yMin = XUnits(UPEm, GetInt16(table, 38, 1));
+        info->xMax = XUnits(UPEm, GetInt16(table, 40, 1));
+        info->yMax = XUnits(UPEm, GetInt16(table, 42, 1));
+        info->macStyle = GetInt16(table, 44, 1);
+    }
 
     table = getTable(ttf, O_hhea);
-    if (table) {
+    table_size = getTableSize(ttf, O_hhea);
+    if (table && table_size >= 10) {
         info->ascender  = XUnits(UPEm, GetInt16(table, 4, 1));
         info->descender = XUnits(UPEm, GetInt16(table, 6, 1));
         info->linegap   = XUnits(UPEm, GetInt16(table, 8, 1));
     }
 
     table = getTable(ttf, O_vhea);
-    if (table) {
-        info->vascent  = XUnits(UPEm, GetInt16(table, 4, 1));
-        info->vdescent = XUnits(UPEm, GetInt16(table, 6, 1));
-    }
 }
 
 GlyphData *GetTTRawGlyphData(TrueTypeFont *ttf, sal_uInt32 glyphID)
commit 3084ad15a03093e09fdb4e6502cdcf92924888b2
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 15:50:35 2018 +0000

    check O_head size
    
    Change-Id: Idf5d30eaed0196cfa9266e35131c538c606a0960
    Reviewed-on: https://gerrit.libreoffice.org/49365
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit b10ae2faae6f3c448bbab71585550387e18cc248)
    Reviewed-on: https://gerrit.libreoffice.org/49367
    Reviewed-by: Michael Stahl <mstahl at redhat.com>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index b34037ebdba1..150b21ec676a 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1555,7 +1555,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     int i;
     sal_uInt32 length, tag;
     sal_uInt32 tdoffset = 0;        /* offset to TableDirectory in a TTC file. For TTF files is 0 */
-    int indexfmt;
 
     sal_uInt32 TTCTag = GetInt32(t->ptr, 0, 1);
 
@@ -1699,8 +1698,13 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     t->nglyphs = table_size >= 6 ? GetUInt16(table, 4, 1) : 0;
 
     table = getTable(t, O_head);
+    table_size = getTableSize(t, O_head);
+    if (table_size < 52) {
+        CloseTTFont(t);
+        return SF_TTFORMAT;
+    }
     t->unitsPerEm = GetUInt16(table, 18, 1);
-    indexfmt = GetInt16(table, 50, 1);
+    int indexfmt = GetInt16(table, 50, 1);
 
     if( ((indexfmt != 0) && (indexfmt != 1)) || (t->unitsPerEm <= 0) ) {
         CloseTTFont(t);
commit 0939dc7eb4de0f4f2c323322cbe7f887937335c1
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 16:44:43 2018 +0000

    check O_hhea and O_vhea sizes
    
    Change-Id: I82e47732815f0112801c8c3a3e5b0b09ac25610a
    Reviewed-on: https://gerrit.libreoffice.org/49439
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index d97be8071272..b34037ebdba1 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1548,8 +1548,10 @@ int OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, T
 
 static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
 {
-    if (t->fsize < 4)
+    if (t->fsize < 4) {
+        CloseTTFont(t);
         return SF_TTFORMAT;
+    }
     int i;
     sal_uInt32 length, tag;
     sal_uInt32 tdoffset = 0;        /* offset to TableDirectory in a TTC file. For TTF files is 0 */
@@ -1730,10 +1732,12 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     }
 
     table = getTable(t, O_hhea);
-    t->numberOfHMetrics = (table != nullptr) ? GetUInt16(table, 34, 1) : 0;
+    table_size = getTableSize(t, O_hhea);
+    t->numberOfHMetrics = (table && table_size >= 36) ? GetUInt16(table, 34, 1) : 0;
 
     table = getTable(t, O_vhea);
-    t->numOfLongVerMetrics = (table != nullptr) ? GetUInt16(table, 34, 1) : 0;
+    table_size = getTableSize(t, O_vhea);
+    t->numOfLongVerMetrics = (table && table_size >= 36) ? GetUInt16(table, 34, 1) : 0;
 
     GetNames(t);
     FindCmap(t);
commit 038175f960401e0be0a26e74c9c0c5ff052c31fd
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 15:33:36 2018 +0000

    check table size before reading nglyphs
    
    Change-Id: Ib511fdf16006877ca76085137eb9200601b2f8f7
    Reviewed-on: https://gerrit.libreoffice.org/49363
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 08dd51bfcaa6b493e134bcc7787cc18c36ad5db1)
    Reviewed-on: https://gerrit.libreoffice.org/49436
    Reviewed-by: Michael Stahl <mstahl at redhat.com>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 0e0978b779c0..d97be8071272 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1693,7 +1693,8 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     }
 
     const sal_uInt8* table = getTable(t, O_maxp);
-    t->nglyphs = GetUInt16(table, 4, 1);
+    sal_uInt32 table_size = getTableSize(t, O_maxp);
+    t->nglyphs = table_size >= 6 ? GetUInt16(table, 4, 1) : 0;
 
     table = getTable(t, O_head);
     t->unitsPerEm = GetUInt16(table, 18, 1);
commit d5a86c604c7c3ff459be28521f7689742e0545db
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 16:20:54 2018 +0000

    return early on short stream
    
    Change-Id: Ia9cb4dec5358281322a2428c5f2153836a1ee1af
    Reviewed-on: https://gerrit.libreoffice.org/49375
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index cc4893216d3d..0e0978b779c0 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1548,6 +1548,8 @@ int OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, T
 
 static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
 {
+    if (t->fsize < 4)
+        return SF_TTFORMAT;
     int i;
     sal_uInt32 length, tag;
     sal_uInt32 tdoffset = 0;        /* offset to TableDirectory in a TTC file. For TTF files is 0 */
commit 9b543d51907d1311ecfac59bbd66fdd667a0da90
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 16:05:08 2018 +0000

    stay within font bounds
    
    Change-Id: Ie8ed610b71cb1b20963827c2be97155d2d8aa22c
    Reviewed-on: https://gerrit.libreoffice.org/49371
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index dfe66eb5d58c..cc4893216d3d 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1590,7 +1590,12 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     /* parse the tables */
     for (i=0; i<(int)t->ntables; i++) {
         int nIndex;
-        tag = GetUInt32(t->ptr + tdoffset + 12, 16 * i, 1);
+        const sal_uInt32 nStart = tdoffset + 12;
+        const sal_uInt32 nOffset = 16 * i;
+        if (nStart + nOffset + sizeof(sal_uInt32) <=  static_cast<sal_uInt32>(t->fsize))
+            tag = GetUInt32(t->ptr + nStart, nOffset, 1);
+        else
+            tag = static_cast<sal_uInt32>(-1);
         switch( tag ) {
             case T_maxp: nIndex = O_maxp; break;
             case T_glyf: nIndex = O_glyf; break;
commit f0e086f0e9646ddfcdc30d44c03b5287351464da
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 16:51:32 2018 +0000

    what matters is the availability of the last element, not the first
    
    Change-Id: I23d3abdbe62b735d66261fb337613da88cc4206b
    Reviewed-on: https://gerrit.libreoffice.org/49380
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Michael Stahl <mstahl at redhat.com>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 3378b35344e8..dfe66eb5d58c 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -2553,7 +2553,8 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
     info->symbolEncoded = (ttf->cmapType == CMAP_MS_Symbol);
 
     const sal_uInt8* table = getTable(ttf, O_OS2);
-    if (table) {
+    sal_uInt32 table_size = getTableSize(ttf, O_OS2);
+    if (table && table_size >= 42) {
         info->weight = GetUInt16(table, 4, 1);
         info->width  = GetUInt16(table, 6, 1);
 
@@ -2561,12 +2562,13 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
          * Microsoft old (78 bytes long) and Microsoft new (86 bytes long,)
          * Apple's documentation recommends looking at the table length.
          */
-        if (getTableSize(ttf, O_OS2) > 68) {
+        if (table_size >= 78) {
             info->typoAscender = XUnits(UPEm,GetInt16(table, 68, 1));
             info->typoDescender = XUnits(UPEm, GetInt16(table, 70, 1));
             info->typoLineGap = XUnits(UPEm, GetInt16(table, 72, 1));
             info->winAscent = XUnits(UPEm, GetUInt16(table, 74, 1));
             info->winDescent = XUnits(UPEm, GetUInt16(table, 76, 1));
+
             /* sanity check; some fonts treat winDescent as signed
            * violating the standard */
             if( info->winDescent > 5*UPEm )
commit 23d53ae3a51dde89a8d40b05841232527480a4bc
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 16:57:27 2018 +0000

    check kern table size
    
    Change-Id: I65b5f0a8950d54c00d6fd7c385ca1c5dca2ef2c8
    Reviewed-on: https://gerrit.libreoffice.org/49384
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 0d24beaf4428..3378b35344e8 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1368,7 +1368,7 @@ static void GetKern(TrueTypeFont *ttf)
     if( !table )
         goto badtable;
 
-    if (GetUInt16(table, 0, 1) == 0) {                                /* Traditional Microsoft style table with sal_uInt16 version and nTables fields */
+    if (nTableSize >= 4 && GetUInt16(table, 0, 1) == 0) { /* Traditional Microsoft style table with sal_uInt16 version and nTables fields */
         ttf->nkern = GetUInt16(table, 2, 1);
         ttf->kerntype = KT_MICROSOFT;
         ptr = table + 4;
@@ -1400,7 +1400,7 @@ static void GetKern(TrueTypeFont *ttf)
         return;
     }
 
-    if (GetUInt32(table, 0, 1) == 0x00010000) {                       /* MacOS style kern tables: fixed32 version and sal_uInt32 nTables fields */
+    if (nTableSize >= 8 && GetUInt32(table, 0, 1) == 0x00010000) { /* MacOS style kern tables: fixed32 version and sal_uInt32 nTables fields */
         ttf->nkern = GetUInt32(table, 4, 1);
         ttf->kerntype = KT_APPLE_NEW;
         ptr = table + 8;
commit 91590515fc5261e506892a94dc8d1e6429cffa1e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 12:29:32 2018 +0000

    sanity check cmap table size
    
    Change-Id: I010c2fd221bcd86a62efd9996a0c34930828cb6d
    Reviewed-on: https://gerrit.libreoffice.org/49350
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 2385d2676033..0d24beaf4428 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1245,6 +1245,12 @@ static void FindCmap(TrueTypeFont *ttf)
 {
     const sal_uInt8* table = getTable(ttf, O_cmap);
     sal_uInt32 table_size = getTableSize(ttf, O_cmap);
+    if (table_size < 4)
+    {
+        SAL_WARN("vcl.fonts", "Parsing error in " << OUString::createFromAscii(ttf->fname) <<
+                 "cmap table size too short");
+        return;
+    }
     sal_uInt16 ncmaps = GetUInt16(table, 2, 1);
     sal_uInt32 AppleUni   = 0;              // Apple Unicode
     sal_uInt32 ThreeZero  = 0;              /* MS Symbol            */


More information about the Libreoffice-commits mailing list