untrusted comment: verify with openbsd-74-base.pub
RWRoyQmAD08ajR5JBhxE3D47WqXNCKkmFDM1XUy3njosoXABCHB50KDtrTO7Lrh6uvNaz542ati8c2Jd9PZrO40b7JQO96QFEAE=

OpenBSD 7.4 errata 007, November 29, 2023:

A crafted regular expression when compiled by perl can cause a
one-byte attacker controlled buffer overflow in a heap allocated
buffer. CVE-2023-47038

Apply by doing:
   signify -Vep /etc/signify/openbsd-74-base.pub -x 007_perl.patch.sig \
       -m - | (cd /usr/src && patch -p0)

And then rebuild and install perl:
   cd /usr/src/gnu/usr.bin/perl/
   make -f Makefile.bsd-wrapper obj
   make -f Makefile.bsd-wrapper
   make -f Makefile.bsd-wrapper install

Index: gnu/usr.bin/perl/regcomp.c
===================================================================
RCS file: /cvs/src/gnu/usr.bin/perl/regcomp.c,v
diff -u -p -r1.33 regcomp.c
--- gnu/usr.bin/perl/regcomp.c  15 Feb 2023 01:38:21 -0000      1.33
+++ gnu/usr.bin/perl/regcomp.c  26 Nov 2023 16:59:18 -0000
@@ -24250,7 +24250,7 @@ S_parse_uniprop_string(pTHX_
     * compile perl to know about them) */
    bool is_nv_type = FALSE;

-    unsigned int i, j = 0;
+    unsigned int i = 0, i_zero = 0, j = 0;
    int equals_pos = -1;    /* Where the '=' is found, or negative if none */
    int slash_pos  = -1;    /* Where the '/' is found, or negative if none */
    int table_index = 0;    /* The entry number for this property in the table
@@ -24384,9 +24384,13 @@ S_parse_uniprop_string(pTHX_
     * all of them are considered to be for that package.  For the purposes of
     * parsing the rest of the property, strip it off */
    if (non_pkg_begin == STRLENs("utf8::") && memBEGINPs(name, name_len, "utf8::")) {
-        lookup_name +=  STRLENs("utf8::");
-        j -=  STRLENs("utf8::");
-        equals_pos -=  STRLENs("utf8::");
+        lookup_name += STRLENs("utf8::");
+        j           -= STRLENs("utf8::");
+        equals_pos  -= STRLENs("utf8::");
+        i_zero       = STRLENs("utf8::");   /* When resetting 'i' to reparse
+                                               from the beginning, it has to be
+                                               set past what we're stripping
+                                               off */
        stripped_utf8_pkg = TRUE;
    }

@@ -24800,7 +24804,8 @@ S_parse_uniprop_string(pTHX_

            /* We set the inputs back to 0 and the code below will reparse,
             * using strict */
-            i = j = 0;
+            i = i_zero;
+            j = 0;
        }
    }

@@ -24821,7 +24826,7 @@ S_parse_uniprop_string(pTHX_
         * separates two digits */
        if (cur == '_') {
            if (    stricter
-                && (     i == 0 || (int) i == equals_pos || i == name_len- 1
+                && (   i == i_zero || (int) i == equals_pos || i == name_len- 1
                    || ! isDIGIT_A(name[i-1]) || ! isDIGIT_A(name[i+1])))
            {
                lookup_name[j++] = '_';