8312 Commits
Author SHA1 Message Date
Mykhailo Shevchuk d9a9ccd136 upd changelog [ci skip] 2026-07-28 14:52:14 +03:00
Mykhailo ShevchukandGitHub bd5e6c6dba [NFC] Fix Type 4 Tag listener crashes on malformed NDEF write APDUs (#1051)
* [NFC] Fix Type 4 Tag listener crashes on malformed NDEF write APDUs

While emulating a Type 4 Tag, type_4_tag_listener_iso_write() trusted the
reader-supplied Lc and NLEN, so four malformed UPDATE BINARY APDUs reached a
furi_check instead of an error status word:

  00 D6 00 00           lc = 0 / data = NULL -> deref in bit_lib_bytes_to_num_be
  00 D6 00 00 00        same, via the Le-only body
  00 D6 00 00 01 AA     lc -= write_len underflows size_t -> ~4 GB allocation
  00 D6 00 00 02 FF FF  NLEN never clamped -> ~128 KB transient allocation

Reject an APDU with no data field, clamp the NLEN bytes consumed to what the
reader actually sent, and bound the new length by ndef_max_len before it sizes
the array. The partial-NLEN write now merges into the current length the way
the read path already does, instead of zeroing the byte it did not cover.

Behaviour for a spec-compliant write (offset 0, Lc >= 2) is unchanged.

Closes #1050

* [NFC] Fix wrong parent protocol in Type 4 Tag listener assert

Copy-pasted from the SLIX listener: the Type 4 Tag listener sits on
ISO14443-4a, not ISO15693-3, so any debug build crashed as soon as Type 4 Tag
emulation received a frame. Release builds are unaffected (furi_assert is
compiled out).

* upd changelog
2026-07-28 14:50:26 +03:00
Endika IglesiasandGitHub 86a315965f [NFC] Fix Type 4 Tag writes that start inside the NLEN field (#1049) 2026-07-28 14:17:27 +03:00
f11ebf4b9c Added examples for GPS service, Network service, canvas_get_buffer example (#1047)
* RPC GPS: add stream example, one-shot example

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* RPC network: add examples

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* GUI: add example_canvas_buffer with pixel-collision demo

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:48:22 +03:00
MX c8d8a4cc6a upd changelog 2026-07-28 13:17:47 +03:00
MX 57034eaf47 Fix pecinin keeloq manufacturer
by lifegame1lu111

https://github.com/lifegame1lu111/Momentum-Firmware/commit/47e445cea0ad3b6b3dfdd5a8a1ed20c0c4b758c8
2026-07-28 13:15:33 +03:00
MX bd8d60dd41 subghz raw files corruption fix
by Lechnio

https://github.com/Lechnio/Momentum-Firmware/commit/faa4084f8934eb96c5282e5e410d90a55726ac0e
2026-07-28 13:01:25 +03:00
MX dc144f8554 upd changelog 2026-07-27 23:58:26 +03:00
MX b19b4f6cd6 Merge OFW PR 4383: NFC FeliCa: Add Standard card emulation sup [ci skip]
https://github.com/flipperdevices/flipperzero-firmware/pull/4383/changes
2026-07-27 23:19:24 +03:00
MX 65d4ddabd8 Merge remote-tracking branch 'OFW/dev' into dev 2026-07-27 23:15:43 +03:00
Cole MunzandGitHub 8713d1c47c bit_lib: don't read past the buffer when the bits fit one byte (#4424)
bit_lib_get_bits reads data[position/8 + 1] whenever position isn't
byte-aligned, even when all the requested bits live in the current byte.
When position/8 is the last byte of the buffer that's a one-byte
over-read. The extra byte only contributes bits that get shifted back
out, so the return value is unchanged and optimized builds often drop
the load, but at -O0 AddressSanitizer flags it and the access is still
out of bounds.

Skip the next-byte read when shift + length <= 8. This is the same fix
that already landed in fbtng-corelibs; lib/bit_lib here is an independent
copy that never picked it up, so the TODO FL-3534 comment is still here.

Signed-off-by: Cole Munz <colemunz@gmail.com>
2026-07-27 20:49:10 +03:00
Cole MunzandGitHub 376dc488f5 js_event_loop: reject a non-positive timer interval (#4425)
eventLoop.timer(mode, interval) passes interval straight into
furi_ms_to_ticks() with no validation. For a periodic timer an interval
of 0 divides by zero in furi_event_loop_process_expired_timers()
(elapsed_time / timer->interval) and is counted as expired on every
event-loop pass, so a one-line script - eventLoop.timer("periodic", 0) -
pins the thread running the loop.

Reject interval <= 0 at the binding with a normal script-level error,
matching how the other js_app modules report bad arguments. The <= 0
check also covers negative values that would otherwise wrap to a huge
interval when cast to uint32_t.

Signed-off-by: Cole Munz <colemunz@gmail.com>
2026-07-27 20:36:49 +03:00
Cole MunzandGitHub 9c173b4651 LFRFID: fix the Pyramid trailing Wiegand parity bit (#4426)
protocol_pyramid_add_wiegand_parity() computes the trailing odd-parity
bit with protocol_pyramid_get_parity(source + length / 2, ...). length is
a bit count (24), so source + length / 2 moves the pointer 12 bytes,
but wiegand[] in protocol_pyramid_encode() is 3 bytes. It should read
bits 12..23 of the same buffer.

So the parity bit we transmit comes from stack memory past wiegand[]
instead of the card number. Checked every 8-bit FC against every 16-bit
card number: the bit is wrong for essentially half of them, which a
reader that validates 26-bit Wiegand parity rejects. Our own decoder only
checks the CRC-8 and the format length, so reading a written card back
with a Flipper doesn't show it.

Give get_parity an explicit start position instead of doing pointer
arithmetic with a bit count. The even-parity call keeps reading bits
0..11 and is unchanged.

Signed-off-by: Cole Munz <colemunz@gmail.com>
2026-07-27 20:19:53 +03:00
Cole MunzandGitHub 9d1bd9e4f2 LFRFID: NUL-terminate the PAC/Stanley card id before parsing it (#4427)
protocol_pac_stanley_decode() fills an 8-byte asciiCardId[] and hands it
to hex_chars_to_uint8(), which takes no length and loops
while(*value_str && value_str[1]) - it stops at a terminator the buffer
doesn't have. So every successful decode reads asciiCardId[8] and [9] off
the end of the array, and if those two stack bytes happen to be hex
digits it also writes past protocol->data, which is 4 bytes.

Made the buffer 9 bytes and zeroed it. The loop still fills [0..7] and
the parse now stops after exactly 4 bytes, which is what
PAC_STANLEY_DECODED_DATA_SIZE expects.

Signed-off-by: Cole Munz <colemunz@gmail.com>
2026-07-27 19:58:24 +03:00
Cole MunzandGitHub c9c77f66de NFC FeliCa: check the poller error before reading the system-code response (#4428)
felica_poller_state_handler_list_system reads response_system_code->system_count
before checking whether felica_poller_list_system_code actually succeeded. That
function only writes the response pointer on success - on a timeout, a bad CRC,
or a response shorter than 13 bytes it returns an error and leaves the pointer
untouched. Since it's an uninitialized stack variable, every error path here
dereferences garbage.

This is the default path for Standard FeliCa cards, since auth is skipped by
default, so a weak read, a card pulled away mid-read, or an emulator that
doesn't answer Request System Code crashes the reader. That's the crash in
#4314.

Move the response handling inside the success branch, matching every other
handler in this file.

Signed-off-by: Cole Munz <colemunz@gmail.com>
2026-07-27 19:26:56 +03:00
Cole MunzandGitHub 5dc7187085 Infrared: initialize timings_cnt on decoder alloc and fix its bounds check (#4429)
infrared_common_decoder_alloc() sets protocol and level but leaves
timings_cnt uninitialized. Every caller allocs then resets, and for RC5
(the one protocol with preamble_mark == 0) the reset path reads
timings_cnt and feeds it to consume_samples() as a length before the
reset function zeroes it a few lines later. With a nonzero garbage value
that shifts the 6-element timings[] array out of bounds, both read and
write.

Separately, the bounds check in infrared_common_decode() compares
timings_cnt (an element count) against sizeof(decoder->timings) (24
bytes for six uint32_t), so it doesn't fire until 24 instead of 6.
Should be COUNT_OF.

Both come down to timings_cnt not being trustworthy; init it at alloc and
use the element count in the check.

Signed-off-by: Cole Munz <colemunz@gmail.com>
2026-07-27 17:59:05 +03:00
a56750ffe7 Fix deprecated CodeQL action and harden the PR report commenter (#1046)
CodeQL runs are still reporting green, but every run carries a
failure-level annotation: "CodeQL Action major versions v1 and v2 have
been deprecated." It is running on a compatibility shim. Move all four
pins to v4, and bump checkout from v3 to v6 to match the rest of the
repo and clear the Node 20 deprecation warning. Drop
setup-python-dependencies, which the run log confirms has had no effect
since CodeQL 2.16. Add a concurrency group so back-to-back pushes to dev
no longer run several full firmware builds plus analyses at once.

pr-comment.yml trusted pr_number.txt from the report artifact and
validated it only as an integer. That artifact is written by a job that
checks out and runs the PR's own code, so both the comment body and its
destination were attacker-controlled: a malicious fork PR could make the
privileged commenter post arbitrary markdown onto any open thread in the
repo. Check the named PR's head SHA against the triggering run's
head_sha, which comes from the event payload and cannot be forged, and
refuse to comment on a mismatch.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 13:28:47 +03:00
MX 589ce3a7ca upd changelog 2026-07-25 12:37:40 +03:00
MX b54672f313 oops merge artifact [ci skip] 2026-07-25 04:42:40 +03:00
MX be05e0cdef make new nightstand clock our default menu clock [ci skip] 2026-07-25 04:12:11 +03:00
MX 7fd3dbe9ea Merge remote-tracking branch 'OFW/dev' into dev [ci skip] 2026-07-25 02:32:47 +03:00
MMXandGitHub 38b725c92c Docs: Fixed missing line in view_dispatcher_check_id (#4423) 2026-07-25 00:56:18 +03:00
MX d4394d9ac8 Merge remote-tracking branch 'OFW/dev' into dev 2026-07-25 00:15:14 +03:00
3094fc58d3 Allow for checking if an id is in use before adding to view dispatcher (#4422)
* Include documentation about caller thread context for GUI methods

* Add method for checking if view dispatcher id is already in use

* bump api

---------

Co-authored-by: Lofty Inclination <loftyinclination@outlook.com>
Co-authored-by: Stefan <66339601+turbospok@users.noreply.github.com>
2026-07-24 23:34:01 +03:00
MX 9c88d8ee68 Merge remote-tracking branch 'OFW/dev' into dev [ci skip] 2026-07-24 16:58:52 +03:00
8fcf13cc87 Add method for changing variable item label (#4421)
* Add method for changing variable item label

* sync name, fix api bump, sync f18 api

---------

Co-authored-by: Stefan <66339601+turbospok@users.noreply.github.com>
2026-07-24 16:41:36 +03:00
MX 88f5d5cc2d Merge remote-tracking branch 'OFW/dev' into dev 2026-07-23 19:32:28 +03:00
SegerEndandGitHub 2fe5605034 NFC: fix iso15693 emulation dropping Read Multiple Blocks for tags >64 blocks (#4420) 2026-07-23 19:30:41 +03:00
6566109b63 [SubGHz] Fix Frequency Analyzer leaving the radio in a degraded state after exit (#1045)
* fix(subghz): park radio in boot state on Frequency Analyzer exit

The FA worker configures the internal CC1101 with a near-field AGC
profile (MDMCFG3/4, AGCCTRL0-2) and isolates the RF path, but exited
with only idle+sleep. SPWD retains configuration registers and the RF
switch lines keep their last state, so the radio parked with the
antenna disconnected and skewed AGC. Apps driving the radio HAL
directly (no reset / plain set_frequency) inherited a sticky
sensitivity loss until a full re-init; the built-in app and
subghz_devices-API apps rebuild state and were unaffected.

Reset the chip and re-park the RF switch on exit, matching the state
furi_hal_subghz_init establishes at boot. The explicit set_path is
needed because SRES reverts IOCFG2 to CHIP_RDYn, which deasserts in
sleep and would leave the switch half-selected on the 433 path.

Fixes #1044

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: add changelog entry for Frequency Analyzer radio-state fix

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 19:28:39 +03:00
D.T.andGitHub 7a5f7108a2 fix(subghz): write intermediate frequency to FSCTRL1 (#1040) 2026-07-23 18:29:01 +03:00
MX 2deb1cfc72 bump apps again 2026-07-23 04:29:39 +03:00
MX 2cc26f1ee9 bump apps tag 2026-07-23 00:38:46 +03:00
MX 75fe3566ef bump again 2026-07-22 02:48:49 +03:00
MX ccd07eb4c9 bump apps tag 2026-07-22 02:34:25 +03:00
Mykhailo ShevchukandClaude Opus 4.8 bd775e297d Revert "disable bot completely due to endless email spam" [ci skip]
This reverts commit d71868364f.

The stale closed-thread backlog was locked silently beforehand, so the
restored daily lock-threads bot only comments on newly-idle threads
instead of re-flooding old ones.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 23:13:04 +03:00
e343383472 [NFC] Gate transit parser partial-read on the needed sector (#1043)
* [NFC] Gate transit parser partial-read on the needed sector (#1042)

The transit parsers (plantain, troika, two_cities, sevppk_tk, szppk_so)
accepted any partial read as success. A parser read-success is terminal in
the read flow, so this skipped the dictionary/nested key-recovery tail even
when the parser's own data sector was never read.

Accept a partial read only when the sector parse() key-checks was actually
read (mf_classic_is_sector_read); otherwise report "not handled" so the app
runs the nested/dict-attack tail and re-parses.

Preserves the Plus 2K SL1 fix from #1038 (the needed low sectors are read on
those cards, so they stay accepted) and keeps genuine SL1/SL3 mixed-mode
cards on the parser path (their higher SL3 sectors are unrecoverable by
Crypto1 nested anyway).

Closes #1042

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(changelog): add PR #1043 to the transit parser fix entry

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 14:19:12 +03:00
3dcdb353f2 [NFC] Fix MIFARE Plus 2K SL1 transit parsers (#1037) (#1038)
* [NFC] Fix MIFARE Plus 2K SL1 transit parsers after MfClassicType2k

After #1016 promoted genuine MIFARE Plus S/X 2K cards in SL1 (SAK 0x08 +
Plus ATS) from MfClassicType1k to the new MfClassicType2k, the supported-
card parsers for those cards stopped working:

- Type gates (get_card_config / extract_purse_data) knew only 1K/4K, so
  parse() rejected 2K -- plantain, troika.
- mf_classic_is_card_read() now needs all 32 sectors / 64 keys for a 2K
  card, so a targeted read() that keys only its own sectors returns
  MfClassicErrorPartialRead -> is_read = false -> the app diverts to the
  dict-attack scene and never reaches parse() -- sevppk, szppk_so,
  two_cities (and the above).

Handle MfClassicType2k explicitly as the Classic 1K these cards present
(same lower-sector keys / data sector), and accept a partial read in the
plugins' read() so parse() runs and validates the key.

social_moscow / kazan (plain Classic) and sk_tk (4K) are not promoted to
2K and are left unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(changelog): note Plus 2K SL1 transit parser fix (PR #1038)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 22:28:18 +03:00
MX 3b160a5e0e bump apps tag 2026-07-15 05:47:36 +03:00
MX f629d2cb98 bump apps tag 2026-07-13 15:08:22 +03:00
MX d71868364f disable bot completely due to endless email spam [ci skip]
todo: disable comments for old PRs and issues, keep them only for new ones
2026-07-13 13:36:45 +03:00
MX 9bcabc0134 bump apps tag and sync api 2026-07-11 16:00:44 +03:00
MX 17ad4461a4 Merge remote-tracking branch 'OFW/dev' into dev [ci skip] 2026-07-09 13:19:29 +03:00
7432d21a7e CCID: move USB layer from firmware HAL into ccid_test app (#4407)
* CCID: move USB layer from firmware HAL into ccid_test app

The CCID USB device interface no longer needs to live in the firmware.
A FAP can define its own FuriHalUsbInterface and drive the libusb_stm32
device stack directly: the usbd_* helpers are inline static in
usbd_core.h and dispatch through the dev->driver vtable, and those
headers already ship in the app SDK, so no new symbols must be exported.

- Move furi_hal_usb_ccid.{c,h} into applications/debug/ccid_test as
  ccid_usb.{c,h} (interface renamed usb_ccid -> ccid_usb_interface,
  furi_hal_usb_ccid_* -> ccid_usb_*). String-descriptor indices are
  hardcoded since furi_hal_usb_i.h is not part of the SDK.
- Delete the firmware CCID module and its extern/include hooks.
- Drop the 4 CCID entries from f7 + f18 api_symbols.csv (keeping the
  libusb usb_ccid.h header), bump API 87.3 -> 88.0 (breaking).

Frees ~1.7 KB of base-firmware flash; CCID code now only costs space
in the FAP while the app runs. Verified on hardware: enumerates as a
CCID reader (076b:3a21, class 0x0b) and passes the app's APDU tests.

* apply fbt format

---------

Co-authored-by: Štefan Croitoru <66339601+turbospok@users.noreply.github.com>
2026-07-09 13:16:57 +03:00
MX 48b6484ce2 bump apps tag 2026-07-09 10:51:43 +03:00
Mykhailo ShevchukandClaude Opus 4.8 568c456f52 [CI] Add lock-threads workflow (lock closed issues/PRs after 14d idle) [ci skip]
Daily dessant/lock-threads@v6 sweep + manual dispatch. Locks only closed
threads that have been inactive for 14 days; never closes anything and open
threads are untouched. Leaves a comment pointing users to open a fresh issue.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 18:50:30 +03:00
Elly RomanovaandGitHub d1019d3bb3 Fix User Documentation link in index.dox (#4410)
Updated the link to the User Documentation by removing the trailing slash, which was pointing to an incorrectly rendered page
2026-07-08 13:48:01 +03:00
Mykhailo ShevchukandClaude Opus 4.8 71280128a3 Apply clang-format to recently merged NFC/RPC/CCID files [ci skip]
Run `fbt format` over the tree; normalizes whitespace, comment
spacing and argument wrapping in the bambu parser, Network/GPS RPC
services and ccid_test USB layer. No functional change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 00:05:57 +03:00
MX 473476300a bump apps tag 2026-07-07 23:35:53 +03:00
fd2ec5878d [SubGHz] Fix crash when exiting CLI subghz chat with external CC1101 (#1036)
* [SubGHz] Fix crash when exiting CLI `subghz chat` with external CC1101

Pressing Ctrl+C to exit `subghz chat` while using an external CC1101
crashed the Flipper (null-pointer dereference + reboot).

The exit path called subghz_devices_deinit() before stopping the chat
worker. deinit unloads the external CC1101 radio-device plugin, freeing
its SubGhzDevice struct and interconnect vtable; the TxRx worker thread
sleeps/ends that device from its own thread on shutdown, so joining it
after deinit dereferenced freed plugin memory. The internal CC1101 is a
static device that deinit never frees, which is why the crash was
external-only.

Stop and free the worker before subghz_devices_deinit(), matching the
teardown order already used by subghz_cli_command_rx. Also add the
missing deinit + radio power-off to the "tx not allowed" early return so
a subsequent subghz command's subghz_devices_init() does not
furi_check-fail on an already-valid registry.

Fixes #829

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* changelog: SubGHz crash exiting CLI chat with external CC1101 (PR #1036, Fixes #829)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 23:09:05 +03:00
e4e8a8ef2b [NFC] Trim MIFARE Plus generator & admin-key mapping (in-place cleanup) (#1035)
* [NFC] Data-drive MIFARE Plus manual-add generators

Replace the 18 near-identical MIFARE Plus generator thunks and their
handler-table entries with a data-driven mf_plus_generator_configs[]
table (uid_len / type / size / ATS per variant), dispatched via a small
range predicate. The Ultralight/NTAG and Classic types keep their
bespoke handlers, so the handler table now stops before the MF Plus
range.

Also drop mf_plus_ats_hist_ev, which was byte-identical to
mf_plus_ats_hist_s (EV1/EV2 are identified by GetVersion, not the ATS).

Pure refactor: the Add-Manually menu entries, the generated cards and the
public SDK API are all unchanged. Trims firmware flash by removing the
per-variant functions and the duplicate blob; a _Static_assert pins the
config table to the enum range so a future type can't desync it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* [NFC] MIFARE Plus: single source for admin-key addresses

Fold the three copies of the admin-key address<->type mapping
(0x9000 CardMaster, 0x9001 CardConfig, 0x9003 L3Switch, 0x9004
SL1CardAuth) into one mf_plus_admin_key_addresses[] table with a forward
helper (mf_plus_get_admin_key_address, replaces the poller's local id
array) and a reverse helper (mf_plus_admin_key_type_from_address,
replaces two identical switch statements in the listener's key-resolve
and write-store paths).

Behavior-preserving: both listener default fall-throughs are kept (resolve
returns false; store falls through to data/config block handling), the
poller authenticates the same addresses, and a _Static_assert pins the
table to MfPlusAdminKeyNum. Internal helpers only; no SDK API change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* [NFC] Changelog: MIFARE Plus generator/admin-map cleanup

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 23:08:54 +03:00