Imported Upstream version 4.6.0.125

Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-08-03 10:59:49 +00:00
parent a569aebcfd
commit e79aa3c0ed
17047 changed files with 3137615 additions and 392334 deletions

View File

@@ -0,0 +1,84 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Debugger.Symbol
{
using System.Globalization;
using System.IO;
using System.Runtime;
// Represent the debug symbol for an Activity.
// It defines the start/end of Activity in the Xaml file.
public class ActivitySymbol
{
public int StartLine { get; internal set; }
public int StartColumn { get; internal set; }
public int EndLine { get; internal set; }
public int EndColumn { get; internal set; }
// Internal representation of QualifiedId.
internal byte[] QualifiedId { get; set; }
string id;
// Publicly available Id.
public string Id
{
get
{
if (this.id == null)
{
if (this.QualifiedId != null)
{
this.id = new QualifiedId(this.QualifiedId).ToString();
}
else
{
this.id = string.Empty;
}
}
return this.id;
}
}
// Binary serializer.
internal void Write(BinaryWriter writer)
{
SymbolHelper.WriteEncodedInt32(writer, this.StartLine);
SymbolHelper.WriteEncodedInt32(writer, this.StartColumn);
SymbolHelper.WriteEncodedInt32(writer, this.EndLine);
SymbolHelper.WriteEncodedInt32(writer, this.EndColumn);
if (this.QualifiedId != null)
{
SymbolHelper.WriteEncodedInt32(writer, this.QualifiedId.Length);
writer.Write(this.QualifiedId, 0, this.QualifiedId.Length);
}
else
{
SymbolHelper.WriteEncodedInt32(writer, 0);
}
}
// Binary deserializer.
internal ActivitySymbol(BinaryReader reader)
{
this.StartLine = SymbolHelper.ReadEncodedInt32(reader);
this.StartColumn = SymbolHelper.ReadEncodedInt32(reader);
this.EndLine = SymbolHelper.ReadEncodedInt32(reader);
this.EndColumn = SymbolHelper.ReadEncodedInt32(reader);
int qidLength = SymbolHelper.ReadEncodedInt32(reader);
if (qidLength > 0)
{
this.QualifiedId = reader.ReadBytes(qidLength);
}
}
internal ActivitySymbol()
{
}
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3},{4}", this.Id, this.StartLine, this.StartColumn, this.EndLine, this.EndColumn);
}
}
}

View File

@@ -0,0 +1,41 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Debugger.Symbol
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Xaml;
using System.Runtime;
[Fx.Tag.XamlVisible(false)]
public static class DebugSymbol
{
static Type attachingTypeName = typeof(DebugSymbol);
[SuppressMessage(FxCop.Category.Security, FxCop.Rule.DoNotDeclareReadOnlyMutableReferenceTypes)]
public static readonly AttachableMemberIdentifier SymbolName = new AttachableMemberIdentifier(attachingTypeName, "Symbol");
[Fx.Tag.InheritThrows(From = "SetProperty", FromDeclaringType = typeof(AttachablePropertyServices))]
public static void SetSymbol(object instance, object value)
{
AttachablePropertyServices.SetProperty(instance, SymbolName, value);
}
[Fx.Tag.InheritThrows(From = "TryGetProperty", FromDeclaringType = typeof(AttachablePropertyServices))]
public static object GetSymbol(object instance)
{
string value;
if (AttachablePropertyServices.TryGetProperty(instance, SymbolName, out value))
{
return value;
}
else
{
return string.Empty;
}
}
}
}

View File

