ULONG _detectAndSkipVASentinel(PCCOR_SIGNATURE sig) { ULONG cb = 0; ULONG elementType = ELEMENT_TYPE_MAX; cb += CorSigUncompressData(sig, &elementType); if (CorIsModifierElementType((CorElementType)elementType) && (elementType == ELEMENT_TYPE_SENTINEL)) { return cb; } else { return 0; } }
HRESULT _CountBytesOfOneArg( PCCOR_SIGNATURE pbSig, ULONG *pcbTotal) // Initially, *pcbTotal contains the remaining size of the sig blob { ULONG cb; ULONG cbTotal=0; ULONG cbTotalMax; CorElementType ulElementType; ULONG ulData; ULONG ulTemp; int iData; mdToken tk; ULONG cArg; ULONG callingconv; ULONG cArgsIndex; HRESULT hr = NOERROR; if(pcbTotal==NULL) return E_FAIL; cbTotalMax = *pcbTotal; CHECK_REMAINDER; cbTotal = CorSigUncompressElementType(pbSig, &ulElementType); while (CorIsModifierElementType((CorElementType) ulElementType)) { CHECK_REMAINDER; cbTotal += CorSigUncompressElementType(&pbSig[cbTotal], &ulElementType); } switch (ulElementType) { case ELEMENT_TYPE_SZARRAY: case 0x1e /* obsolete */: // skip over base type CHECK_REMAINDER; cb = cbTotalMax - cbTotal; IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) ); cbTotal += cb; break; case ELEMENT_TYPE_FNPTR: CHECK_REMAINDER; cbTotal += CorSigUncompressData (&pbSig[cbTotal], &callingconv); // remember number of bytes to represent the arg counts CHECK_REMAINDER; cbTotal += CorSigUncompressData (&pbSig[cbTotal], &cArg); // how many bytes to represent the return type CHECK_REMAINDER; cb = cbTotalMax - cbTotal; IfFailGo( _CountBytesOfOneArg( &pbSig[cbTotal], &cb) ); cbTotal += cb; // loop through argument for (cArgsIndex = 0; cArgsIndex < cArg; cArgsIndex++) { CHECK_REMAINDER; cb = cbTotalMax - cbTotal; IfFailGo( _CountBytesOfOneArg( &pbSig[cbTotal], &cb) ); cbTotal += cb; } break; case ELEMENT_TYPE_ARRAY: // syntax : ARRAY BaseType <rank> [i size_1... size_i] [j lowerbound_1 ... lowerbound_j] // skip over base type CHECK_REMAINDER; cb = cbTotalMax - cbTotal; IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) ); cbTotal += cb; // Parse for the rank CHECK_REMAINDER; cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData); // if rank == 0, we are done if (ulData == 0) break; // any size of dimension specified? CHECK_REMAINDER; cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData); while (ulData--) { CHECK_REMAINDER; cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulTemp); } // any lower bound specified? CHECK_REMAINDER; cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData); while (ulData--) { CHECK_REMAINDER; cbTotal += CorSigUncompressSignedInt(&pbSig[cbTotal], &iData); } break; case ELEMENT_TYPE_VALUETYPE: case ELEMENT_TYPE_CLASS: case ELEMENT_TYPE_CMOD_REQD: case ELEMENT_TYPE_CMOD_OPT: // count the bytes for the token compression CHECK_REMAINDER; cbTotal += CorSigUncompressToken(&pbSig[cbTotal], &tk); if ( ulElementType == ELEMENT_TYPE_CMOD_REQD || ulElementType == ELEMENT_TYPE_CMOD_OPT) { // skip over base type CHECK_REMAINDER; cb = cbTotalMax - cbTotal; IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) ); cbTotal += cb; } break; default: break; } *pcbTotal = cbTotal; ErrExit: return hr; }
//***************************************************************************** // walk one type and mark tokens embedded in the signature //***************************************************************************** HRESULT FilterManager::MarkFieldSignature( PCCOR_SIGNATURE pbSig, // [IN] point to the current byte to visit in the signature ULONG cbSig, // [IN] count of bytes available. ULONG *pcbUsed) // [OUT] count of bytes consumed. { HRESULT hr = NOERROR; // A result. ULONG cb; // Bytes in one signature element. ULONG cbUsed = 0; // Total bytes consumed from signature. CorElementType ulElementType; // ELEMENT_TYPE_xxx from signature. ULONG ulData; // Some data (like a count) from the signature. ULONG ulTemp; // Unused data. mdToken token; // A token from the signature. int iData; // Integer data from signature. VALIDATE_SIGNATURE_LEN( CorSigUncompressElementType(pbSig, &ulElementType) ); // Skip the modifiers... while (CorIsModifierElementType((CorElementType) ulElementType)) { VALIDATE_SIGNATURE_LEN( CorSigUncompressElementType(pbSig, &ulElementType) ); } // Examine the signature element switch (ulElementType) { case ELEMENT_TYPE_SZARRAY: // syntax: SZARRAY <BaseType> // conver the base type for the SZARRAY or GENERICARRAY VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); break; case ELEMENT_TYPE_CMOD_REQD: case ELEMENT_TYPE_CMOD_OPT: // syntax: {CMOD_REQD|CMOD_OPT} <token> <signature> // now get the embedded token VALIDATE_SIGNATURE_LEN( CorSigUncompressToken(pbSig, &token) ); // Mark the token IfFailGo( Mark(token) ); // mark the base type VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); break; case ELEMENT_TYPE_VAR: case ELEMENT_TYPE_MVAR: // syntax: VAR <index> VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); break; case ELEMENT_TYPE_ARRAY: // syntax: ARRAY BaseType <rank> [i size_1... size_i] [j lowerbound_1 ... lowerbound_j] VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); // Parse for the rank VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); // if rank == 0, we are done if (ulData == 0) break; // Any size of dimension specified? VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); // Consume sizes of dimension. while (ulData--) { VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulTemp) ); } // Any lower bounds specified? VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); // Consume lower bounds. while (ulData--) { VALIDATE_SIGNATURE_LEN( CorSigUncompressSignedInt(pbSig, &iData) ); } break; case ELEMENT_TYPE_FNPTR: // function pointer is followed by another complete signature VALIDATE_SIGNATURE_LEN_HR( MarkSignature(pbSig, cbSig - cbUsed, &cb) ); break; case ELEMENT_TYPE_VALUETYPE: case ELEMENT_TYPE_CLASS: // syntax: {CLASS | VALUECLASS} <token> VALIDATE_SIGNATURE_LEN( CorSigUncompressToken(pbSig, &token) ); // Mark it. IfFailGo( Mark(token) ); break; case ELEMENT_TYPE_GENERICINST: // syntax: ELEMENT_TYPE_GEENRICINST <ELEMENT_TYPE_CLASS | ELEMENT_TYPE_VALUECLASS> <token> <n> <n params> VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); // Get the number of generic parameters VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); // Get the generic parameters while (ulData--) { VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); } break; default: // If valid element (I4, etc), great. Otherwise, return error. if ((ulElementType >= ELEMENT_TYPE_MAX) || (ulElementType == ELEMENT_TYPE_PTR) || (ulElementType == ELEMENT_TYPE_BYREF) || (ulElementType == ELEMENT_TYPE_VALUEARRAY_UNSUPPORTED)) { IfFailGo(META_E_BAD_SIGNATURE); } break; } ErrExit: *pcbUsed = cbUsed; return hr; } // HRESULT FilterManager::MarkFieldSignature()