Skip to content

Commit 5446b7b

Browse files
committed
Make string marshaling either lax or strict
1 parent 638dedb commit 5446b7b

21 files changed

+250
-163
lines changed

LibGit2Sharp/BranchCollection.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ private Branch BuildFromReferenceName(string canonicalName)
9191
/// <returns>An <see cref="IEnumerator{T}"/> object that can be used to iterate through the collection.</returns>
9292
public virtual IEnumerator<Branch> GetEnumerator()
9393
{
94-
return Proxy.git_branch_foreach(repo.Handle, GitBranchType.GIT_BRANCH_LOCAL | GitBranchType.GIT_BRANCH_REMOTE, branchToCanoncialName)
94+
return Proxy.git_branch_foreach(repo.Handle, GitBranchType.GIT_BRANCH_LOCAL | GitBranchType.GIT_BRANCH_REMOTE, BranchToCanoncialName)
9595
.Select(n => this[n])
9696
.GetEnumerator();
9797
}
@@ -203,9 +203,9 @@ private static bool LooksLikeABranchName(string referenceName)
203203
referenceName.LooksLikeRemoteTrackingBranch();
204204
}
205205

206-
private static string branchToCanoncialName(IntPtr namePtr, GitBranchType branchType)
206+
private static string BranchToCanoncialName(IntPtr namePtr, GitBranchType branchType)
207207
{
208-
string shortName = Utf8Marshaler.FromNative(namePtr);
208+
string shortName = LaxUtf8Marshaler.FromNative(namePtr);
209209

210210
switch (branchType)
211211
{

LibGit2Sharp/CheckoutCallbacks.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ private void OnGitCheckoutProgress(IntPtr str, UIntPtr completedSteps, UIntPtr t
8686
if (onCheckoutProgress != null)
8787
{
8888
// Convert null strings into empty strings.
89-
string path = (str != IntPtr.Zero) ? Utf8Marshaler.FromNative(str) : string.Empty;
89+
FilePath path = (str != IntPtr.Zero) ? LaxFilePathMarshaler.FromNative(str) : FilePath.Empty;
9090

91-
onCheckoutProgress(path, (int)completedSteps, (int)totalSteps);
91+
onCheckoutProgress(path.Native, (int)completedSteps, (int)totalSteps);
9292
}
9393
}
9494

@@ -103,9 +103,9 @@ private int OnGitCheckoutNotify(
103103
int result = 0;
104104
if (this.onCheckoutNotify != null)
105105
{
106-
string path = (pathPtr != IntPtr.Zero) ?
107-
((FilePath)Utf8Marshaler.FromNative(pathPtr)).Native : string.Empty;
108-
result = onCheckoutNotify(path, why) ? 0 : 1;
106+
FilePath path = (pathPtr != IntPtr.Zero) ?
107+
LaxFilePathMarshaler.FromNative(pathPtr) : FilePath.Empty;
108+
result = onCheckoutNotify(path.Native, why) ? 0 : 1;
109109
}
110110

111111
return result;

LibGit2Sharp/Configuration.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,8 @@ private IEnumerable<ConfigurationEntry<string>> BuildConfigEntries()
282282
{
283283
var entry = (GitConfigEntry)Marshal.PtrToStructure(entryPtr, typeof(GitConfigEntry));
284284

285-
return new ConfigurationEntry<string>(Utf8Marshaler.FromNative(entry.namePtr),
286-
Utf8Marshaler.FromNative(entry.valuePtr),
285+
return new ConfigurationEntry<string>(LaxUtf8Marshaler.FromNative(entry.namePtr),
286+
LaxUtf8Marshaler.FromNative(entry.valuePtr),
287287
(ConfigurationLevel)entry.level);
288288
});
289289
}

LibGit2Sharp/ContentChanges.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ private int FileCallback(GitDiffDelta delta, float progress, IntPtr payload)
3939

4040
private int HunkCallback(GitDiffDelta delta, GitDiffRange range, IntPtr header, UIntPtr headerlen, IntPtr payload)
4141
{
42-
string decodedContent = Utf8Marshaler.FromNative(header, (int)headerlen);
42+
string decodedContent = LaxUtf8Marshaler.FromNative(header, (int)headerlen);
4343

4444
AppendToPatch(decodedContent);
4545
return 0;
4646
}
4747

4848
private int LineCallback(GitDiffDelta delta, GitDiffRange range, GitDiffLineOrigin lineorigin, IntPtr content, UIntPtr contentlen, IntPtr payload)
4949
{
50-
string decodedContent = Utf8Marshaler.FromNative(content, (int)contentlen);
50+
string decodedContent = LaxUtf8Marshaler.FromNative(content, (int)contentlen);
5151

5252
string prefix;
5353

LibGit2Sharp/Core/Ensure.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ private static void HandleError(int result)
9696
}
9797
else
9898
{
99-
errorMessage = Utf8Marshaler.FromNative(error.Message);
99+
errorMessage = LaxUtf8Marshaler.FromNative(error.Message);
100100
}
101101

102102
Func<string, GitErrorCode, GitErrorCategory, LibGit2SharpException> exceptionBuilder;

LibGit2Sharp/Core/FilePathMarshaler.cs

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Runtime.InteropServices;
3+
using System.Text;
34

45
namespace LibGit2Sharp.Core
56
{
@@ -11,13 +12,13 @@ namespace LibGit2Sharp.Core
1112
/// Use this marshaler for return values, for example:
1213
/// [return: MarshalAs(UnmanagedType.CustomMarshaler,
1314
/// MarshalCookie = UniqueId.UniqueIdentifier,
14-
/// MarshalTypeRef = typeof(FilePathNoCleanupMarshaler))]
15+
/// MarshalTypeRef = typeof(LaxFilePathNoCleanupMarshaler))]
1516
/// </summary>
16-
internal class FilePathNoCleanupMarshaler : FilePathMarshaler
17+
internal class LaxFilePathNoCleanupMarshaler : LaxFilePathMarshaler
1718
{
18-
private static readonly FilePathNoCleanupMarshaler staticInstance = new FilePathNoCleanupMarshaler();
19+
private static readonly LaxFilePathNoCleanupMarshaler staticInstance = new LaxFilePathNoCleanupMarshaler();
1920

20-
public static new ICustomMarshaler GetInstance(String cookie)
21+
public new static ICustomMarshaler GetInstance(String cookie)
2122
{
2223
return staticInstance;
2324
}
@@ -43,11 +44,11 @@ public override void CleanUpNativeData(IntPtr pNativeData)
4344
/// internal static extern int git_index_open(out IndexSafeHandle index,
4445
/// [MarshalAs(UnmanagedType.CustomMarshaler,
4546
/// MarshalCookie = UniqueId.UniqueIdentifier,
46-
/// MarshalTypeRef = typeof(FilePathMarshaler))] FilePath indexpath);
47+
/// MarshalTypeRef = typeof(StrictFilePathMarshaler))] FilePath indexpath);
4748
/// </summary>
48-
internal class FilePathMarshaler : Utf8Marshaler
49+
internal class StrictFilePathMarshaler : StrictUtf8Marshaler
4950
{
50-
private static readonly FilePathMarshaler staticInstance = new FilePathMarshaler();
51+
private static readonly StrictFilePathMarshaler staticInstance = new StrictFilePathMarshaler();
5152

5253
public new static ICustomMarshaler GetInstance(String cookie)
5354
{
@@ -74,9 +75,10 @@ public override IntPtr MarshalManagedToNative(Object managedObj)
7475
return FromManaged(filePath);
7576
}
7677

77-
public override Object MarshalNativeToManaged(IntPtr pNativeData)
78+
public override object MarshalNativeToManaged(IntPtr pNativeData)
7879
{
79-
return (FilePath)FromNative(pNativeData);
80+
throw new InvalidOperationException(
81+
string.Format("{0} cannot be used to retrieve data from libgit2.", GetType().Name));
8082
}
8183

8284
#endregion
@@ -88,7 +90,52 @@ public static IntPtr FromManaged(FilePath filePath)
8890
return IntPtr.Zero;
8991
}
9092

91-
return Utf8Marshaler.FromManaged(filePath.Posix);
93+
return StrictUtf8Marshaler.FromManaged(filePath.Posix);
94+
}
95+
}
96+
97+
/// <summary>
98+
/// This marshaler is to be used for capturing a UTF-8 string allocated by libgit2 and
99+
/// converting it to a managed FilePath instance. The marshaler will free the native pointer
100+
/// after conversion.
101+
/// </summary>
102+
internal class LaxFilePathMarshaler : EncodingMarshaler
103+
{
104+
private static readonly LaxFilePathMarshaler staticInstance = new LaxFilePathMarshaler();
105+
106+
private static readonly Encoding encoding = new UTF8Encoding(true, false);
107+
108+
public LaxFilePathMarshaler() : base(encoding)
109+
{ }
110+
111+
#region ICustomMarshaler
112+
113+
public override IntPtr MarshalManagedToNative(object managedObj)
114+
{
115+
throw new InvalidOperationException(
116+
string.Format("{0} cannot be used to pass data to libgit2.", GetType().Name));
117+
}
118+
119+
public override Object MarshalNativeToManaged(IntPtr pNativeData)
120+
{
121+
return FromNative(pNativeData);
122+
}
123+
124+
#endregion
125+
126+
public static ICustomMarshaler GetInstance(String cookie)
127+
{
128+
return staticInstance;
129+
}
130+
131+
public static FilePath FromNative(IntPtr pNativeData)
132+
{
133+
return FromNative(encoding, pNativeData);
134+
}
135+
136+
public static FilePath FromBuffer(byte[] buffer)
137+
{
138+
return FromBuffer(encoding, buffer);
92139
}
93140
}
94141
}

LibGit2Sharp/Core/GitRepositoryInitOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static GitRepositoryInitOptions BuildFrom(FilePath workdirPath, bool isBa
2828
{
2929
Debug.Assert(!isBare);
3030

31-
opts.WorkDirPath = FilePathMarshaler.FromManaged(workdirPath);
31+
opts.WorkDirPath = StrictFilePathMarshaler.FromManaged(workdirPath);
3232
}
3333

3434
if (isBare)

LibGit2Sharp/Core/GitStrArrayIn.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static GitStrArrayIn BuildFrom(FilePath[] paths)
2020
for (int i = 0; i < nbOfPaths; i++)
2121
{
2222
var s = paths[i].Posix;
23-
pathPtrs[i] = FilePathMarshaler.FromManaged(s);
23+
pathPtrs[i] = StrictFilePathMarshaler.FromManaged(s);
2424
}
2525

2626
int dim = IntPtr.Size * nbOfPaths;

0 commit comments

Comments
 (0)