Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package perl-Clone for openSUSE:Factory 
checked in at 2026-04-10 17:42:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Clone (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Clone.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Clone"

Fri Apr 10 17:42:59 2026 rev:35 rq:1345212 version:0.500.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Clone/perl-Clone.changes    2026-03-13 
21:15:47.458829132 +0100
+++ /work/SRC/openSUSE:Factory/.perl-Clone.new.21863/perl-Clone.changes 
2026-04-10 17:43:05.989311868 +0200
@@ -1,0 +2,6 @@
+Sun Mar 29 06:21:35 UTC 2026 - Tina Müller <[email protected]>
+
+- updated to 0.500.0 (0.50)
+   see /usr/share/doc/packages/perl-Clone/Changes
+
+-------------------------------------------------------------------

Old:
----
  Clone-0.48.tar.gz

New:
----
  Clone-0.50.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Clone.spec ++++++
--- /var/tmp/diff_new_pack.mTA9Yl/_old  2026-04-10 17:43:06.605337198 +0200
+++ /var/tmp/diff_new_pack.mTA9Yl/_new  2026-04-10 17:43:06.605337198 +0200
@@ -18,10 +18,10 @@
 
 %define cpan_name Clone
 Name:           perl-Clone
-Version:        0.480.0
+Version:        0.500.0
 Release:        0
-# 0.48 -> normalize -> 0.480.0
-%define cpan_version 0.48
+# 0.50 -> normalize -> 0.500.0
+%define cpan_version 0.50
 License:        Artistic-1.0 OR GPL-1.0-or-later
 Summary:        Recursively copy Perl datatypes
 URL:            https://metacpan.org/release/%{cpan_name}
@@ -68,5 +68,5 @@
 %perl_gen_filelist
 
 %files -f %{name}.files
-%doc Changes README.md
+%doc AI_POLICY.md Changes README.md SECURITY.md
 

++++++ Clone-0.48.tar.gz -> Clone-0.50.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/AI_POLICY.md new/Clone-0.50/AI_POLICY.md
--- old/Clone-0.48/AI_POLICY.md 1970-01-01 01:00:00.000000000 +0100
+++ new/Clone-0.50/AI_POLICY.md 2026-03-28 06:23:00.000000000 +0100
@@ -0,0 +1,125 @@
+# AI Policy
+
+> **TL;DR** — AI tools assist our workflow at every stage. Humans remain in 
control of every decision, every review, and every release.
+
+---
+
+## Overview
+
+This document describes how artificial intelligence tools are used in the 
maintenance and development of this project. It is intended to be transparent 
with our contributors, users, and the broader open-source community about the 
role AI plays — and, equally importantly, the role it does **not** play.
+
+We believe in honest, clear communication about AI-assisted workflows. This 
policy will be updated as our practices evolve.
+
+---
+
+## Our Guiding Principle
+
+**AI assists. Humans decide.**
+
+The maintainers who have been stewarding this project for years remain fully 
responsible for every line of code that ships. AI tools extend our capacity to 
review, research, and improve — they do not replace human judgment, expertise, 
or accountability.
+
+---
+
+## How AI Is Used in This Project
+
+### 1. Code and Issue Analysis
+
+AI tools help us process and understand incoming issues, pull requests, and 
code changes at scale. This includes:
+
+- Summarising issue reports and identifying patterns across similar bugs
+- Analysing code diffs for potential problems, regressions, or style 
inconsistencies
+- Surfacing relevant context from the codebase, documentation, and prior 
discussions
+- Flagging potential security concerns for human review
+
+This analysis is **always** used as input to human decision-making, never as a 
substitute for it.
+
+### 2. Draft Pull Requests
+
+AI may generate draft pull requests as a starting point for a fix, a refactor, 
or an improvement. These drafts:
+
+- Are clearly labelled as AI-generated when created
+- Represent a first pass only — they are never considered complete or correct 
without human review
+- May be substantially reworked, rejected, or replaced entirely by maintainers
+
+Think of these drafts the way you would think of a junior contributor's first 
attempt: useful raw material that still needs experienced eyes.
+
+### 3. Human Review of Every Pull Request
+
+**Every pull request — whether AI-drafted or human-authored — is reviewed by a 
human maintainer before it can be merged.**
+
+During review, maintainers actively use AI as a tool to assist their own 
thinking:
+
+- Asking AI to explain or justify specific implementation choices
+- Challenging AI-generated code and requesting alternative approaches
+- Using AI to research edge cases, relevant standards, or upstream behaviour
+- Requesting targeted rewrites of individual sections based on review feedback
+
+The maintainer's judgment always takes precedence. AI answers are treated as 
input to be verified, not conclusions to be accepted.
+
+### 4. Test Coverage and Defect Detection
+
+AI helps us improve the quality and completeness of our test suite by:
+
+- Suggesting test cases for edge conditions and failure modes
+- Identifying gaps in existing test coverage
+- Proposing tests that target known classes of defects or security issues
+- Helping reproduce and characterise reported bugs
+
+All suggested tests are reviewed and validated by maintainers before being 
committed.
+
+### 5. Security Review
+
+AI tools assist in identifying potential security issues, including:
+
+- Common vulnerability patterns (injection, insecure defaults, deprecated 
APIs, etc.)
+- Dependencies with known CVEs
+- Code paths that may warrant closer scrutiny
+
+Security findings from AI are **always** verified by a human maintainer. We do 
not act on AI-flagged security issues without independent assessment.
+
+---
+
+## What AI Does Not Do
+
+To be explicit about the limits of AI involvement in this project:
+
+| ❌ AI does not… | ✅ A human maintainer does… |
+|---|---|
+| Approve or merge pull requests | Review and decide on every PR |
+| Make architectural decisions | Own all design and direction choices |
+| Triage and close issues autonomously | Assess and respond to all issues |
+| Publish releases | Tag, build, and release manually |
+| Represent the project publicly | Communicate on behalf of the project |
+
+---
+
+## Releases
+
+Releases are performed manually by the same long-standing maintainers as 
always. The release process — including changelog review, version tagging, and 
publication — uses standard Perl ecosystem tooling (e.g. ExtUtils::MakeMaker, 
Dist::Zilla, Module::Build) but involves no AI-driven automation. Every release 
is initiated, supervised, and published by a human maintainer.
+
+AI may assist in drafting changelogs or release notes, but these are always 
reviewed and edited before publication.
+
+---
+
+## Attribution and Transparency
+
+Where AI has played a material role in generating code or content within a 
pull request, we aim to note this in the PR description (e.g. via a 
`Generated-By` or `AI-Assisted` label or note). We do not consider AI the 
author of any contribution — the maintainer who reviewed and approved the work 
takes responsibility for it.
+
+---
+
+## Why We Do This
+
+Open-source software is built on trust. Our users and downstream dependants 
trust us to ship correct, secure, and well-considered code. AI tools help us do 
that work better — but they do not change who is responsible for the outcome.
+
+We use AI because it makes our maintainers more effective, not because it 
replaces them.
+
+---
+
+## Questions and Feedback
+
+If you have questions about our use of AI, or concerns about a specific pull 
request or change, please open an issue or start a discussion. We are committed 
to being open about our process.
+
+---
+
+*Last updated: 2026-03-23*
+*This policy is maintained by the project maintainers and subject to revision 
as AI tooling and community norms evolve.*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/Changes new/Clone-0.50/Changes
--- old/Clone-0.48/Changes      2026-03-03 00:01:44.219864224 +0100
+++ new/Clone-0.50/Changes      2026-03-28 07:11:45.000000000 +0100
@@ -1,6 +1,21 @@
 Revision history for Perl module Clone
 
-0.48 2026-03-02 16:02:00 atoomic
+0.50 2026-03-28 atoomic
+  - fix: deep-copy HVs past MAX_DEPTH instead of aliasing (GH #93)
+  - fix: strip macOS xattrs from dist directory before packaging
+  - cleanup: remove unreachable break and empty magic_ref if-body in Clone.xs
+  - docs: update MAX_DEPTH limits to reflect actual platform values
+  - docs: add SECURITY.md policy for vulnerability reporting
+  - Prefer using gtar in Makefile.PL
+
+0.49 2026-03-24 21:23:44 atoomic
+  - fix: exclude macOS extended attributes from dist tarball
+  - fix: suppress DBI STDERR noise in t/13-io-handle.t (GH #82)
+  - fix: skip DBI fork tests on Windows
+  - fix: remove spurious warn output in t/03-scalar.t
+  - Add AI_POLICY.md documenting AI-assisted workflow
+
+0.48 2026-03-02 16:01:53 atoomic
   - perf: optimize hot paths in Clone.xs
   - fix: replace subtest with SKIP/bare blocks to avoid Test2 warnings
   - fix: don't require MGf_DUP flag for ext magic duplication
@@ -26,69 +41,69 @@
   - Rename tests with more readable names
   - Remove TODO from cow test
 
-0.47 2024-08-17 12:30:00 atoomic
+0.47 2024-08-17 12:31:14 atoomic
   - Stop using quote as package separator
 
-0.46 2022-10-18 20:23:00 garu
+0.46 2022-10-18 20:27:26 garu
   - fix backwards compatibility with older perls (haarg)
   - bump MANIFEST to include extra tests
 
-0.45 2020-04-23 14:46:00 atoomic
+0.45 2020-04-23 14:44:50 atoomic
   - bump B::COW requirement to fix big-endian issue
 
-0.44 2020-04-20 11:30:00 atoomic
+0.44 2020-04-20 11:33:11 atoomic
   - support Perls with COW disabled (plicease)
   - bump B::COW requirement for testing
 
-0.43 2019-07-29 13:47:42  atoomic
+0.43 2019-07-29 13:49:04 atoomic
   - fix an issue when cloning a NULL mg_ptr pointer
 
-0.42 2019-07-19 23:06:04  garu
+0.42 2019-07-19 01:38:38 garu
   - make handling of mg_ptr safer (ATOOMIC, Harald Jörg)
   - change license wording on some test files to
     make the entire dist released under the same
     terms as Perl itself (fixes GH#20) (GARU)
 
-0.41 2018-10-25 10:20:03  garu
+0.41 2018-10-25 15:08:43 garu
   - Check the CowREFCNT of a COWed PV (ATOOMIC)
     this should fix some issues people have been
     having with 0.40 on DBD drives and DBIx::Class
   - Make buildtools files not executable (Mohammad S Anwar)
   - Move bugtracker to Github (GARU)
 
-0.40 2018-10-23 20:001:49  garu
+0.40 2018-10-23 20:03:07 garu
   - reuse COWed PV when cloning (fixes RT97535) (ATOOMIC)
   - extra protection against potential infinite loop (ATOOMIC)
   - improved tests
 
-0.39 2017-04-07 13:06:00  garu
+0.39 2017-04-07 13:21:36 garu
   - use explicit '.' in tests since it may not be in @INC
     anymore in newer perls (fixes RT120648) (PLICEASE, SIMCOP)
 
-0.38 2015-01-18 19:27:41  garu
+0.38 2015-01-18 19:34:45 garu
   - typo fixes and improvements to the README (zmughal)
   - travis/coveralls integration (zmughal)
 
-0.37 2014-05-15 16:45:33  garu
+0.37 2014-05-15 18:46:04 garu
   - removed Carp dependency (GARU)
   - silenced some clang warnings (JACQUESG)
   - added a README (GARU)
 
-0.36 2013-12-07 17:36:04  garu
+0.36 2013-12-07 17:33:43 garu
   - fixed compilation issue on AIX and C89 (GAAS)
 
-0.35 2013-09-05 13:26:54  garu
+0.35 2013-09-05 13:23:20 garu
   - SV's can be NULL (shit happens) (fixes RT86217) (HMBRAND)
   - making tests compatible with older versions of Test::More (GARU)
 
-0.34 2012-12-09 14:46:09  garu
+0.34 2012-12-09 19:19:02 garu
   - making some tests optional (fixes RT81774) (GARU)
   - modernizing synopsis (GARU)
 
-0.33  2012-11-24 11:37:22  garu
+0.33 2012-11-24 11:38:31 garu
   - fix typo in croak message (Salvatore Bonaccorso)
 
-0.32  2012-11-22 12:14:07  garu
+0.32 2012-11-22 12:42:19 garu
   - Stop skipping SvROK handling for all magical scalars. This fixes
     RT issues 67105, 79730 and 80201 (FLORA).
   - making the Changes file compliant to the CPAN::Changes spec (GARU).
@@ -101,150 +116,149 @@
   - updated remark on Storable's dclone() to address RT issue 50174 (GARU)
   - updated Makefile.PL to include test dependencies (GARU)
 
-0.31  2009-01-20 04:54:37  ray
+0.31 2009-01-20 04:54:37 ray
   - Made changes for build failure on Solaris, apparently compiler warnings
     from the last patch are errors in Solaris.
   - Also, brought Changes file up to date.
 
-0.30  2008-12-14 03:33:14  ray
+0.30 2008-12-14 03:33:14 ray
   - Updating log: Applied patches from RT # 40957 and #41551.
 
-0.29  2008-12-14 03:32:41  ray
+0.29 2008-12-14 03:32:41 ray
   - Updating log: Applied patches supplied by Andreas Koenig, see RT #34317.
 
-0.28  2008-12-14 03:31:33  ray
+0.28 2008-12-14 03:31:33 ray
   - Updating log: Made a change in CLONE_KEY to the way Clone stores refs in
     the ref hash.
   - Perl no longer uses the SvANY part of the SV struct in the same way which
     means the old way of storing the hash key is no longer unique.
     Thanks to Slaven Rezic for the patch.
 
-0.27  2008-12-14 03:30:40  ray
+0.27 2008-12-14 03:30:40 ray
   - Updating Log: Latest patch from Ruslan Zakirov. Patched another
     memory leak.
 
-0.26  2007-10-15 04:52:42  ray
+0.26 2007-10-15 04:52:42 ray
   - Made a change in CLONE_KEY to the way Clone stores refs in the ref hash.
   - Perl no longer uses the SvANY part of the SV struct in the same way which
     means the old way of storing the hash key is no longer unique.
     Thanks to Slaven Rezic for the patch.
 
-0.25  2007-07-25 03:41:04  ray
+0.25 2007-07-25 03:41:04 ray
   - Latest patch from Ruslan Zakirov. Patched another memory leak.
 
-0.24  2007-07-25 03:33:57  ray
+0.24 2007-07-25 03:33:57 ray
   - Bug fix for 5.9.*, for some reason the 'visible' logic is no longer
     working. I #if 'ed it out until I figure out what is going on.
   - Also removed an old redundant CLONE_STORE, could have been the cause of
     some memory leaks.
 
-0.23  2007-04-20 05:40:27  ray
+0.23 2007-04-20 05:40:27 ray
   - Applied patch so clone will contiue to work with newer perls.
   - Also fixed test to work with older perls.
 
-0.22  2006-10-08 05:35:19  ray
+0.22 2006-10-08 05:35:19 ray
   - D'oh! The 0.21 tardist that I just uploaded to CPAN contained the
     0.20 Clone.xs file. This release is just in case any of the 0.21
     releases get mirrored.
 
-0.21  2006-10-08 04:02:56  ray
+0.21 2006-10-08 04:02:56 ray
   - Clone was segfaulting due to a null SV object in a magical reference (a
     PERL_MAGIC_utf8).
   - 21859: Clone segfault (isolated example)
 
-0.20  2006-03-08 17:15:23  ray
+0.20 2006-03-08 17:15:23 ray
   - Commented out VERSION causes errors with DynaLoader in perl 5.6.1 (and
     probably all earlier versions. It was removed.
 
-0.19  2006-03-06 07:22:32  ray
+0.19 2006-03-06 07:22:32 ray
   - added a test and fix for tainted variables.
   - use a static VERSION in Clone.pm.
 
-0.18  2005-05-23 15:34:31  ray
+0.18 2005-05-23 15:34:31 ray
   - moved declaration to top of function, M$ (and other) C compilers choke.
 
-0.17  2005-05-05 22:26:01  ray
+0.17 2005-05-05 22:26:01 ray
   - Changed PERL_MAGIC_backref to '<' for compatability with 5.6
 
-0.16  2005-04-20 15:49:35  ray
+0.16 2005-04-20 15:49:35 ray
   - Bug fix for id 11997, "Clone dies horribly when Scalar::Util::weaken
     is around" see http://rt.cpan.org/Ticket/Display.html?id=11997
     for details.
 
-0.15.2.1  2005-05-05 21:55:30  ray
+0.15.2.1 2005-05-05 21:55:30 ray
   - changed PERL_MAGIC_backref to '<' for backward compatibility with 5.6
 
-0.15  2003-09-07 22:02:35  ray
+0.15 2003-09-07 22:02:35 ray
   - VERSION 0.15
 
-0.13.2.3  2003-09-07 21:51:03  ray
+0.13.2.3 2003-09-07 21:51:03 ray
   - added support for unicode hash keys. This is only really a bug in 5.8.0
     and the test in t/03scalar supports this.
 
-0.14  2003-09-07 05:48:10  ray
+0.14 2003-09-07 05:48:10 ray
   - VERSION 0.14
 
-0.13.2.2  2003-09-07 05:45:52  ray
+0.13.2.2 2003-09-07 05:45:52 ray
   - bug fix: refs to a qr (regexp) expression was causing a segfault.
 
-0.13.2.1  2003-09-06 20:18:37  ray
+0.13.2.1 2003-09-06 20:18:37 ray
   - Bug fix on cloning references, only set ROK in clone if it's set in ref.
 
-0.13  2002-02-03 02:12:29  ray
+0.13 2002-02-03 02:12:29 ray
   - VERSION 0.13
 
-0.11.2.1  2002-02-03 02:10:30  ray
+0.11.2.1 2002-02-03 02:10:30 ray
   - removed dependency on Storable for tests.
 
-0.12  2001-09-30 20:35:27  ray
+0.12 2001-09-30 20:35:27 ray
   - Version 0.12 release.
 
-0.11  2001-07-29 19:30:27  ray
+0.11 2001-07-29 19:30:27 ray
   - VERSION 0.11
 
-0.10.2.3  2001-07-28 21:53:03  ray
+0.10.2.3 2001-07-28 21:53:03 ray
   - fixed memory leaks on un-blessed references.
 
-0.10.2.2  2001-07-28 21:52:41  ray
+0.10.2.2 2001-07-28 21:52:41 ray
   - added test cases for circular reference bugs and memory leaks.
 
-0.10.2.1  2001-07-28 21:52:15  ray
+0.10.2.1 2001-07-28 21:52:15 ray
   - fixed circular reference bugs.
 
-0.10  2001-04-29 21:48:45  ray
+0.10 2001-04-29 21:48:45 ray
   - VERSION 0.10
 
-0.09.2.3  2001-03-11 00:54:41  ray
+0.09.2.3 2001-03-11 00:54:41 ray
   - change call to rv_clone in clone to sv_clone; this allows any scalar to
     be cloned.
 
-0.09.2.2  2001-03-11 00:50:01  ray
+0.09.2.2 2001-03-11 00:50:01 ray
   - version 0.09.3: cleaned up code, consolidated MAGIC.
 
-0.09.2.1  2001-03-05 16:01:52  ray
+0.09.2.1 2001-03-05 16:01:52 ray
   - added support for double-types.
 
-0.09  2000-08-21 23:05:55  ray
+0.09 2000-08-21 23:05:55 ray
   - added support for code refs
 
-0.08  2000-08-11 17:08:24  ray
+0.08 2000-08-11 17:08:24 ray
   - Release 0.08.
 
-0.07  2000-08-01 00:31:24  ray
+0.07 2000-08-01 00:31:24 ray
   - release 0.07.
 
-0.06.2.3  2000-07-28 20:40:25  ray
+0.06.2.3 2000-07-28 20:40:25 ray
   - added support for circular references
 
-0.06.2.2  2000-07-28 19:04:14  ray
+0.06.2.2 2000-07-28 19:04:14 ray
   - first pass at circular references.
 
-0.06.2.1  2000-07-28 18:54:33  ray
+0.06.2.1 2000-07-28 18:54:33 ray
   - added support for scalar types.
 
-0.06  Thu May 25 17:48:59 2000 GMT
-       - initial release to CPAN.
-
-0.01  Tue May 16 08:55:10 2000
-       - original version; created by h2xs 1.19
+0.06 2000-05-25 17:48:59 ray
+  - initial release to CPAN.
 
+0.01 2000-05-16 08:55:10 ray
+  - original version; created by h2xs 1.19
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/Clone.pm new/Clone-0.50/Clone.pm
--- old/Clone-0.48/Clone.pm     2026-03-03 00:01:04.037717500 +0100
+++ new/Clone-0.50/Clone.pm     2026-03-28 07:11:03.000000000 +0100
@@ -9,7 +9,7 @@
 our @EXPORT;
 our @EXPORT_OK = qw( clone );
 
-our $VERSION = '0.48';
+our $VERSION = '0.50';
 
 XSLoader::load('Clone', $VERSION);
 
@@ -125,9 +125,20 @@
 
 =item * Maximum Recursion Depth
 
-Clone supports structures up to 32,000 levels deep. Deeper structures
-will cause the clone operation to fail with an error. This limit prevents
-stack overflow and ensures safe operation.
+Clone uses a recursion depth counter to prevent stack overflow.
+The default limit is 4000 rdepth units on Linux/macOS and 2000 on
+Windows/Cygwin. Each nesting level consumes approximately 2 rdepth
+units, so the effective limits are roughly 2000 nesting levels on
+Linux/macOS and 1000 on Windows/Cygwin.
+
+For arrays, exceeding the limit triggers an iterative fallback that
+avoids stack overflow. For other reference types (hashes, scalars),
+exceeding the limit produces a warning and a shallow copy.
+
+You can override the depth limit by passing it as the second argument
+to C<clone()>:
+
+    my $copy = clone($data, 8000);  # allow deeper recursion
 
 =item * Filehandles and IO Objects
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/Clone.xs new/Clone-0.50/Clone.xs
--- old/Clone-0.48/Clone.xs     2026-02-24 15:25:30.732456997 +0100
+++ new/Clone-0.50/Clone.xs     2026-03-28 06:57:50.000000000 +0100
@@ -45,6 +45,7 @@
 static SV *av_clone (SV *, SV *, HV *, int, int, AV *);
 static SV *sv_clone (SV *, HV *, int, int, AV *);
 static SV *av_clone_iterative(SV *, HV *, int, AV *);
+static SV *hv_clone_iterative(SV *, HV *, int, AV *);
 
 #ifdef DEBUG_CLONE
 #define TRACEME(a) printf("%s:%d: ",__FUNCTION__, __LINE__) && printf a;
@@ -195,6 +196,49 @@
     return (SV*)root_clone;
 }
 
+/* Iterative hash clone for use when rdepth exceeds MAX_DEPTH.
+ * Mirrors av_clone_iterative: creates a new HV, registers it in hseen for
+ * circular-ref safety, then clones each value via sv_clone (which will
+ * re-enter this function for any nested HVs still above MAX_DEPTH). */
+static SV *
+hv_clone_iterative(SV * ref, HV* hseen, int rdepth, AV * weakrefs)
+{
+    HV *self;
+    HV *root_clone;
+    SV **seen = NULL;
+    HE *next = NULL;
+
+    if (!ref) return NULL;
+
+    self = (HV *)ref;
+
+    /* Return cached clone if we have already visited this HV (circular refs) 
*/
+    if ((seen = CLONE_FETCH(ref))) {
+        return SvREFCNT_inc(*seen);
+    }
+
+    root_clone = newHV();
+    CLONE_STORE(ref, (SV *)root_clone);
+
+    /* Pre-size to avoid incremental resizing */
+    if (HvKEYS(self) > 0)
+        hv_ksplit(root_clone, HvKEYS(self));
+
+    /* Clone each value; sv_clone will use the iterative path again for any
+     * nested structures that are still above MAX_DEPTH. */
+    hv_iterinit(self);
+    while ((next = hv_iternext(self))) {
+        I32 klen;
+        char *kpv = hv_iterkey(next, &klen);
+        SV *val = sv_clone(hv_iterval(self, next), hseen, 1, rdepth, weakrefs);
+        if (HeKUTF8(next))
+            klen = -klen;
+        hv_store(root_clone, kpv, klen, val, HeHASH(next));
+    }
+
+    return (SV *)root_clone;
+}
+
 static SV *
 av_clone (SV * ref, SV * target, HV* hseen, int depth, int rdepth, AV * 
weakrefs)
 {
@@ -259,6 +303,9 @@
         if (SvTYPE(ref) == SVt_PVAV) {
             return av_clone_iterative(ref, hseen, rdepth, weakrefs);
         }
+        if (SvTYPE(ref) == SVt_PVHV) {
+            return hv_clone_iterative(ref, hseen, rdepth, weakrefs);
+        }
         /* For RVs pointing to AVs, follow the reference and use the
          * iterative path -- this is the common case for [[[...]]] */
         if (SvROK(ref) && SvTYPE(SvRV(ref)) == SVt_PVAV) {
@@ -268,6 +315,14 @@
                 sv_bless(clone_rv, SvSTASH(SvRV(ref)));
             return clone_rv;
         }
+        /* For RVs pointing to HVs, use the iterative hash path */
+        if (SvROK(ref) && SvTYPE(SvRV(ref)) == SVt_PVHV) {
+            SV *clone_hv = hv_clone_iterative(SvRV(ref), hseen, rdepth, 
weakrefs);
+            SV *clone_rv = newRV_noinc(clone_hv);
+            if (SvOBJECT(SvRV(ref)))
+                sv_bless(clone_rv, SvSTASH(SvRV(ref)));
+            return clone_rv;
+        }
         /* For other types, just return a reference to avoid stack overflow */
         return SvREFCNT_inc(ref);
     }
@@ -498,8 +553,7 @@
             case 't':  /* PERL_MAGIC_taint */
             case '<': /* PERL_MAGIC_backref */
             case '@':  /* PERL_MAGIC_arylen_p */
-              continue;
-              break;
+              continue; /* resumes the outer magic iteration loop */
             case 'P': /* PERL_MAGIC_tied */
             case 'p': /* PERL_MAGIC_tiedelem */
             case 'q': /* PERL_MAGIC_tiedscalar */
@@ -552,33 +606,34 @@
         mg->mg_virtual = (MGVTBL *) NULL;
     }
     /* 2: HASH/ARRAY  - (with 'internal' elements) */
-  if ( magic_ref )
+    /* For tied HV/AV (magic_ref > 0): skip direct element iteration;
+     * the tie magic cloned above handles the data. */
+  if ( !magic_ref )
   {
-    ;;
-  }
-  else if ( SvTYPE(ref) == SVt_PVHV )
-    clone = hv_clone (ref, clone, hseen, depth, rdepth, weakrefs);
-  else if ( SvTYPE(ref) == SVt_PVAV )
-    clone = av_clone (ref, clone, hseen, depth, rdepth, weakrefs);
+    if ( SvTYPE(ref) == SVt_PVHV )
+      clone = hv_clone (ref, clone, hseen, depth, rdepth, weakrefs);
+    else if ( SvTYPE(ref) == SVt_PVAV )
+      clone = av_clone (ref, clone, hseen, depth, rdepth, weakrefs);
     /* 3: REFERENCE (inlined for speed) */
-  else if (SvROK (ref))
-    {
-      TRACEME(("clone = 0x%x(%d)\n", clone, SvREFCNT(clone)));
-      SvREFCNT_dec(SvRV(clone));
-      SvRV(clone) = sv_clone (SvRV(ref), hseen, depth, rdepth, weakrefs); /* 
Clone the referent */
-      if (SvOBJECT(SvRV(ref)))
+    else if (SvROK (ref))
       {
-          sv_bless (clone, SvSTASH (SvRV (ref)));
-      }
-      if (SvWEAKREF(ref)) {
-          /* Defer weakening until after the entire clone graph is built.
-           * sv_rvweaken decrements the referent's refcount, which can
-           * destroy it if no other strong references exist yet.
-           * By deferring, we ensure all strong references are in place
-           * before any weakening occurs. (fixes GH #15) */
-          av_push(weakrefs, SvREFCNT_inc_simple_NN(clone));
+        TRACEME(("clone = 0x%x(%d)\n", clone, SvREFCNT(clone)));
+        SvREFCNT_dec(SvRV(clone));
+        SvRV(clone) = sv_clone (SvRV(ref), hseen, depth, rdepth, weakrefs); /* 
Clone the referent */
+        if (SvOBJECT(SvRV(ref)))
+        {
+            sv_bless (clone, SvSTASH (SvRV (ref)));
+        }
+        if (SvWEAKREF(ref)) {
+            /* Defer weakening until after the entire clone graph is built.
+             * sv_rvweaken decrements the referent's refcount, which can
+             * destroy it if no other strong references exist yet.
+             * By deferring, we ensure all strong references are in place
+             * before any weakening occurs. (fixes GH #15) */
+            av_push(weakrefs, SvREFCNT_inc_simple_NN(clone));
+        }
       }
-    }
+  }
 
   TRACEME(("clone = 0x%x(%d)\n", clone, SvREFCNT(clone)));
   return clone;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/MANIFEST new/Clone-0.50/MANIFEST
--- old/Clone-0.48/MANIFEST     2026-03-03 00:04:34.415727749 +0100
+++ new/Clone-0.50/MANIFEST     2026-03-28 07:12:34.000000000 +0100
@@ -1,3 +1,4 @@
+AI_POLICY.md
 Changes
 Clone.pm
 Clone.xs
@@ -6,6 +7,7 @@
 MANIFEST.SKIP
 ppport.h
 README.md
+SECURITY.md
 t/00-cow.t
 t/01-array.t
 t/02-hash.t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/MANIFEST.SKIP new/Clone-0.50/MANIFEST.SKIP
--- old/Clone-0.48/MANIFEST.SKIP        2026-02-17 22:45:23.000000000 +0100
+++ new/Clone-0.50/MANIFEST.SKIP        2026-03-28 07:10:29.000000000 +0100
@@ -72,3 +72,6 @@
 \.bs$
 \.c$
 CLAUDE.md
+Clone\-.*\.gz
+^local/
+\.claude
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/META.json new/Clone-0.50/META.json
--- old/Clone-0.48/META.json    2026-03-03 00:04:34.320987685 +0100
+++ new/Clone-0.50/META.json    2026-03-28 07:12:34.000000000 +0100
@@ -49,6 +49,6 @@
          "url" : "https://github.com/garu/Clone";
       }
    },
