OneShot: Fix isPressed() and isSticky()

I tried to be smart and use `sizeof()` instead of hard-coding the array size,
but I used it wrong, and we iterated to 32 instead of 16, overflowing the array
and looking at parts of the memory we had no business looking at. This resulted
in `isPressed()` and `isSticky()` always being true.

Instead of trying to be clever, use `OneShot::ONESHOT_KEY_COUNT` throughout,
which is a constexpr defined at 16, the number of oneshot keys we have.

Fixes #572.

Signed-off-by: Gergely Nagy <algernon@keyboard.io>
pull/573/head
Gergely Nagy 6 years ago
parent aecc29a313
commit 51a7537d87
No known key found for this signature in database
GPG Key ID: AC1E90BAC433F68F

@ -26,13 +26,13 @@ uint32_t OneShot::start_time_ = 0;
uint16_t OneShot::time_out = 2500; uint16_t OneShot::time_out = 2500;
uint16_t OneShot::hold_time_out = 250; uint16_t OneShot::hold_time_out = 250;
int16_t OneShot::double_tap_time_out = -1; int16_t OneShot::double_tap_time_out = -1;
OneShot::key_state_t OneShot::state_[16]; OneShot::key_state_t OneShot::state_[OneShot::ONESHOT_KEY_COUNT];
Key OneShot::prev_key_; Key OneShot::prev_key_;
bool OneShot::should_cancel_ = false; bool OneShot::should_cancel_ = false;
bool OneShot::should_cancel_stickies_ = false; bool OneShot::should_cancel_stickies_ = false;
bool OneShot::isPressed() { bool OneShot::isPressed() {
for (uint8_t i = 0; i < sizeof(state_); i++) { for (uint8_t i = 0; i < ONESHOT_KEY_COUNT; i++) {
if (state_[i].pressed) if (state_[i].pressed)
return true; return true;
} }
@ -40,7 +40,7 @@ bool OneShot::isPressed() {
} }
bool OneShot::isSticky() { bool OneShot::isSticky() {
for (uint8_t i = 0; i < sizeof(state_); i++) { for (uint8_t i = 0; i < ONESHOT_KEY_COUNT; i++) {
if (state_[i].sticky) if (state_[i].sticky)
return true; return true;
} }
@ -209,7 +209,7 @@ void OneShot::inject(Key mapped_key, uint8_t key_state) {
// --- glue code --- // --- glue code ---
bool OneShot::isActive(void) { bool OneShot::isActive(void) {
for (uint8_t i = 0; i < 16; i++) { for (uint8_t i = 0; i < ONESHOT_KEY_COUNT; i++) {
if ((state_[i].active && !hasTimedOut()) || if ((state_[i].active && !hasTimedOut()) ||
state_[i].pressed || state_[i].pressed ||
state_[i].sticky) state_[i].sticky)
@ -256,25 +256,25 @@ void OneShot::disableStickability(Key key) {
} }
void OneShot::enableStickabilityForModifiers() { void OneShot::enableStickabilityForModifiers() {
for (uint8_t i = 0; i < 8; i++) { for (uint8_t i = 0; i < ONESHOT_KEY_COUNT / 2; i++) {
state_[i].stickable = true; state_[i].stickable = true;
} }
} }
void OneShot::enableStickabilityForLayers() { void OneShot::enableStickabilityForLayers() {
for (uint8_t i = 8; i < 16; i++) { for (uint8_t i = ONESHOT_KEY_COUNT / 2; i < ONESHOT_KEY_COUNT; i++) {
state_[i].stickable = true; state_[i].stickable = true;
} }
} }
void OneShot::disableStickabilityForModifiers() { void OneShot::disableStickabilityForModifiers() {
for (uint8_t i = 0; i < 8; i++) { for (uint8_t i = 0; i < ONESHOT_KEY_COUNT / 2; i++) {
state_[i].stickable = false; state_[i].stickable = false;
} }
} }
void OneShot::disableStickabilityForLayers() { void OneShot::disableStickabilityForLayers() {
for (uint8_t i = 8; i < 16; i++) { for (uint8_t i = ONESHOT_KEY_COUNT / 2; i < ONESHOT_KEY_COUNT; i++) {
state_[i].stickable = false; state_[i].stickable = false;
} }
} }

@ -29,7 +29,7 @@ namespace plugin {
class OneShot : public kaleidoscope::Plugin { class OneShot : public kaleidoscope::Plugin {
public: public:
OneShot(void) { OneShot(void) {
for (uint8_t i = 0; i < 16; i++) { for (uint8_t i = 0; i < ONESHOT_KEY_COUNT; i++) {
state_[i].stickable = true; state_[i].stickable = true;
} }
} }
@ -79,6 +79,7 @@ class OneShot : public kaleidoscope::Plugin {
void inject(Key mapped_key, uint8_t key_state); void inject(Key mapped_key, uint8_t key_state);
private: private:
static constexpr uint8_t ONESHOT_KEY_COUNT = 16;
typedef struct { typedef struct {
bool active: 1; bool active: 1;
bool pressed: 1; bool pressed: 1;
@ -87,7 +88,7 @@ class OneShot : public kaleidoscope::Plugin {
uint8_t __reserved: 4; uint8_t __reserved: 4;
uint8_t position; uint8_t position;
} key_state_t; } key_state_t;
static key_state_t state_[16]; static key_state_t state_[ONESHOT_KEY_COUNT];
static uint32_t start_time_; static uint32_t start_time_;
static Key prev_key_; static Key prev_key_;

Loading…
Cancel
Save