@@ -0,0 +1,114 @@
//-----------------------------------------------------------------------
// <copyright file="SymbolHelper.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace System.Activities.Debugger.Symbol
{
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime;
using System.Security;
using System.Security.Cryptography;
internal static class SymbolHelper
{
// This is the same Encode/Decode logic as the WCF FramingEncoder
public static int ReadEncodedInt32(BinaryReader reader)
{
int value = 0;
int bytesConsumed = 0;
while (true)
{
int next = reader.ReadByte();
value |= (next & 0x7F) << (bytesConsumed * 7);
bytesConsumed++;
if ((next & 0x80) == 0)
{
break;
}
}
return value;
}
// This is the same Encode/Decode logic as the WCF FramingEncoder
public static void WriteEncodedInt32(BinaryWriter writer, int value)
{
Fx.Assert(value >= 0, "Must be non-negative");
while ((value & 0xFFFFFF80) != 0)
{
writer.Write((byte)((value & 0x7F) | 0x80));
value >>= 7;
}
writer.Write((byte)value);
}
public static int GetEncodedSize(int value)
{
Fx.Assert(value >= 0, "Must be non-negative");
int count = 1;
while ((value & 0xFFFFFF80) != 0)
{
count++;
value >>= 7;
}
return count;
}
[SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed",
Justification = "Design has been approved. We are not using MD5 for any security or cryptography purposes but rather as a hash.")]
public static byte[] CalculateChecksum(string fileName)
{
Fx.Assert(!string.IsNullOrEmpty(fileName), "fileName should not be empty or null");
byte[] checksum;
try
{
using (StreamReader streamReader = new StreamReader(fileName))
{
MD5 md5 = new MD5CryptoServiceProvider();
checksum = md5.ComputeHash(streamReader.BaseStream);
}
}
catch (IOException)
{
// DirectoryNotFoundException and FileNotFoundException are expected
checksum = null;
}
catch (UnauthorizedAccessException)
{
// UnauthorizedAccessException is expected
checksum = null;
}
catch (SecurityException)
{
// Must not have had enough permissions to access the file.
checksum = null;
}
return checksum;
}
[Fx.Tag.SecurityNote(Critical = "Used to get a string from checksum that is provided by the user/from a file.",
Safe = "We not exposing any critical data. Just converting the byte array to a hex string.")]
[SecuritySafeCritical]
public static string GetHexStringFromChecksum(byte[] checksum)
{
return checksum == null ? string.Empty : string.Join(string.Empty, checksum.Select(x => x.ToString("X2")).ToArray());
}
[Fx.Tag.SecurityNote(Critical = "Used to validate checksum that is provided by the user/from a file.",
Safe = "We not exposing any critical data. Just validating that the provided checksum meets the format for the checksums we produce.")]
[SecuritySafeCritical]
internal static bool ValidateChecksum(byte[] checksumToValidate)
{
// We are using MD5.ComputeHash, which will return a 16 byte array.
return checksumToValidate.Length == 16;
}
}
}

View File

