Subject: Re: bug#53011: Possible to Update qtbase-5 to v5.15.8?

From: Jaft <[email-masked]>
Date: Wed, 2 Feb 2022 19:15:54 +0000 (UTC)

I don't know if it's the best method to handle this but I tried just applying the patch manually with substitute*s.
Whatever point the codebase in the patch is, what's being pulled down by Guix doesn't seem to be there yet as one of the files was entirely missing but adding the file manually didn't seem to disturb anything and everything was able to build alright, for me.
I'm now typing this from Qutebrowser, built with my altered QTwebengine, and I've got proper text rendering (at least, for the sites I first noticed text rendering failing at and sites that had worked properly, to begin with).
    On Wednesday, January 5, 2022, 01:09:58 PM CST, Leo Famulari <[email-masked]> wrote:  
 
 On Wed, Jan 05, 2022 at 02:08:08PM -0500, Leo Famulari wrote:
> On Tue, Jan 04, 2022 at 07:04:57PM +0100, Florian Bruhin wrote:
> > Alternatively, to fix the issues with missing text, backporting this
> > patch should suffice:
> > https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/374232
> 
> I'm testing this now.

Oh, the patch does not apply to the source code of our qtwebengine
package. So, I hope that somebody else will take a look and try to fix
this bug.

* gnu/packages/qt.scm (qtwebengine): Backport fix for text rendering.
---
gnu/packages/qt.scm | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 286 insertions(+)
diff --git a/gnu/packages/qt.scm b/gnu/packages/qt.scm
index ca97725052..111e068094 100644
--- a/gnu/packages/qt.scm
+++ b/gnu/packages/qt.scm
@@ -1878,6 +1878,292 @@ (define (delete-unwanted-files child stat flag base level)
                                       ;; Respect the '--cores' option of 'guix build'.
                                       " -j" (number->string (parallel-job-count))))
                #t))
