mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-11-14 10:34:57 +00:00
controllers/npad: Validate device handles before use
Some games such as NEKOPARA Vol. 3 send invalid device handles when calling InitializeVibrationDevice. Introduce a check to validate the device handle before use.
This commit is contained in:
parent
69b46dd607
commit
1c773c0869
2 changed files with 45 additions and 0 deletions
|
@ -116,6 +116,31 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Controller_NPad::IsNpadIdValid(u32 npad_id) {
|
||||
switch (npad_id) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case NPAD_UNKNOWN:
|
||||
case NPAD_HANDHELD:
|
||||
return true;
|
||||
default:
|
||||
LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Controller_NPad::IsDeviceHandleValid(const DeviceHandle& device_handle) {
|
||||
return IsNpadIdValid(device_handle.npad_id) &&
|
||||
device_handle.npad_type < NpadType::MaxNpadType &&
|
||||
device_handle.device_index < DeviceIndex::MaxDeviceIndex;
|
||||
}
|
||||
|
||||
Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
|
||||
|
||||
Controller_NPad::~Controller_NPad() {
|
||||
|
@ -742,6 +767,10 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size
|
|||
|
||||
void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
|
||||
const VibrationValue& vibration_value) {
|
||||
if (!IsDeviceHandleValid(vibration_device_handle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
|
||||
return;
|
||||
}
|
||||
|
@ -798,12 +827,20 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat
|
|||
|
||||
Controller_NPad::VibrationValue Controller_NPad::GetLastVibration(
|
||||
const DeviceHandle& vibration_device_handle) const {
|
||||
if (!IsDeviceHandleValid(vibration_device_handle)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
||||
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
||||
return latest_vibration_values[npad_index][device_index];
|
||||
}
|
||||
|
||||
void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) {
|
||||
if (!IsDeviceHandleValid(vibration_device_handle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
||||
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
||||
InitializeVibrationDeviceAtIndex(npad_index, device_index);
|
||||
|
@ -824,6 +861,10 @@ void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
|
|||
}
|
||||
|
||||
bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const {
|
||||
if (!IsDeviceHandleValid(vibration_device_handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
||||
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
||||
return vibration_devices_mounted[npad_index][device_index];
|
||||
|
|
|
@ -56,12 +56,14 @@ public:
|
|||
JoyconLeft = 6,
|
||||
JoyconRight = 7,
|
||||
Pokeball = 9,
|
||||
MaxNpadType = 10,
|
||||
};
|
||||
|
||||
enum class DeviceIndex : u8 {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
None = 2,
|
||||
MaxDeviceIndex = 3,
|
||||
};
|
||||
|
||||
enum class GyroscopeZeroDriftMode : u32 {
|
||||
|
@ -213,6 +215,8 @@ public:
|
|||
static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type);
|
||||
static std::size_t NPadIdToIndex(u32 npad_id);
|
||||
static u32 IndexToNPad(std::size_t index);
|
||||
static bool IsNpadIdValid(u32 npad_id);
|
||||
static bool IsDeviceHandleValid(const DeviceHandle& device_handle);
|
||||
|
||||
private:
|
||||
struct CommonHeader {
|
||||
|
|
Loading…
Reference in a new issue