Skip to content

fix: correct eight bugs found in STM32Ethernet sources - #102

Merged
fpistm merged 8 commits into
stm32duino:mainfrom
fpistm:fix
Oct 21, 2026
Merged

fpistm merged 8 commits into
stm32duino:mainfrom
fpistm:fix

Conversation

@fpistm

@fpistm fpistm commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Summary

Fixes eight bugs found during a review of the STM32Ethernet sources. Each fix is a separate commit.

  • tcp_accept_callback: initialize the accepted flag (now bool, set to false).
  • tcp_accept_callback: on mem_malloc() failure, close only the new pcb with tcp_close() instead of calling tcp_connection_close() with a NULL client.
  • _stm32_eth_scheduler: define it for all STM32 core versions, fixing the build on older cores. stm32_eth_scheduler() remains the wrapper for the newer timer path.
  • EthernetClient::operator==: handle a NULL connection without dereferencing it.
  • EthernetClient::stop(): track ownership with _owns_tcp_client to avoid a double free for clients created from a server-owned structure.
  • EthernetUDP::begin(): call stop() when igmp_joingroup() fails, so the UDP pcb is not leaked.
  • EthernetUDP::write(): keep already buffered data when stm32_new_data() fails.
  • EthernetUDP constructor: initialize all members in the initializer list.

The doc-comment cleanup, Doxygen fixes and astyle formatting are already on main, so they are not part of this PR.

Validation

  • Doxygen with the repo Doxyfile: 0 warnings.
  • astyle 3.1 (the version used by CI): no formatting issues.
  • Not compiled: no STM32 core is available in this environment. Please let CI build it.

The accepted flag is read after the accept logic but was never
set on every path, so it could hold an indeterminate value.
Changing it to a boolean type and initializing it to false.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Assisted-by: GitHub Copilot: Claude Haiku 5.5
When mem_malloc() fails for the new connection structure,
the error path called tcp_connection_close() with a NULL
client and dereferenced it. Close only the new pcb with
tcp_close(), since there is no client structure to update.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Assisted-by: GitHub Copilot: Claude Haiku 5.5
_stm32_eth_scheduler() was declared and defined only for STM32 cores
newer than 0x01060100, but scheduler_callback() calls it unconditionally,
so older cores failed to build.
Define it for all versions and keep the stm32_eth_scheduler()
wrapper for the newer timer path. Older cores get a wrapper that
calls the shared body from the polling loops.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Assisted-by: GitHub Copilot: Claude Haiku 5.5
operator== read _tcp_client->pcb without checking for NULL.
Two clients with no connection both have a NULL _tcp_client,
so comparing them crashed.
Only compare the pcb when both have one.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Assisted-by: GitHub Copilot: Claude Haiku 5.5
stop() freed _tcp_client unconditionally, but a client
created from a server-owned tcp_struct does not own it.
EthernetServer::accept() frees those slots, so the same
memory was freed twice. Track ownership with _owns_tcp_client,
set only in connect(), and free only owned connections.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Assisted-by: GitHub Copilot: Claude Haiku 5.5
begin() returned 0 after a failed igmp_joingroup() but left
the UDP pcb allocated and bound. Call stop() before returning
so the socket is not leaked.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Assisted-by: GitHub Copilot: Claude Haiku 5.5
write(buffer, size) assigned the result of stm32_new_data()
directly to _data. On allocation failure that dropped the
packet already buffered. Store the result in a temporary
and assign _data only on success.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Assisted-by: GitHub Copilot: Claude Haiku 5.5
The default constructor left the port, pbuf and UDP pcb members
uninitialized until begin() was called.
Initialize them in the member initializer list, in declaration order.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Assisted-by: GitHub Copilot: Claude Haiku 5.5
@fpistm fpistm added the fix 🩹 Bug fix label Oct 20, 2026
@fpistm
fpistm merged commit c263656 into stm32duino:main Oct 21, 2026
4 checks passed
@fpistm fpistm added this to the 1.6.0 milestone Oct 21, 2026
@github-project-automation github-project-automation Bot moved this from In progress to Done in STM32duino libraries Oct 21, 2026
@fpistm
fpistm deleted the fix branch October 21, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix 🩹 Bug fix

Projects

Development

Successfully merging this pull request may close these issues.

1 participant