Skip to content

Commit

Permalink
Apply IPAddress fixes from ESP8266
Browse files Browse the repository at this point in the history
  • Loading branch information
s-hadinger committed Nov 1, 2023
1 parent 5e62273 commit 17dc50c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 26 deletions.
39 changes: 18 additions & 21 deletions cores/esp32/IPAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ IPAddress::IPAddress(const IPAddress& from)
}

IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) {
setV4();
(*this)[0] = first_octet;
(*this)[1] = second_octet;
(*this)[2] = third_octet;
(*this)[3] = fourth_octet;
uint8_t addr[] {
first_octet,
second_octet,
third_octet,
fourth_octet,
};
*this = &addr[0];

This comment has been minimized.

Copy link
@TD-er

TD-er Nov 1, 2023

@s-hadinger
In a constructor you should not call member functions, especially not when the class uses inheritance.
Also this is causing quite a chain of calls as you're using operator=(const uint8_t*), which calls the constructor with uint32_t as argument and that one uses v4() = ...
However this is extremely tricky as we're in the constructor and thus it sounds like undefined behavior to me.
Calling setV4() is already pushing it a bit, but using functions like v4() which actis on references of members which may not yet be constructed is really tricky.

}

IPAddress::IPAddress(uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16) {
Expand Down Expand Up @@ -86,19 +88,6 @@ IPAddress::IPAddress(IPType type, const uint8_t *address, uint8_t zone) {

}

void IPAddress::ctor32(uint32_t address) {
setV4();
v4() = address;
}

IPAddress::IPAddress(const uint8_t *address) {
setV4();
(*this)[0] = address[0];
(*this)[1] = address[1];
(*this)[2] = address[2];
(*this)[3] = address[3];
}

bool IPAddress::fromString(const char *address) {
if (!fromString4(address)) {
#if LWIP_IPV6
Expand Down Expand Up @@ -154,8 +143,9 @@ bool IPAddress::fromString4(const char *address) {
}

IPAddress& IPAddress::operator=(const uint8_t *address) {
setV4();
v4() = *reinterpret_cast<const uint32_t*>(address);
uint32_t value;
memcpy_P(&value, address, sizeof(value));
*this = value;
return *this;
}

Expand All @@ -166,7 +156,14 @@ IPAddress& IPAddress::operator=(uint32_t address) {
}

bool IPAddress::operator==(const uint8_t* addr) const {
return isV4() && v4() == *reinterpret_cast<const uint32_t*>(addr);
if (!isV4()) {
return false;
}

uint32_t value;
memcpy_P(&value, addr, sizeof(value));

return v4() == value;
}

size_t IPAddress::printTo(Print& p) const {
Expand Down
17 changes: 12 additions & 5 deletions cores/esp32/IPAddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ class IPAddress: public Printable
IPAddress(const IPAddress& from);
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16);
IPAddress(uint32_t address) { ctor32(address); }
IPAddress(const uint8_t *address); // v4 only
IPAddress(uint32_t address) { *this = address; }
IPAddress(unsigned long address) { *this = address; }
IPAddress(int address) { *this = address; }
IPAddress(const uint8_t *address) { *this = address; }
IPAddress(IPType type, const uint8_t *address);
IPAddress(IPType type, const uint8_t *address, uint8_t zone);

Expand All @@ -68,7 +70,7 @@ class IPAddress: public Printable
operator uint32_t() { return isV4()? v4(): (uint32_t)0; }

// generic IPv4 wrapper to uint32-view like arduino loves to see it
const uint32_t& v4() const { return ip_2_ip4(&_ip)->addr; } // for raw_address(const)
const uint32_t& v4() const { return ip_2_ip4(&_ip)->addr; }
uint32_t& v4() { return ip_2_ip4(&_ip)->addr; }

bool operator==(const IPAddress& addr) const {
Expand Down Expand Up @@ -97,11 +99,16 @@ class IPAddress: public Printable

// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const {
return isV4()? *(raw_address() + index): 0;
if (!isV4()) {
return 0;
}

return ip4_addr_get_byte_val(*ip_2_ip4(&_ip), index);
}
uint8_t& operator[](int index) {
setV4();
return *(raw_address() + index);
uint8_t* ptr = reinterpret_cast<uint8_t*>(&v4());
return *(ptr + index);
}

// Overloaded copy operators to allow initialisation of IPAddress objects from other types
Expand Down

0 comments on commit 17dc50c

Please sign in to comment.