-   "version" : "0.48",
+   "version" : "0.50",
    "x_serialization_backend" : "JSON::PP version 4.16"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/META.yml new/Clone-0.50/META.yml
--- old/Clone-0.48/META.yml     2026-03-03 00:04:33.766211477 +0100
+++ new/Clone-0.50/META.yml     2026-03-28 07:12:34.000000000 +0100
@@ -23,5 +23,5 @@
   bugtracker: https://github.com/garu/Clone/issues
   license: https://dev.perl.org/licenses/
   repository: https://github.com/garu/Clone
-version: '0.48'
+version: '0.50'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/Makefile.PL new/Clone-0.50/Makefile.PL
--- old/Clone-0.48/Makefile.PL  2026-02-11 00:01:43.277866825 +0100
+++ new/Clone-0.50/Makefile.PL  2026-03-28 06:57:50.000000000 +0100
@@ -26,6 +26,18 @@
         repository => 'https://github.com/garu/Clone',
       },
     },
+    # Prevent macOS extended attributes (com.apple.provenance, etc.) from
+    # being embedded in the distribution tarball.
+    # - COPYFILE_DISABLE=1 stops macOS tar from adding ._AppleDouble sidecar 
files.
+    # - PREOP strips any xattrs already set on the dist directory files (e.g.
+    #   com.apple.provenance set by macOS on git-cloned files) before tar runs.
+    #   xattr(1) is macOS-specific; the "|| true" makes it a no-op elsewhere.
+    dist => {
+        COMPRESS => 'gzip -9f',
+        SUFFIX   => 'gz',
+        TAR      => 'COPYFILE_DISABLE=1 TAR_OPTIONS="--no-xattrs --no-acls" 
gtar',
+        PREOP    => 'command -v xattr >/dev/null 2>&1 && xattr -cr 
$(DISTVNAME) || true',
+    },
 );
 
 my $EUMM_VERSION = eval $ExtUtils::MakeMaker::VERSION;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/README.md new/Clone-0.50/README.md
