private static unsafe int DecodeBitStringHelper(ArrayList resultList, SafeBerHandle berElement) { int error; // return a bitstring and its length IntPtr ptrResult = IntPtr.Zero; int length = 0; error = BerPal.ScanNextBitString(berElement, "B", ref ptrResult, ref length); if (!BerPal.IsBerDecodeError(error)) { byte[] byteArray = null; if (ptrResult != IntPtr.Zero) { byteArray = new byte[length]; Marshal.Copy(ptrResult, byteArray, 0, length); } resultList.Add(byteArray); } else { Debug.WriteLine("ber_scanf for format character 'B' failed"); } // no need to free memory as wldap32 returns the original pointer instead of a duplicating memory pointer that // needs to be freed return(error); }
private static byte[][] DecodingMultiByteArrayHelper(SafeBerHandle berElement, char fmt, ref int error) { error = 0; // several berval IntPtr ptrResult = IntPtr.Zero; int i = 0; ArrayList binaryList = new ArrayList(); IntPtr tempPtr = IntPtr.Zero; byte[][] result = null; try { error = BerPal.ScanNextPtr(berElement, new string(fmt, 1), ref ptrResult); if (!BerPal.IsBerDecodeError(error)) { if (ptrResult != IntPtr.Zero) { tempPtr = Marshal.ReadIntPtr(ptrResult); while (tempPtr != IntPtr.Zero) { berval ber = new berval(); Marshal.PtrToStructure(tempPtr, ber); byte[] berArray = new byte[ber.bv_len]; Marshal.Copy(ber.bv_val, berArray, 0, ber.bv_len); binaryList.Add(berArray); i++; tempPtr = Marshal.ReadIntPtr(ptrResult, i * IntPtr.Size); } result = new byte[binaryList.Count][]; for (int j = 0; j < binaryList.Count; j++) { result[j] = (byte[])binaryList[j]; } } } else { Debug.WriteLine("ber_scanf for format character 'V' failed"); } } finally { if (ptrResult != IntPtr.Zero) { BerPal.FreeBervalArray(ptrResult); } } return(result); }
private static int DecodeBitStringHelper(ArrayList resultList, SafeBerHandle berElement) { // Windows doesn't really decode BitStrings correctly, and wldap32 will internally treat it as 'O' Octet string. // In order to match behavior, in Linux we will interpret 'B' as 'O' when passing the call to libldap. // return BerVal byte[] byteArray = DecodingByteArrayHelper(berElement, 'O', out int error); if (!BerPal.IsBerDecodeError(error)) { // add result to the list resultList.Add(byteArray); } return(error); }
private static byte[] DecodingByteArrayHelper(SafeBerHandle berElement, char fmt, ref int error) { error = 0; IntPtr result = IntPtr.Zero; berval binaryValue = new berval(); byte[] byteArray = null; // can't use SafeBerval here as CLR creates a SafeBerval which points to a different memory location, but when doing memory // deallocation, wldap has special check. So have to use IntPtr directly here. error = BerPal.ScanNextPtr(berElement, new string(fmt, 1), ref result); try { if (!BerPal.IsBerDecodeError(error)) { if (result != IntPtr.Zero) { Marshal.PtrToStructure(result, binaryValue); byteArray = new byte[binaryValue.bv_len]; Marshal.Copy(binaryValue.bv_val, byteArray, 0, binaryValue.bv_len); } } else { Debug.WriteLine("ber_scanf for format character 'O' failed"); } } finally { if (result != IntPtr.Zero) { BerPal.FreeBerval(result); } } return(byteArray); }
internal static object[] TryDecode(string format, byte[] value, out bool decodeSucceeded) { if (format == null) { throw new ArgumentNullException(nameof(format)); } Debug.WriteLine("Begin decoding"); UTF8Encoding utf8Encoder = new UTF8Encoding(false, true); berval berValue = new berval(); ArrayList resultList = new ArrayList(); SafeBerHandle berElement = null; object[] decodeResult = null; decodeSucceeded = false; if (value == null) { berValue.bv_len = 0; berValue.bv_val = IntPtr.Zero; } else { berValue.bv_len = value.Length; berValue.bv_val = Marshal.AllocHGlobal(value.Length); Marshal.Copy(value, 0, berValue.bv_val, value.Length); } try { berElement = new SafeBerHandle(berValue); } finally { if (berValue.bv_val != IntPtr.Zero) { Marshal.FreeHGlobal(berValue.bv_val); } } int error = 0; for (int formatCount = 0; formatCount < format.Length; formatCount++) { char fmt = format[formatCount]; if (fmt == '{' || fmt == '}' || fmt == '[' || fmt == ']' || fmt == 'n' || fmt == 'x') { error = BerPal.ScanNext(berElement, new string(fmt, 1)); if (BerPal.IsBerDecodeError(error)) { Debug.WriteLine("ber_scanf for {, }, [, ], n or x failed"); } } else if (fmt == 'i' || fmt == 'e' || fmt == 'b') { int result = 0; error = BerPal.ScanNextInt(berElement, new string(fmt, 1), ref result); if (!BerPal.IsBerDecodeError(error)) { if (fmt == 'b') { // should return a bool bool boolResult = false; if (result == 0) { boolResult = false; } else { boolResult = true; } resultList.Add(boolResult); } else { resultList.Add(result); } } else { Debug.WriteLine("ber_scanf for format character 'i', 'e' or 'b' failed"); } } else if (fmt == 'a') { // return a string byte[] byteArray = DecodingByteArrayHelper(berElement, 'O', ref error); if (!BerPal.IsBerDecodeError(error)) { string s = null; if (byteArray != null) { s = utf8Encoder.GetString(byteArray); } resultList.Add(s); } } else if (fmt == 'O') { // return berval byte[] byteArray = DecodingByteArrayHelper(berElement, fmt, ref error); if (!BerPal.IsBerDecodeError(error)) { // add result to the list resultList.Add(byteArray); } } else if (fmt == 'B') { error = DecodeBitStringHelper(resultList, berElement); } else if (fmt == 'v') { //null terminate strings byte[][] byteArrayresult = null; string[] stringArray = null; byteArrayresult = DecodingMultiByteArrayHelper(berElement, 'V', ref error); if (!BerPal.IsBerDecodeError(error)) { if (byteArrayresult != null) { stringArray = new string[byteArrayresult.Length]; for (int i = 0; i < byteArrayresult.Length; i++) { if (byteArrayresult[i] == null) { stringArray[i] = null; } else { stringArray[i] = utf8Encoder.GetString(byteArrayresult[i]); } } } resultList.Add(stringArray); } } else if (fmt == 'V') { byte[][] result = null; result = DecodingMultiByteArrayHelper(berElement, fmt, ref error); if (!BerPal.IsBerDecodeError(error)) { resultList.Add(result); } } else { Debug.WriteLine("Format string contains undefined character\n"); throw new ArgumentException(SR.BerConverterUndefineChar); } if (BerPal.IsBerDecodeError(error)) { // decode failed, just return return(decodeResult); } } decodeResult = new object[resultList.Count]; for (int count = 0; count < resultList.Count; count++) { decodeResult[count] = resultList[count]; } decodeSucceeded = true; return(decodeResult); }