@@ -0,0 +1,217 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Debugger.Symbol
{
using System;
using System.IO;
using System.IO.Compression;
using System.Runtime;
using System.Runtime.Serialization;
using System.Text;
using System.Globalization;
using System.Collections.Generic;
using System.Security.Cryptography;
// Represent debug symbol of a workflow tree (similar to pdb file).
// It contains the absolute path of the xaml file and the location of each activity in the workflow tree.
// This is used to instrument the workflow without having access to the original xaml file.
public class WorkflowSymbol
{
public string FileName { get; set; }
public ICollection<ActivitySymbol> Symbols { get; set; }
private byte[] checksum;
public byte[] GetChecksum()
{
if (this.checksum == null)
{
return null;
}
return (byte[]) this.checksum.Clone();
}
[Flags]
internal enum EncodingFormat : byte
{
String = 0x76, // Format as well as cookie. String format is hidden from public.
Binary = 0x77,
Checksum = 0x80
}
internal const EncodingFormat DefaultEncodingFormat = EncodingFormat.Binary;
public WorkflowSymbol()
{
}
// These constructors are private and used by Decode() method.
// Binary deserializer.
WorkflowSymbol(BinaryReader reader, byte[] checksum)
{
this.FileName = reader.ReadString();
int numSymbols = SymbolHelper.ReadEncodedInt32(reader);
this.Symbols = new List<ActivitySymbol>(numSymbols);
for (int i = 0; i < numSymbols; ++i)
{
this.Symbols.Add(new ActivitySymbol(reader));
}
this.checksum = checksum;
}
// Decode from Base64 string.
public static WorkflowSymbol Decode(string symbolString)
{
byte[] data = Convert.FromBase64String(symbolString);
using (BinaryReader reader = new BinaryReader(new MemoryStream(data)))
{
byte[] checksum = null;
EncodingFormat format = (EncodingFormat)reader.ReadByte();
int payloadBytesCount = data.Length - sizeof(EncodingFormat);
if (0 != (format & EncodingFormat.Checksum))
{
int bytesCount = SymbolHelper.ReadEncodedInt32(reader);
checksum = reader.ReadBytes(bytesCount);
payloadBytesCount -= SymbolHelper.GetEncodedSize(bytesCount);
format &= (~EncodingFormat.Checksum);
}
switch (format)
{
case EncodingFormat.Binary:
return ParseBinary(reader.ReadBytes(payloadBytesCount), checksum); // Compute the
case EncodingFormat.String:
return ParseStringRepresentation(reader.ReadString(), checksum);
}
}
throw FxTrace.Exception.AsError(new SerializationException());
}
// Serialization
// Encode to Base64 string
public string Encode()
{
return Encode(WorkflowSymbol.DefaultEncodingFormat); // default format
}
internal string Encode(EncodingFormat encodingFormat)
{
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(ms))
{
if (this.checksum != null)
{
writer.Write((byte)(encodingFormat | EncodingFormat.Checksum));
SymbolHelper.WriteEncodedInt32(writer, this.checksum.Length);
writer.Write(this.checksum);
}
else
{
writer.Write((byte)encodingFormat);
}
switch (encodingFormat)
{
case EncodingFormat.Binary:
this.Write(writer);
break;
case EncodingFormat.String:
writer.Write(this.ToString());
break;
default:
throw FxTrace.Exception.AsError(new SerializationException());
}
// Need to copy to a buffer to trim excess capacity.
byte[] buffer = new byte[ms.Length];
Array.Copy(ms.GetBuffer(), buffer, ms.Length);
return Convert.ToBase64String(buffer);
}
}
}
// Binary deserializer
static WorkflowSymbol ParseBinary(byte[] bytes, byte[] checksum)
{
using (BinaryReader reader = new BinaryReader(new MemoryStream(bytes)))
{
return new WorkflowSymbol(reader, checksum);
}
}
// Binary serializer
void Write(BinaryWriter writer)
{
writer.Write(this.FileName ?? string.Empty);
if (this.Symbols != null)
{
SymbolHelper.WriteEncodedInt32(writer, this.Symbols.Count);
foreach (ActivitySymbol actSym in this.Symbols)
{
actSym.Write(writer);
}
}
else
{
SymbolHelper.WriteEncodedInt32(writer, 0);
}
}
// String encoding serialization.
// This is used for String encoding format.
public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("{0}", this.FileName ?? string.Empty);
if (this.Symbols != null)
{
foreach (ActivitySymbol symbol in Symbols)
{
builder.AppendFormat(";{0}", symbol.ToString());
}
}
return builder.ToString();
}
// Deserialization of string encoding format.
static WorkflowSymbol ParseStringRepresentation(string symbolString, byte[] checksum)
{
string[] s = symbolString.Split(';');
int numSymbols = s.Length - 1;
ActivitySymbol[] symbols = new ActivitySymbol[numSymbols];
for (int i = 0; i < numSymbols; ++i)
{
string[] symbolSegments = s[i + 1].Split(',');
Fx.Assert(symbolSegments.Length == 5, "Invalid activity symbol");
symbols[i] = new ActivitySymbol
{
QualifiedId = QualifiedId.Parse(symbolSegments[0]).AsByteArray(),
StartLine = int.Parse(symbolSegments[1], CultureInfo.InvariantCulture),
StartColumn = int.Parse(symbolSegments[2], CultureInfo.InvariantCulture),
EndLine = int.Parse(symbolSegments[3], CultureInfo.InvariantCulture),
EndColumn = int.Parse(symbolSegments[4], CultureInfo.InvariantCulture)
};
}
return new WorkflowSymbol
{
FileName = s[0],
Symbols = symbols,
checksum = checksum
};
}
public bool CalculateChecksum()
{
this.checksum = null;
if (!string.IsNullOrEmpty(this.FileName))
{
this.checksum = SymbolHelper.CalculateChecksum(this.FileName);
}
return (this.checksum != null);
}
}
}