In GetPubKeyFromInput(), evaluating TxoutType::SCRIPTHASH (P2SH-P2WPKH) inputs runs EvalScript under SCRIPT_VERIFY_NONE and passes the resulting redeem script to Solver(redeem, solutions). Because Solver clears the passed solutions vector, the 20-byte script hash originally extracted from the UTXO's scriptPubKey is erased without checking that Hash160(redeem) matches it. Consequently, spending an arbitrary P2SH UTXO (such as a multisig or timelock) with a scriptSig that pushes a valid P2WPKH redeem script causes an unintended public key to be extracted and summed into A_sum, silently corrupting the Silent Payments input hash and derived shared secret.
Additionally, GetPubKeyFromInput() previously accepted malleated or non-standard witness stacks and scriptSigs by grabbing stack.back() without enforcing the BIP-16 push-only requirement (!txin.scriptSig.IsPushOnly()), the BIP-141 single-element redeem script constraint (stack.size() == 1), the standard two-element P2WPKH witness stack depth (txin.scriptWitness.stack.size() == 2), or verifying that the extracted compressed public key actually hashes to the target witness program (Hash160(key) == solutions[0]).
This change preserves the expected 20-byte script hash prior to solver invocation, enforces BIP-16 push-only and single-element constraints, verifies both redeem script and witness pubkey preimage hashes, and validates exact witness stack depths for both native P2WPKH and P2SH-P2WPKH inputs. Targeted unit test coverage in src/test/bip352_tests.cpp verifies rejection of redeem script mismatches, non-push opcodes, multi-push scriptSigs, pubkey hash mismatches, uncompressed keys, and invalid stack sizes.