diff --git a/LibGit2Sharp/Core/Handles/Libgit2Object.cs b/LibGit2Sharp/Core/Handles/Libgit2Object.cs index 892ebde90..a96d99e10 100644 --- a/LibGit2Sharp/Core/Handles/Libgit2Object.cs +++ b/LibGit2Sharp/Core/Handles/Libgit2Object.cs @@ -1,13 +1,13 @@ // This activates a lightweight mode which will help put under the light -// incorrectly released handles by outputing a warning message in the console. +// incorrectly released handles by outputting a warning message in the console. // // This should be activated when tests are being run on the CI server. // // Uncomment the line below or add a conditional symbol to activate this mode -// #define LEAKS_IDENTIFYING +//#define LEAKS_IDENTIFYING -// This activates a more throrough mode which will show the stack trace of the +// This activates a more thorough mode which will show the stack trace of the // allocation code path for each handle that has been improperly released. // // This should be manually activated when some warnings have been raised as @@ -15,17 +15,17 @@ // // Uncomment the line below or add a conditional symbol to activate this mode -// #define LEAKS_TRACKING +//#define LEAKS_TRACKING using System; -using System.Linq; -using System.Diagnostics; -using System.Globalization; -using System.Collections.Generic; +using Microsoft.Win32.SafeHandles; #if LEAKS_IDENTIFYING namespace LibGit2Sharp.Core { + using System.Collections.Generic; + using System.Linq; + /// /// Holds leaked handle type names reported by /// @@ -78,30 +78,27 @@ public static IEnumerable TypeNames namespace LibGit2Sharp.Core.Handles { - internal unsafe abstract class Libgit2Object : IDisposable +#if LEAKS_TRACKING + using System.Diagnostics; + using System.Globalization; +#endif + + internal unsafe abstract class Libgit2Object : SafeHandleZeroOrMinusOneIsInvalid { #if LEAKS_TRACKING private readonly string trace; private readonly Guid id; #endif - protected void* ptr; - - internal void* Handle + internal unsafe Libgit2Object(void* ptr, bool owned) + : this(new IntPtr(ptr), owned) { - get - { - return ptr; - } } - bool owned; - bool disposed; - - internal unsafe Libgit2Object(void* handle, bool owned) + internal unsafe Libgit2Object(IntPtr ptr, bool owned) + : base(owned) { - this.ptr = handle; - this.owned = owned; + SetHandle(ptr); #if LEAKS_TRACKING id = Guid.NewGuid(); @@ -111,35 +108,12 @@ internal unsafe Libgit2Object(void* handle, bool owned) #endif } - internal unsafe Libgit2Object(IntPtr ptr, bool owned) - : this(ptr.ToPointer(), owned) - { - } + internal IntPtr AsIntPtr() => DangerousGetHandle(); - ~Libgit2Object() - { - Dispose(false); - } - - internal bool IsNull - { - get - { - return ptr == null; - } - } - - internal IntPtr AsIntPtr() - { - return new IntPtr(ptr); - } - - public abstract void Free(); - - void Dispose(bool disposing) + protected override void Dispose(bool disposing) { #if LEAKS_IDENTIFYING - bool leaked = !disposing && ptr != null; + bool leaked = !disposing && DangerousGetHandle() != IntPtr.Zero; if (leaked) { @@ -147,17 +121,7 @@ void Dispose(bool disposing) } #endif - if (!disposed) - { - if (owned) - { - Free(); - } - - ptr = null; - } - - disposed = true; + base.Dispose(disposing); #if LEAKS_TRACKING if (!leaked) @@ -172,11 +136,6 @@ void Dispose(bool disposing) } #endif } - - public void Dispose() - { - Dispose(true); - } } } diff --git a/LibGit2Sharp/Core/Handles/Objects.cs b/LibGit2Sharp/Core/Handles/Objects.cs index 5f8db722e..7666a7412 100644 --- a/LibGit2Sharp/Core/Handles/Objects.cs +++ b/LibGit2Sharp/Core/Handles/Objects.cs @@ -7,7 +7,7 @@ namespace LibGit2Sharp.Core.Handles internal unsafe class TreeEntryHandle : Libgit2Object { internal TreeEntryHandle(git_tree_entry *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -16,21 +16,23 @@ internal TreeEntryHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_tree_entry_free((git_tree_entry*) ptr); + NativeMethods.git_tree_entry_free((git_tree_entry*)AsIntPtr()); + + return true; } public static implicit operator git_tree_entry*(TreeEntryHandle handle) { - return (git_tree_entry*) handle.Handle; + return (git_tree_entry*)handle.AsIntPtr(); } } internal unsafe class ReferenceHandle : Libgit2Object { internal ReferenceHandle(git_reference *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -39,21 +41,23 @@ internal ReferenceHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_reference_free((git_reference*) ptr); + NativeMethods.git_reference_free((git_reference*)AsIntPtr()); + + return true; } public static implicit operator git_reference*(ReferenceHandle handle) { - return (git_reference*) handle.Handle; + return (git_reference*)handle.AsIntPtr(); } } internal unsafe class RepositoryHandle : Libgit2Object { internal RepositoryHandle(git_repository *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -62,21 +66,23 @@ internal RepositoryHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_repository_free((git_repository*) ptr); + NativeMethods.git_repository_free((git_repository*)AsIntPtr()); + + return true; } public static implicit operator git_repository*(RepositoryHandle handle) { - return (git_repository*) handle.Handle; + return (git_repository*)handle.AsIntPtr(); } } internal unsafe class SignatureHandle : Libgit2Object { internal SignatureHandle(git_signature *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -85,21 +91,23 @@ internal SignatureHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_signature_free((git_signature*) ptr); + NativeMethods.git_signature_free((git_signature*)AsIntPtr()); + + return true; } public static implicit operator git_signature*(SignatureHandle handle) { - return (git_signature*) handle.Handle; + return (git_signature*)handle.AsIntPtr(); } } internal unsafe class StatusListHandle : Libgit2Object { internal StatusListHandle(git_status_list *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -108,21 +116,23 @@ internal StatusListHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_status_list_free((git_status_list*) ptr); + NativeMethods.git_status_list_free((git_status_list*)AsIntPtr()); + + return true; } public static implicit operator git_status_list*(StatusListHandle handle) { - return (git_status_list*) handle.Handle; + return (git_status_list*)handle.AsIntPtr(); } } internal unsafe class BlameHandle : Libgit2Object { internal BlameHandle(git_blame *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -131,21 +141,23 @@ internal BlameHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_blame_free((git_blame*) ptr); + NativeMethods.git_blame_free((git_blame*)AsIntPtr()); + + return true; } public static implicit operator git_blame*(BlameHandle handle) { - return (git_blame*) handle.Handle; + return (git_blame*)handle.AsIntPtr(); } } internal unsafe class DiffHandle : Libgit2Object { internal DiffHandle(git_diff *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -154,21 +166,23 @@ internal DiffHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_diff_free((git_diff*) ptr); + NativeMethods.git_diff_free((git_diff*)AsIntPtr()); + + return true; } public static implicit operator git_diff*(DiffHandle handle) { - return (git_diff*) handle.Handle; + return (git_diff*)handle.AsIntPtr(); } } internal unsafe class PatchHandle : Libgit2Object { internal PatchHandle(git_patch *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -177,21 +191,23 @@ internal PatchHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_patch_free((git_patch*) ptr); + NativeMethods.git_patch_free((git_patch*)AsIntPtr()); + + return true; } public static implicit operator git_patch*(PatchHandle handle) { - return (git_patch*) handle.Handle; + return (git_patch*)handle.AsIntPtr(); } } internal unsafe class ConfigurationHandle : Libgit2Object { internal ConfigurationHandle(git_config *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -200,21 +216,23 @@ internal ConfigurationHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_config_free((git_config*) ptr); + NativeMethods.git_config_free((git_config*)AsIntPtr()); + + return true; } public static implicit operator git_config*(ConfigurationHandle handle) { - return (git_config*) handle.Handle; + return (git_config*)handle.AsIntPtr(); } } internal unsafe class ConflictIteratorHandle : Libgit2Object { internal ConflictIteratorHandle(git_index_conflict_iterator *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -223,21 +241,23 @@ internal ConflictIteratorHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_index_conflict_iterator_free((git_index_conflict_iterator*) ptr); + NativeMethods.git_index_conflict_iterator_free((git_index_conflict_iterator*)AsIntPtr()); + + return true; } public static implicit operator git_index_conflict_iterator*(ConflictIteratorHandle handle) { - return (git_index_conflict_iterator*) handle.Handle; + return (git_index_conflict_iterator*)handle.AsIntPtr(); } } internal unsafe class IndexHandle : Libgit2Object { internal IndexHandle(git_index *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -246,21 +266,23 @@ internal IndexHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_index_free((git_index*) ptr); + NativeMethods.git_index_free((git_index*)AsIntPtr()); + + return true; } public static implicit operator git_index*(IndexHandle handle) { - return (git_index*) handle.Handle; + return (git_index*)handle.AsIntPtr(); } } internal unsafe class ReflogHandle : Libgit2Object { internal ReflogHandle(git_reflog *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -269,21 +291,23 @@ internal ReflogHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_reflog_free((git_reflog*) ptr); + NativeMethods.git_reflog_free((git_reflog*)AsIntPtr()); + + return true; } public static implicit operator git_reflog*(ReflogHandle handle) { - return (git_reflog*) handle.Handle; + return (git_reflog*)handle.AsIntPtr(); } } internal unsafe class TreeBuilderHandle : Libgit2Object { internal TreeBuilderHandle(git_treebuilder *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -292,21 +316,23 @@ internal TreeBuilderHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_treebuilder_free((git_treebuilder*) ptr); + NativeMethods.git_treebuilder_free((git_treebuilder*)AsIntPtr()); + + return true; } public static implicit operator git_treebuilder*(TreeBuilderHandle handle) { - return (git_treebuilder*) handle.Handle; + return (git_treebuilder*)handle.AsIntPtr(); } } internal unsafe class PackBuilderHandle : Libgit2Object { internal PackBuilderHandle(git_packbuilder *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -315,21 +341,23 @@ internal PackBuilderHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_packbuilder_free((git_packbuilder*) ptr); + NativeMethods.git_packbuilder_free((git_packbuilder*)AsIntPtr()); + + return true; } public static implicit operator git_packbuilder*(PackBuilderHandle handle) { - return (git_packbuilder*) handle.Handle; + return (git_packbuilder*)handle.AsIntPtr(); } } internal unsafe class NoteHandle : Libgit2Object { internal NoteHandle(git_note *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -338,21 +366,23 @@ internal NoteHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_note_free((git_note*) ptr); + NativeMethods.git_note_free((git_note*)AsIntPtr()); + + return true; } public static implicit operator git_note*(NoteHandle handle) { - return (git_note*) handle.Handle; + return (git_note*)handle.AsIntPtr(); } } internal unsafe class DescribeResultHandle : Libgit2Object { internal DescribeResultHandle(git_describe_result *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -361,21 +391,23 @@ internal DescribeResultHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_describe_result_free((git_describe_result*) ptr); + NativeMethods.git_describe_result_free((git_describe_result*)AsIntPtr()); + + return true; } public static implicit operator git_describe_result*(DescribeResultHandle handle) { - return (git_describe_result*) handle.Handle; + return (git_describe_result*)handle.AsIntPtr(); } } internal unsafe class SubmoduleHandle : Libgit2Object { internal SubmoduleHandle(git_submodule *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -384,21 +416,23 @@ internal SubmoduleHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_submodule_free((git_submodule*) ptr); + NativeMethods.git_submodule_free((git_submodule*)AsIntPtr()); + + return true; } public static implicit operator git_submodule*(SubmoduleHandle handle) { - return (git_submodule*) handle.Handle; + return (git_submodule*)handle.AsIntPtr(); } } internal unsafe class AnnotatedCommitHandle : Libgit2Object { internal AnnotatedCommitHandle(git_annotated_commit *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -407,21 +441,23 @@ internal AnnotatedCommitHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_annotated_commit_free((git_annotated_commit*) ptr); + NativeMethods.git_annotated_commit_free((git_annotated_commit*)AsIntPtr()); + + return true; } public static implicit operator git_annotated_commit*(AnnotatedCommitHandle handle) { - return (git_annotated_commit*) handle.Handle; + return (git_annotated_commit*)handle.AsIntPtr(); } } internal unsafe class ObjectDatabaseHandle : Libgit2Object { internal ObjectDatabaseHandle(git_odb *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -430,21 +466,23 @@ internal ObjectDatabaseHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_odb_free((git_odb*) ptr); + NativeMethods.git_odb_free((git_odb*)AsIntPtr()); + + return true; } public static implicit operator git_odb*(ObjectDatabaseHandle handle) { - return (git_odb*) handle.Handle; + return (git_odb*)handle.AsIntPtr(); } } internal unsafe class RevWalkerHandle : Libgit2Object { internal RevWalkerHandle(git_revwalk *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -453,21 +491,23 @@ internal RevWalkerHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_revwalk_free((git_revwalk*) ptr); + NativeMethods.git_revwalk_free((git_revwalk*)AsIntPtr()); + + return true; } public static implicit operator git_revwalk*(RevWalkerHandle handle) { - return (git_revwalk*) handle.Handle; + return (git_revwalk*)handle.AsIntPtr(); } } internal unsafe class RemoteHandle : Libgit2Object { internal RemoteHandle(git_remote *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -476,21 +516,23 @@ internal RemoteHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_remote_free((git_remote*) ptr); + NativeMethods.git_remote_free((git_remote*)AsIntPtr()); + + return true; } public static implicit operator git_remote*(RemoteHandle handle) { - return (git_remote*) handle.Handle; + return (git_remote*)handle.AsIntPtr(); } } internal unsafe class ObjectHandle : Libgit2Object { internal ObjectHandle(git_object *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -499,21 +541,23 @@ internal ObjectHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_object_free((git_object*) ptr); + NativeMethods.git_object_free((git_object*)AsIntPtr()); + + return true; } public static implicit operator git_object*(ObjectHandle handle) { - return (git_object*) handle.Handle; + return (git_object*)handle.AsIntPtr(); } } internal unsafe class RebaseHandle : Libgit2Object { internal RebaseHandle(git_rebase *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -522,21 +566,23 @@ internal RebaseHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_rebase_free((git_rebase*) ptr); + NativeMethods.git_rebase_free((git_rebase*)AsIntPtr()); + + return true; } public static implicit operator git_rebase*(RebaseHandle handle) { - return (git_rebase*) handle.Handle; + return (git_rebase*)handle.AsIntPtr(); } } internal unsafe class OdbStreamHandle : Libgit2Object { internal OdbStreamHandle(git_odb_stream *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -545,21 +591,23 @@ internal OdbStreamHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_odb_stream_free((git_odb_stream*) ptr); + NativeMethods.git_odb_stream_free((git_odb_stream*)AsIntPtr()); + + return true; } public static implicit operator git_odb_stream*(OdbStreamHandle handle) { - return (git_odb_stream*) handle.Handle; + return (git_odb_stream*)handle.AsIntPtr(); } } internal unsafe class WorktreeHandle : Libgit2Object { internal WorktreeHandle(git_worktree *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -568,14 +616,16 @@ internal WorktreeHandle(IntPtr ptr, bool owned) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.git_worktree_free((git_worktree*) ptr); + NativeMethods.git_worktree_free((git_worktree*)AsIntPtr()); + + return true; } public static implicit operator git_worktree*(WorktreeHandle handle) { - return (git_worktree*) handle.Handle; + return (git_worktree*)handle.AsIntPtr(); } } diff --git a/LibGit2Sharp/Core/Handles/Objects.tt b/LibGit2Sharp/Core/Handles/Objects.tt index a6d1fa251..93707590e 100644 --- a/LibGit2Sharp/Core/Handles/Objects.tt +++ b/LibGit2Sharp/Core/Handles/Objects.tt @@ -73,7 +73,7 @@ for (var i = 0; i < cNames.Length; i++) internal unsafe class <#= csNames[i] #> : Libgit2Object { internal <#= csNames[i] #>(<#= cNames[i] #> *ptr, bool owned) - : base((void *) ptr, owned) + : base(ptr, owned) { } @@ -82,14 +82,16 @@ for (var i = 0; i < cNames.Length; i++) { } - public override void Free() + protected override bool ReleaseHandle() { - NativeMethods.<#= cNames[i] #>_free((<#= cNames[i] #>*) ptr); + NativeMethods.<#= cNames[i] #>_free((<#= cNames[i] #>*)AsIntPtr()); + + return true; } public static implicit operator <#= cNames[i] #>*(<#= csNames[i] #> handle) { - return (<#= cNames[i] #>*) handle.Handle; + return (<#= cNames[i] #>*)handle.AsIntPtr(); } } diff --git a/LibGit2Sharp/Network.cs b/LibGit2Sharp/Network.cs index bd80834bb..ba0a33144 100644 --- a/LibGit2Sharp/Network.cs +++ b/LibGit2Sharp/Network.cs @@ -216,11 +216,11 @@ private IEnumerable ListReferencesInternal(string url, CredentialsHan static RemoteHandle BuildRemoteHandle(RepositoryHandle repoHandle, string url) { - Debug.Assert(repoHandle != null && !repoHandle.IsNull); + Debug.Assert(repoHandle != null && !repoHandle.IsInvalid); Debug.Assert(url != null); RemoteHandle remoteHandle = Proxy.git_remote_create_anonymous(repoHandle, url); - Debug.Assert(remoteHandle != null && !(remoteHandle.IsNull)); + Debug.Assert(remoteHandle != null && !remoteHandle.IsInvalid); return remoteHandle; } diff --git a/LibGit2Sharp/Reference.cs b/LibGit2Sharp/Reference.cs index 9530f2378..9a86195d1 100644 --- a/LibGit2Sharp/Reference.cs +++ b/LibGit2Sharp/Reference.cs @@ -35,7 +35,7 @@ private protected Reference(IRepository repo, string canonicalName, string targe // This overload lets public-facing methods avoid having to use the pointers directly internal static unsafe T BuildFromPtr(ReferenceHandle handle, Repository repo) where T : Reference { - return BuildFromPtr((git_reference*) handle.Handle, repo); + return BuildFromPtr((git_reference*)handle.AsIntPtr(), repo); } internal static unsafe T BuildFromPtr(git_reference* handle, Repository repo) where T : Reference diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index e23c9cd3b..fc777404e 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -575,7 +575,7 @@ internal GitObject LookupInternal(ObjectId id, GitObjectType type, string knownP using (ObjectHandle obj = Proxy.git_object_lookup(handle, id, type)) { - if (obj == null || obj.IsNull) + if (obj == null || obj.IsInvalid) { return null; } @@ -1781,7 +1781,7 @@ public void RevParse(string revision, out Reference reference, out GitObject obj using (var objH = handles.Item1) using (var refH = handles.Item2) { - reference = refH.IsNull ? null : Reference.BuildFromPtr(refH, this); + reference = refH.IsInvalid ? null : Reference.BuildFromPtr(refH, this); obj = GitObject.BuildFrom(this, Proxy.git_object_id(objH), Proxy.git_object_type(objH), PathFromRevparseSpec(revision)); } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy