// character set. It is only guaranteed to be larger or equal to cbLength, don't depend on the exact value.
unsafe internal static byte[] DoAnsiConversion(string str, bool fBestFit, bool fThrowOnUnmappableChar, out int cbLength)
{
- byte[] buffer = new byte[(str.Length + 1) * Marshal.SystemMaxDBCSCharSize];
- Debug.Assert(buffer.Length != 0);
+ byte[] buffer = new byte[checked((str.Length + 1) * Marshal.SystemMaxDBCSCharSize)];
fixed (byte* bufferPtr = &buffer[0])
{
cbLength = str.ConvertToAnsi(bufferPtr, buffer.Length, fBestFit, fThrowOnUnmappableChar);
return IntPtr.Zero;
}
- StubHelpers.CheckStringLength(strManaged.Length);
-
int nb;
byte* pbNativeBuffer = (byte*)pNativeBuffer;
// If we are marshaling into a stack buffer or we can accurately estimate the size of the required heap
// space, we will use a "1-pass" mode where we convert the string directly into the unmanaged buffer.
- // + 1 for the null character from the user
- nb = (strManaged.Length + 1) * Marshal.SystemMaxDBCSCharSize;
+ // + 1 for the null character from the user. + 1 for the null character we put in.
+ nb = checked((strManaged.Length + 1) * Marshal.SystemMaxDBCSCharSize + 1);
// Use the pre-allocated buffer (allocated by localloc IL instruction) if not NULL,
// otherwise fallback to AllocCoTaskMem
if (pbNativeBuffer == null)
{
- // + 1 for the null character we put in
- pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 1);
+ pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb);
}
- nb = strManaged.ConvertToAnsi(pbNativeBuffer, nb + 1, 0 != (flags & 0xFF), 0 != (flags >> 8));
+ nb = strManaged.ConvertToAnsi(pbNativeBuffer, nb,
+ fBestFit: 0 != (flags & 0xFF), fThrowOnUnmappableChar: 0 != (flags >> 8));
}
else
{
// wasting memory on systems with multibyte character sets where the buffer we end up with is often much
// smaller than the upper bound for the given managed string.
- byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, 0 != (flags & 0xFF), 0 != (flags >> 8), out nb);
+ byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged,
+ fBestFit: 0 != (flags & 0xFF), fThrowOnUnmappableChar: 0 != (flags >> 8), out nb);
// + 1 for the null character from the user. + 1 for the null character we put in.
pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 2);
{
return IntPtr.Zero;
}
- StubHelpers.CheckStringLength(strManaged.Length);
int nb;
byte* pbNativeBuffer = (byte*)pNativeBuffer;
}
else
{
- StubHelpers.CheckStringLength(strManaged.Length);
-
byte trailByte;
bool hasTrailByte = strManaged.TryGetTrailByte(out trailByte);
cch = strManaged.Length;
- StubHelpers.CheckStringLength(cch);
-
// length field at negative offset + (# of characters incl. the terminator) * max ANSI char size
- int nbytes = sizeof(uint) + ((cch + 1) * Marshal.SystemMaxDBCSCharSize);
+ int nbytes = checked(sizeof(uint) + ((cch + 1) * Marshal.SystemMaxDBCSCharSize));
pNative = (byte*)Marshal.AllocCoTaskMem(nbytes);
int* pLength = (int*)pNative;
return IntPtr.Zero;
}
- int length = strManaged.Length;
-
- StubHelpers.CheckStringLength(length);
-
byte[] bytes = null;
int nb = 0;
- if (length > 0)
+ if (strManaged.Length > 0)
{
bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, 0 != (flags & 0xFF), 0 != (flags >> 8), out nb);
}
else
{
// marshal the object as Unicode string (UnmanagedType.LPWStr)
- StubHelpers.CheckStringLength(pManagedHome.Length);
int allocSize = (pManagedHome.Length + 1) * 2;
pNativeHome = Marshal.AllocCoTaskMem(allocSize);
StubHelpers.CheckStringLength(pManagedHome.Capacity);
// marshal the object as Ansi string (UnmanagedType.LPStr)
- int allocSize = (pManagedHome.Capacity * Marshal.SystemMaxDBCSCharSize) + 4;
+ int allocSize = checked((pManagedHome.Capacity * Marshal.SystemMaxDBCSCharSize) + 4);
pNativeHome = Marshal.AllocCoTaskMem(allocSize);
byte* ptr = (byte*)pNativeHome;
else
{
// marshal the object as Unicode string (UnmanagedType.LPWStr)
- int allocSize = (pManagedHome.Capacity * 2) + 4;
+ int allocSize = checked((pManagedHome.Capacity * 2) + 4);
pNativeHome = Marshal.AllocCoTaskMem(allocSize);
byte* ptr = (byte*)pNativeHome;
{
STANDARD_VM_CONTRACT;
+ // Note: The maximum size of managed string is under 2GB bytes. This cannot overflow.
pslILEmit->EmitCALL(METHOD__STRING__GET_LENGTH, 1, 1);
pslILEmit->EmitLDC(1);
pslILEmit->EmitADD();
pslILEmit->EmitDUP();
- pslILEmit->EmitCALL(METHOD__STUBHELPERS__CHECK_STRING_LENGTH, 1, 0);
- pslILEmit->EmitDUP();
pslILEmit->EmitADD(); // (length+1) * sizeof(WCHAR)
}
// stack: capacity
pslILEmit->EmitLDSFLD(pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__MARSHAL__SYSTEM_MAX_DBCS_CHAR_SIZE)));
- pslILEmit->EmitMUL();
+ pslILEmit->EmitMUL_OVF();
// stack: capacity_in_bytes
pslILEmit->EmitLDC(1);
- pslILEmit->EmitADD();
+ pslILEmit->EmitADD_OVF();
// stack: offset_of_secret_null
pslILEmit->EmitSTLOC(dwTmpOffsetOfSecretNull); // make sure the stack is empty for localloc
pslILEmit->EmitLDC(3);
- pslILEmit->EmitADD();
+ pslILEmit->EmitADD_OVF();
// stack: alloc_size_in_bytes
ILCodeLabel *pAllocRejoin = pslILEmit->NewCodeLabel();
// (String.Length + 2) * GetMaxDBCSCharByteSize()
pslILEmit->EmitLDSFLD(pslILEmit->GetToken(MscorlibBinder::GetField(FIELD__MARSHAL__SYSTEM_MAX_DBCS_CHAR_SIZE)));
- pslILEmit->EmitMUL();
+ pslILEmit->EmitMUL_OVF();
// BufSize = (String.Length + 2) * GetMaxDBCSCharByteSize()
pslILEmit->EmitSTLOC(dwBufSize);