--- old/Clone-0.48/README.md    2026-02-11 01:08:39.302176644 +0100
+++ new/Clone-0.50/README.md    2026-03-28 06:29:40.000000000 +0100
@@ -134,7 +134,7 @@
 
 ## Limitations
 
-* **Maximum Recursion Depth**: Clone supports structures up to 32,000 levels 
deep. Deeper structures will cause the clone operation to fail with an error. 
This limit prevents stack overflow and ensures safe operation.
+* **Maximum Recursion Depth**: Clone uses a recursion depth counter to prevent 
stack overflow. The default limit is 4000 rdepth units on Linux/macOS and 2000 
on Windows/Cygwin. Each nesting level consumes approximately 2 rdepth units, so 
the effective limits are roughly 2000 nesting levels on Linux/macOS and 1000 on 
Windows/Cygwin. For arrays, exceeding the limit triggers an iterative fallback. 
For other types, it produces a warning and a shallow copy. You can override the 
limit via `clone($data, $depth)`.
 
 * **Filehandles and IO Objects**: Filehandles and IO objects are cloned, but 
the underlying file descriptor is shared. Both the original and cloned 
filehandle will refer to the same file position. For DBI database handles and 
similar objects, Clone attempts to handle them safely, but behavior may vary 
depending on the object type.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/SECURITY.md new/Clone-0.50/SECURITY.md
--- old/Clone-0.48/SECURITY.md  1970-01-01 01:00:00.000000000 +0100
+++ new/Clone-0.50/SECURITY.md  2026-03-28 07:10:29.000000000 +0100
@@ -0,0 +1,89 @@
+# Security Policy for the Clone distribution.
+
+This is the Security Policy for Clone.
+
+The latest version of the Security Policy can be found in the
+[git repository for 
Clone](https://github.com/garu/Clone/blob/master/SECURITY.md).
+
+This text is based on the CPAN Security Group's Guidelines for Adding
+a Security Policy to Perl Distributions (version 1.3.0)
+https://security.metacpan.org/docs/guides/security-policy-for-authors.html
+
+# How to Report a Security Vulnerability
+
+If you would like any help with triaging the issue, or if the issue
+is being actively exploited, please copy the report to the CPAN
+Security Group (CPANSec) at <[email protected]>.
+
+Please *do not* use the public issue reporting system on RT or
+GitHub issues for reporting security vulnerabilities.
+
+Please do not disclose the security vulnerability in public forums
+until past any proposed date for public disclosure, or it has been
+made public by the maintainers or CPANSec.  That includes patches or
+pull requests.
+
+For more information, see
+[Report a Security Issue](https://security.metacpan.org/docs/report.html)
+on the CPANSec website.
+
+## Response to Reports
+
+The maintainers aim to acknowledge your security report as soon as
+possible.  However, this project is maintained by people in
+their spare time, and they cannot guarantee a rapid response.  If you
+have not received a response from them within 14 days, then
+please send a reminder to them and copy the report to CPANSec at
+<[email protected]>.
+
+Please note that the initial response to your report will be an
+acknowledgement, with a possible query for more information.  It
+will not necessarily include any fixes for the issue.
+
+The project maintainers may forward this issue to the security
+contacts for other projects where we believe it is relevant.  This
+may include embedded libraries, system libraries, prerequisite
+modules or downstream software that uses this software.
+
+They may also forward this issue to CPANSec.
+
+# Which Software This Policy Applies To
+
+Any security vulnerabilities in Clone are covered by this policy.
+
+Security vulnerabilities are considered anything that allows users
+to execute unauthorised code, access unauthorised resources, or to
+have an adverse impact on accessibility or performance of a system.
+
+Security vulnerabilities in upstream software (prerequisite modules
+or system libraries, or in Perl), are not covered by this policy
+unless they affect Clone, or Clone can be used to exploit
+vulnerabilities in them.
+
+Security vulnerabilities in downstream software (any software that
+uses Clone, or plugins to it that are not included with the
+Clone distribution) are not covered by this policy.
+
+## Supported Versions of Clone
+
+The maintainers will only commit to releasing security fixes for
+the latest version of Clone.
+
+Note that the Clone project only supports major versions of Perl
+starting from v5.8.0.  If a security fix requires us to increase
+the minimum version of Perl that is supported, then we may do so.
+
+# Installation and Usage Issues
+
+The distribution metadata specifies minimum versions of
+prerequisites that are required for Clone to work.  However, some
+of these prerequisites may have security vulnerabilities, and you
+should ensure that you are using up-to-date versions of these
+prerequisites.
+
+Where security vulnerabilities are known, the metadata may indicate
+newer versions as recommended.
+
+## Usage
+
+Please see the software documentation for further information.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/t/03-scalar.t new/Clone-0.50/t/03-scalar.t
--- old/Clone-0.48/t/03-scalar.t        2025-05-16 02:04:25.282136113 +0200
+++ new/Clone-0.50/t/03-scalar.t        2026-03-28 06:23:00.000000000 +0100
@@ -130,7 +130,7 @@
 my $str = 'abcdefg';
 my $qr = qr/$str/;
 my $qc = clone( $qr );
-ok( $qr eq $qc, 'string check' ) or warn "$qr vs $qc";
+ok( $qr eq $qc, 'string check' );
 ok( $str =~ /$qc/, 'regexp check' );
 
 # test for unicode support
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/t/10-deep_recursion.t 
new/Clone-0.50/t/10-deep_recursion.t
--- old/Clone-0.48/t/10-deep_recursion.t        2026-02-24 15:25:30.733026745 
+0100
+++ new/Clone-0.50/t/10-deep_recursion.t        2026-03-28 06:57:50.000000000 
+0100
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
-use Test::More tests => 7;
+use Test::More tests => 13;
 use Clone qw(clone);
 use Config;
 
@@ -19,7 +19,7 @@
 # The deep target must exceed MAX_DEPTH/2 to exercise both paths.
 my $is_limited_stack = ($^O eq 'MSWin32' || $^O eq 'cygwin');
 
-my $deep_target     = $is_limited_stack ? 4000 : 5000;
+my $deep_target     = $is_limited_stack ? 2500 : 5000;
 
 # Moderate depth used for basic tests (safe everywhere).
 my $moderate_target  = 1000;
@@ -109,3 +109,100 @@
                   "Leaf multi-element array should be cloned correctly");
     }
 }
+
+# Test 8-10: Deep recursion with hashes (GH #93)
+# At depth > MAX_DEPTH/2, the guard previously returned SvREFCNT_inc(ref)
+# for hash types, silently aliasing inner nodes instead of deep-copying them.
+{
+    my $deep_hash = {x => undef};
+    my $curr = $deep_hash;
+    for (1..$deep_target) {
+        my $next = {x => undef};
+        $curr->{x} = $next;
+        $curr = $next;
+    }
+
+    my $cloned = eval {
+        local $SIG{__WARN__} = sub {};
+        clone($deep_hash);
+    };
+
+    ok(!$@ && defined($cloned),
+       "Should be able to clone $deep_target-deep hash structure without stack 
overflow")
+        or diag("Error during clone: " . ($@ || "undefined result"));
+
+    SKIP: {
+        skip "Clone failed, can't verify structure", 2 if !defined $cloned;
+
+        # Measure cloned depth
+        my $measured = 0;
+        my $walk = $cloned;
+        while (ref($walk) eq 'HASH' && exists $walk->{x} && ref($walk->{x}) eq 
'HASH') {
+            $walk = $walk->{x};
+            $measured++;
+        }
+
+        is($measured, $deep_target,
+           "Cloned hash structure should maintain full depth ($deep_target 
levels)");
+
+        # Verify clone independence at deep nodes: navigate to a node past
+        # MAX_DEPTH/2 in both original and clone, then mutate the clone and
+        # verify the original is unaffected (proves deep copy, not aliasing).
+        my $depth_target = $is_limited_stack ? 1500 : 2500;
+        my $walk_orig = $deep_hash;
+        my $walk_clone = $cloned;
+        for (1..$depth_target) {
+            $walk_orig  = $walk_orig->{x};
+            $walk_clone = $walk_clone->{x};
+        }
+        $walk_clone->{_sentinel} = "mutation";
+        ok(!exists $walk_orig->{_sentinel},
+           "Mutating clone at depth $depth_target should not affect original 
(no aliasing)");
+    }
+}
+
+# Test 11-13: Mixed deep structure (arrays containing hashes) past MAX_DEPTH
+{
+    my $deep_mixed = [];
+    my $curr = $deep_mixed;
+    for (1..$deep_target) {
+        my $next = [];
+        push @$curr, {val => $next};
+        $curr = $next;
+    }
+
+    my $cloned = eval {
+        local $SIG{__WARN__} = sub {};
+        clone($deep_mixed);
+    };
+
+    ok(!$@ && defined($cloned),
+       "Should clone $deep_target-deep mixed array/hash structure without 
stack overflow")
+        or diag("Error during clone: " . ($@ || "undefined result"));
+
+    SKIP: {
+        skip "Clone failed, can't verify", 2 if !defined $cloned;
+
+        # Measure depth
+        my $measured = 0;
+        my $walk = $cloned;
+        while (ref($walk) eq 'ARRAY' && @$walk == 1 && ref($walk->[0]) eq 
'HASH') {
+            $walk = $walk->[0]{val};
+            $measured++;
+        }
+        is($measured, $deep_target,
+           "Mixed deep structure should maintain full depth ($deep_target 
levels)");
+
+        # Clone independence: mutate a deep hash node in clone
+        my $depth_target = $is_limited_stack ? 1500 : 2500;
+        my $walk_orig  = $deep_mixed;
+        my $walk_clone = $cloned;
+        for (1..$depth_target) {
+            $walk_orig  = $walk_orig->[0]{val};
+            $walk_clone = $walk_clone->[0]{val};
+        }
+        $walk_clone->[0]{_sentinel} = "mutation";
+        ok(!exists $walk_orig->[0]{_sentinel},
+           "Mutating clone hash at depth $depth_target should not affect 
original");
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Clone-0.48/t/13-io-handle.t 
new/Clone-0.50/t/13-io-handle.t
--- old/Clone-0.48/t/13-io-handle.t     2026-02-10 23:39:02.857761495 +0100
+++ new/Clone-0.50/t/13-io-handle.t     2026-03-28 06:23:00.000000000 +0100
@@ -3,10 +3,18 @@
 
 use Test::More;
 use Clone qw(clone);
+use File::Spec ();
+use Scalar::Util ();
 
 # GH #27: Cloning IO handles (filehandles, DBI-like objects) should not 
segfault.
 # Clone cannot deep-copy IO handles (they wrap C-level structures), but it
 # should either croak with a clear message or return a shallow ref — never 
crash.
+#
+# DBI clones lack XS-level magic and produce STDERR noise (SV dumps, "not a
+# DBI handle" warnings) when DBI's DESTROY fires on them.  Worse, circular
+# refs inside cloned handles cause SEGVs during global destruction.  We run
+# DBI-specific tests in a forked subprocess and redirect its STDERR to
+# devnull so neither the noise nor the crash pollutes the test harness.
 
 plan tests => 18;
 
@@ -115,42 +123,54 @@
 }
 
 # --- Test 13-16: DBI database handle (the original GH #27 report) ---
+#
+# Cloned DBI handles lack XS-level magic.  DBI's DESTROY dumps SV internals
+# to STDERR and internal circular refs cause SEGVs during global destruction.
+# We run these tests in a forked child with STDERR suppressed; the child
+# prints TAP lines to a pipe and the parent relays them to Test::More.
 
 SKIP: {
     eval { require DBI; require DBD::SQLite }
         or skip "DBI + DBD::SQLite required for DBI tests", 4;
+    skip "fork() not available (Windows)", 4 unless _can_fork();
 
-    my $dbh = DBI->connect("dbi:SQLite:dbname=:memory:", "", "",
-        { PrintError => 0, RaiseError => 0 });
-    skip "Cannot create DBI handle", 4 unless $dbh;
-
-    $dbh->do("CREATE TABLE test (id INTEGER, name TEXT)");
-    $dbh->do("INSERT INTO test VALUES (1, 'foo')");
-
-    # Test 13: clone does not segfault
-    my $cloned;
-    my $ok = eval { $cloned = clone($dbh); 1 };
-    ok($ok, "GH #27: clone of DBI handle does not segfault")
-        or diag("Error: $@");
-
-    # Test 14: clone returns a defined value
-    ok(defined $cloned, "cloned DBI handle is defined");
-
-    # Test 15: original still works after clone
-    my $sth = $dbh->prepare("SELECT name FROM test WHERE id = 1");
-    $sth->execute;
-    my ($name) = $sth->fetchrow_array;
-    is($name, "foo", "original DBI handle still works after clone");
-
-    # Test 16: cloned handle cannot be used (but doesn't segfault)
-    eval {
-        my $sth2 = $cloned->prepare("SELECT * FROM test");
-        $sth2->execute;
-    };
-    ok($@, "cloned DBI handle raises error on use (not segfault)")
-        or diag("Expected an error but got none");
-
-    $dbh->disconnect;
+    my $result = _run_in_subprocess(sub {
+        my $dbh = DBI->connect("dbi:SQLite:dbname=:memory:", "", "",
+            { PrintError => 0, RaiseError => 0 });
+        return "skip Cannot create DBI handle" unless $dbh;
+
+        $dbh->do("CREATE TABLE test (id INTEGER, name TEXT)");
+        $dbh->do("INSERT INTO test VALUES (1, 'foo')");
+
+        # clone does not segfault
+        my $cloned;
+        my $clone_ok = eval { $cloned = clone($dbh); 1 };
+        print "clone_ok=" . ($clone_ok ? 1 : 0) . "\n";
+        print "clone_defined=" . (defined $cloned ? 1 : 0) . "\n";
+
+        # original still works after clone
+        my $sth = $dbh->prepare("SELECT name FROM test WHERE id = 1");
+        $sth->execute;
+        my ($name) = $sth->fetchrow_array;
+        print "name=$name\n";
+
+        # cloned handle is a HASH-based object (no magic)
+        my $is_hash = (ref($cloned) && Scalar::Util::reftype($cloned) eq 
'HASH') ? 1 : 0;
+        print "is_hash=$is_hash\n";
+
+        $sth->finish;
+        $dbh->disconnect;
+    });
+
+    if ($result =~ /^skip (.*)/) {
+        skip $1, 4;
+    }
+
+    my %r = map { /^(\w+)=(.*)/ ? ($1 => $2) : () } split /\n/, $result;
+    ok($r{clone_ok},      "GH #27: clone of DBI handle does not segfault");
+    ok($r{clone_defined},  "cloned DBI handle is defined");
+    is($r{name}, "foo",   "original DBI handle still works after clone");
+    ok($r{is_hash},       "cloned DBI handle is a HASH-based object (no 
magic)");
 }
 
 # --- Test 17-18: DBI statement handle ---
@@ -158,23 +178,82 @@
 SKIP: {
     eval { require DBI; require DBD::SQLite }
         or skip "DBI + DBD::SQLite required for sth tests", 2;
+    skip "fork() not available (Windows)", 2 unless _can_fork();
 
-    my $dbh = DBI->connect("dbi:SQLite:dbname=:memory:", "", "",
-        { PrintError => 0, RaiseError => 0 });
-    skip "Cannot create DBI handle", 2 unless $dbh;
-
-    $dbh->do("CREATE TABLE t2 (x INTEGER)");
-    my $sth = $dbh->prepare("SELECT * FROM t2");
-
-    # Test 17: clone of sth does not segfault
-    my $cloned;
-    my $ok = eval { $cloned = clone($sth); 1 };
-    ok($ok, "clone of DBI statement handle does not segfault")
-        or diag("Error: $@");
+    my $result = _run_in_subprocess(sub {
+        my $dbh = DBI->connect("dbi:SQLite:dbname=:memory:", "", "",
+            { PrintError => 0, RaiseError => 0 });
+        return "skip Cannot create DBI handle" unless $dbh;
+
+        $dbh->do("CREATE TABLE t2 (x INTEGER)");
+        my $sth = $dbh->prepare("SELECT * FROM t2");
+
+        # clone of sth does not segfault
+        my $cloned;
+        my $clone_ok = eval { $cloned = clone($sth); 1 };
+        print "clone_ok=" . ($clone_ok ? 1 : 0) . "\n";
+
+        # original still works
+        $sth->execute;
+        print "original_works=1\n";
+
+        $sth->finish;
+        $dbh->disconnect;
+    });
+
+    if ($result =~ /^skip (.*)/) {
+        skip $1, 2;
+    }
+
+    my %r = map { /^(\w+)=(.*)/ ? ($1 => $2) : () } split /\n/, $result;
+    ok($r{clone_ok},       "clone of DBI statement handle does not segfault");
+    ok($r{original_works}, "original statement handle still works after 
clone");
+}
 
-    # Test 18: original dbh still works
-    $sth->execute;
-    ok(1, "original statement handle still works after clone");
+# Check whether fork() is usable.  Strawberry Perl on Windows implements
+# fork() via ithreads emulation which doesn't support pipe+fork reliably,
+# and some builds don't implement it at all.
+sub _can_fork {
+    return 0 if $^O eq 'MSWin32';
+    my $pid = eval { fork() };
+    return 0 unless defined $pid;
+    if ($pid == 0) {
+        require POSIX;
+        POSIX::_exit(0);
+    }
+    waitpid($pid, 0);
+    return 1;
+}
 
-    $dbh->disconnect;
+# Run a code block in a forked child process with STDERR suppressed.
+# Returns the child's STDOUT output.  If the child crashes (SEGV etc.),
+# the parent survives and the test still passes based on what was printed
+# before the crash.
+sub _run_in_subprocess {
+    my ($code) = @_;
+    pipe(my $rd, my $wr) or die "pipe: $!";
+    my $pid = fork();
+    die "fork: $!" unless defined $pid;
+
+    if ($pid == 0) {
+        # Child: suppress STDERR, capture STDOUT to pipe
+        close $rd;
+        open(STDERR, '>', File::Spec->devnull);
+        open(STDOUT, '>&', $wr);
+        $| = 1;
+        my $ret = $code->();
+        print $ret if defined $ret && !ref $ret;
+        close $wr;
+        # Use POSIX::_exit to avoid running destructors in the child
+        # (which would trigger the DBI SEGV on cloned handles).
+        require POSIX;
+        POSIX::_exit(0);
+    }
+
+    # Parent
+    close $wr;
+    my $output = do { local $/; <$rd> };
+    close $rd;
+    waitpid($pid, 0);
+    return $output || "";
 }

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.mTA9Yl/_old  2026-04-10 17:43:06.797345093 +0200
+++ /var/tmp/diff_new_pack.mTA9Yl/_new  2026-04-10 17:43:06.805345422 +0200
@@ -1,6 +1,6 @@
-mtime: 1772517942
-commit: 9c48266e339fc540499c3bcdd09921f7187b95980311837aa5022a75d75a329d
+mtime: 1774765296
+commit: 7cee77800714e5204a1973ebd546fe2aaa1f14ac0919b89ce48035ef99800b6b
 url: https://src.opensuse.org/perl/perl-Clone.git
-revision: 9c48266e339fc540499c3bcdd09921f7187b95980311837aa5022a75d75a329d
+revision: 7cee77800714e5204a1973ebd546fe2aaa1f14ac0919b89ce48035ef99800b6b
 projectscmsync: https://src.opensuse.org/perl/_ObsPrj
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-04-07 14:45:08.000000000 +0200
@@ -0,0 +1 @@
+.osc

Reply via email to