+           ;; Backport
+           ;; https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/374232
+           ;; to fix broken text rendering.
+           ;; The patch couldn't be applied directly as it does not apply to
+           ;; the source code of our qtwebengine package
+           (add-before 'configure 'fix-text-rendering
+             (lambda _
+               (let ((output-port (open-file "src/3rdparty/chromium/sandbox/linux/system_headers/linux_stat.h" "a")))
+                 (display "// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_STAT_H_
+#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_STAT_H_
+
+#include <stdint.h>
+
+#include \"build/build_config.h\"
+#include \"sandbox/linux/system_headers/linux_syscalls.h\"
+
+#if defined(ARCH_CPU_MIPS_FAMILY)
+#if defined(ARCH_CPU_64_BITS)
+struct kernel_stat {
+#else
+struct kernel_stat64 {
+#endif
+  unsigned st_dev;
+  unsigned __pad0[3];
+  unsigned long long st_ino;
+  unsigned st_mode;
+  unsigned st_nlink;
+  unsigned st_uid;
+  unsigned st_gid;
+  unsigned st_rdev;
+  unsigned __pad1[3];
+  long long st_size;
+  unsigned st_atime_;
+  unsigned st_atime_nsec_;
+  unsigned st_mtime_;
+  unsigned st_mtime_nsec_;
+  unsigned st_ctime_;
+  unsigned st_ctime_nsec_;
+  unsigned st_blksize;
+  unsigned __pad2;
+  unsigned long long st_blocks;
+};
+#else
+struct kernel_stat64 {
+  unsigned long long st_dev;
+  unsigned char __pad0[4];
+  unsigned __st_ino;
+  unsigned st_mode;
+  unsigned st_nlink;
+  unsigned st_uid;
+  unsigned st_gid;
+  unsigned long long st_rdev;
+  unsigned char __pad3[4];
+  long long st_size;
+  unsigned st_blksize;
+  unsigned long long st_blocks;
+  unsigned st_atime_;
+  unsigned st_atime_nsec_;
+  unsigned st_mtime_;
+  unsigned st_mtime_nsec_;
+  unsigned st_ctime_;
+  unsigned st_ctime_nsec_;
+  unsigned long long st_ino;
+};
+#endif
+
+#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
+struct kernel_stat {
+  /* The kernel headers suggest that st_dev and st_rdev should be 32bit
+   * quantities encoding 12bit major and 20bit minor numbers in an interleaved
+   * format. In reality, we do not see useful data in the top bits. So,
+   * we'll leave the padding in here, until we find a better solution.
+   */
+  unsigned short st_dev;
+  short pad1;
+  unsigned st_ino;
+  unsigned short st_mode;
+  unsigned short st_nlink;
+  unsigned short st_uid;
+  unsigned short st_gid;
+  unsigned short st_rdev;
+  short pad2;
+  unsigned st_size;
+  unsigned st_blksize;
+  unsigned st_blocks;
+  unsigned st_atime_;
+  unsigned st_atime_nsec_;
+  unsigned st_mtime_;
+  unsigned st_mtime_nsec_;
+  unsigned st_ctime_;
+  unsigned st_ctime_nsec_;
+  unsigned __unused4;
+  unsigned __unused5;
+};
+#elif defined(__x86_64__)
+struct kernel_stat {
+  uint64_t st_dev;
+  uint64_t st_ino;
+  uint64_t st_nlink;
+  unsigned st_mode;
+  unsigned st_uid;
+  unsigned st_gid;
+  unsigned __pad0;
+  uint64_t st_rdev;
+  int64_t st_size;
+  int64_t st_blksize;
+  int64_t st_blocks;
+  uint64_t st_atime_;
+  uint64_t st_atime_nsec_;
+  uint64_t st_mtime_;
+  uint64_t st_mtime_nsec_;
+  uint64_t st_ctime_;
+  uint64_t st_ctime_nsec_;
+  int64_t __unused4[3];
+};
+#elif (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
+struct kernel_stat {
+  unsigned st_dev;
+  int st_pad1[3];
+  unsigned st_ino;
+  unsigned st_mode;
+  unsigned st_nlink;
+  unsigned st_uid;
+  unsigned st_gid;
+  unsigned st_rdev;
+  int st_pad2[2];
+  long st_size;
+  int st_pad3;
+  long st_atime_;
+  long st_atime_nsec_;
+  long st_mtime_;
+  long st_mtime_nsec_;
+  long st_ctime_;
+  long st_ctime_nsec_;
+  int st_blksize;
+  int st_blocks;
+  int st_pad4[14];
+};
+#elif defined(__aarch64__)
+struct kernel_stat {
+  unsigned long st_dev;
+  unsigned long st_ino;
+  unsigned int st_mode;
+  unsigned int st_nlink;
+  unsigned int st_uid;
+  unsigned int st_gid;
+  unsigned long st_rdev;
+  unsigned long __pad1;
+  long st_size;
+  int st_blksize;
+  int __pad2;
+  long st_blocks;
+  long st_atime_;
+  unsigned long st_atime_nsec_;
+  long st_mtime_;
+  unsigned long st_mtime_nsec_;
+  long st_ctime_;
+  unsigned long st_ctime_nsec_;
+  unsigned int __unused4;
+  unsigned int __unused5;
+};
+#endif
+
+#if !defined(AT_EMPTY_PATH)
+#define AT_EMPTY_PATH 0x1000
+#endif
+
+// On 32-bit systems, we default to the 64-bit stat struct like libc
+// implementations do. Otherwise we default to the normal stat struct which is
+// already 64-bit.
+// These defines make it easy to call the right syscall to fill out a 64-bit
+// stat struct, which is the default in libc implementations but requires
+// different syscall names on 32 and 64-bit platforms.
+#if defined(__NR_fstatat64)
+
+namespace sandbox {
+using default_stat_struct = struct kernel_stat64;
+}  // namespace sandbox
+
+#define __NR_fstatat_default __NR_fstatat64
+#define __NR_fstat_default __NR_fstat64
+
+#elif defined(__NR_newfstatat)
+
+namespace sandbox {
+using default_stat_struct = struct kernel_stat;
+}  // namespace sandbox
+
+#define __NR_fstatat_default __NR_newfstatat
+#define __NR_fstat_default __NR_fstat
+
+#else
+#error \"one of fstatat64 and newfstatat must be defined\"
+#endif
+
+#endif  // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_STAT_H_
+" output-port)
+
+                 (close output-port))
+
+               (substitute* "src/3rdparty/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc"
+                 (("#include \"sandbox/linux/services/syscall_wrappers\\.h\"")
+                  "#include \"sandbox/linux/services/syscall_wrappers.h\"
+#include \"sandbox/linux/system_headers/linux_stat.h\"")
+                 (("if [(]SyscallSets::IsFileSystem[(]sysno[)] [|][|]")
+                  "if (sysno == __NR_fstatat_default) {
+    return RewriteFstatatSIGSYS(fs_denied_errno);
+  }
+
+  if (SyscallSets::IsFileSystem(sysno) ||"))
+
+               (substitute* "src/3rdparty/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc"
+                 (("BPF_ASSERT[(]S_ISFIFO[(]stat_buf\\.st_mode[)] [|][|] S_ISSOCK[(]stat_buf\\.st_mode[)][)];")
+                  "BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode));
+
+  sys_ret = fstatat(read_end.get(), \"\", &stat_buf, AT_EMPTY_PATH);
+  BPF_ASSERT_EQ(0, sys_ret);
+  BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode));
+
+  // Make sure fstatat with anything other than an empty string is denied.
+  sys_ret = fstatat(read_end.get(), \"/\", &stat_buf, AT_EMPTY_PATH);
+  BPF_ASSERT_EQ(sys_ret, -1);
+  BPF_ASSERT_EQ(EPERM, errno);
+
+  // Make sure fstatat without AT_EMPTY_PATH is denied.
+  sys_ret = fstatat(read_end.get(), \"\", &stat_buf, 0);
+  BPF_ASSERT_EQ(sys_ret, -1);
+  BPF_ASSERT_EQ(EPERM, errno);"))
+
+               (substitute* "src/3rdparty/chromium/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
+                 (("// Variants of the above functions for use with bpf_dsl\\.")
+                  "SANDBOX_EXPORT intptr_t
+SIGSYSFstatatHandler(const struct arch_seccomp_data& args,
+                     void* fs_denied_errno);
+
+// Variants of the above functions for use with bpf_dsl.")
+                 (("SANDBOX_EXPORT bpf_dsl::ResultExpr RewriteSchedSIGSYS[(][)];")
+                  "SANDBOX_EXPORT bpf_dsl::ResultExpr RewriteSchedSIGSYS();
+SANDBOX_EXPORT bpf_dsl::ResultExpr RewriteFstatatSIGSYS(int fs_denied_errno);"))
+
+               (substitute* "src/3rdparty/chromium/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc"
+                 (("#include <stddef\\.h>")
+                  "#include <fcntl.h>
+#include <stddef.h>")
+                 (("#include \"sandbox/linux/system_headers/linux_syscalls\\.h\"")
+                  "#include \"sandbox/linux/system_headers/linux_stat.h\"
+#include \"sandbox/linux/system_headers/linux_syscalls.h\"")
+                 (("bpf_dsl::ResultExpr CrashSIGSYS[(][)] [{]")
+                  "intptr_t SIGSYSFstatatHandler(const struct arch_seccomp_data& args,
+                              void* fs_denied_errno) {
+  if (args.nr == __NR_fstatat_default) {
+    if (*reinterpret_cast<const char*>(args.args[1]) == '\0' &&
+        args.args[3] == static_cast<uint64_t>(AT_EMPTY_PATH)) {
+      return syscall(__NR_fstat_default, static_cast<int>(args.args[0]),
+                     reinterpret_cast<default_stat_struct*>(args.args[2]));
+    }
+    return -reinterpret_cast<intptr_t>(fs_denied_errno);
+  }
+
+  CrashSIGSYS_Handler(args, fs_denied_errno);
+
+  // Should never be reached.
+  RAW_CHECK(false);
+  return -ENOSYS;
+}
+
+bpf_dsl::ResultExpr CrashSIGSYS() {")
+                 (("void AllocateCrashKeys[(][)] [{]")
+                  "bpf_dsl::ResultExpr RewriteFstatatSIGSYS(int fs_denied_errno) {
+  return bpf_dsl::Trap(SIGSYSFstatatHandler,
+                       reinterpret_cast<void*>(fs_denied_errno));
+}
+
+void AllocateCrashKeys() {"))
+
+               (substitute* "src/3rdparty/chromium/sandbox/linux/syscall_broker/broker_process.cc"
+                 (("#if !defined[(]__aarch64__[)]")
+                  "#if !defined(__aarch64__) && !defined(OS_ANDROID)"))
+
+               (substitute* "src/3rdparty/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc"
+                 (("#if !defined[(]__aarch64__[)]")
+                  "#if !defined(__aarch64__) && !defined(OS_ANDROID)"))))
            (replace 'configure
              (lambda _
                ;; Valid QT_BUILD_PARTS variables are: