Page 1 of 1
PeekB Error with PB 6.10
Posted: Fri May 17, 2024 10:18 am
by tatanas
Hi,
I just updated from PB 6.04 to 6.10 and I've got some problems. Try this code, an invalid memory access should popup.
It was fine in 6.04. What's changed ?
Code: Select all
Procedure.s GetIPAddress(HostName.s = "")
Protected TheIPAddress.s, pHostinfo, AdressNumber, ipAddress.l, Url.s
Protected hostinfo.HOSTENT, *Url
URL = GetURLPart(HostName, #PB_URL_Site)
If Url = ""
Url = HostName
EndIf
*Url = Ascii(Url)
If *Url
pHostinfo = gethostbyname_(*Url)
If pHostinfo = 0
TheIPAddress = "Unable to resolve domain name"
Else
CopyMemory(pHostinfo, hostinfo.HOSTENT, SizeOf(HOSTENT))
If hostinfo\h_addrtype <> #AF_INET
TheIPAddress = "A non-IP address was returned."
Else
While PeekL(hostinfo\h_addr_list + AdressNumber * 4)
ipAddress = PeekL(hostinfo\h_addr_list + AdressNumber * 4)
octet1 = PeekB(ipAddress)
octet2 = PeekB(ipAddress + 1)
octet3 = PeekB(ipAddress + 2)
octet4 = PeekB(ipAddress + 3)
TheIPAddress = StrU(octet1, #PB_Byte) + "." +
StrU(octet2, #PB_Byte) + "." +
StrU(octet3, #PB_Byte) + "." +
StrU(octet4, #PB_Byte)
AdressNumber + 1
Wend
EndIf
EndIf
FreeMemory(*Url)
EndIf
ProcedureReturn TheIPAddress
EndProcedure
GetIPAddress("PC_name")
Thanks for your time.
Re: PeekB Error with PB 6.10
Posted: Fri May 17, 2024 10:30 am
by STARGÅTE
Why do you post in "Bug Reports" if you have a code question?
This part is wrong:
Code: Select all
ipAddress = PeekL(hostinfo\h_addr_list + AdressNumber * 4)
octet1 = PeekB(ipAddress)
PeekB() reads from a memory address, and the memory address must be an Integer (.i) not a Long.
If ipAddress is the IP address itself, you don't need PeekB(), then you have to use bit masks like ipAddress & $FF, ipAddress>>8 & $FF to go through all fields.
Edit: This was also wrong in older PB versions.
Re: PeekB Error with PB 6.10
Posted: Fri May 17, 2024 11:11 am
by infratec
I agree: it is a coding question.
A modified version:
Code: Select all
EnableExplicit
Procedure.s GetIPAddress(HostName.s = "")
Protected.a octet1, octet2, octet3, octet4
Protected.i AdressNumber
Protected TheIPAddress.s, Url.s
Protected *Hostinfo, *Url, *ipAddress
Protected hostinfo.HOSTENT
Url = GetURLPart(HostName, #PB_URL_Site)
If Url = ""
Url = HostName
EndIf
*Url = Ascii(Url)
If *Url
*Hostinfo = gethostbyname_(*Url)
If *Hostinfo = #Null
TheIPAddress = "Unable to resolve domain name"
Else
CopyMemory(*Hostinfo, @hostinfo, SizeOf(HOSTENT))
If hostinfo\h_addrtype <> #AF_INET
TheIPAddress = "A non-IP address was returned."
Else
While PeekI(hostinfo\h_addr_list + AdressNumber * SizeOf(Integer))
*ipAddress = PeekI(hostinfo\h_addr_list + AdressNumber * SizeOf(Integer))
octet1 = PeekA(*ipAddress)
octet2 = PeekA(*ipAddress + 1)
octet3 = PeekA(*ipAddress + 2)
octet4 = PeekA(*ipAddress + 3)
TheIPAddress = Str(octet1) + "." + Str(octet2) + "." + Str(octet3) + "." + Str(octet4)
AdressNumber + 1
Wend
EndIf
EndIf
FreeMemory(*Url)
EndIf
ProcedureReturn TheIPAddress
EndProcedure
Debug GetIPAddress("mit.edu")
Works with x86 and x64
Re: PeekB Error with PB 6.10
Posted: Fri May 17, 2024 11:20 am
by tatanas
Thank you both of you. I thought it could be a bug because It started to crash right after the update to 6.10.
Re: PeekB Error with PB 6.10
Posted: Fri May 17, 2024 11:23 am
by mk-soft
There are already so many examples of this. Here is one for ALL-OS
Code: Select all
;-TOP
CompilerIf #PB_Compiler_64Bit
Structure HOSTENT_FIX
*h_name
*h_aliases
h_addrtype.w
PB_Alignment.b[2]
h_length.w
PB_Alignment2.b[2]
*h_addr_list.integer[0]
EndStructure
CompilerElse
Structure HOSTENT_FIX
*h_name
*h_aliases
h_addrtype.w
h_length.w
*h_addr_list.integer[0]
EndStructure
CompilerEndIf
;-- Contants
#AF_UNSPEC = 0
#AF_INET = 2
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
#AF_INET6 = 23
CompilerCase #PB_OS_Linux
#AF_INET6 = 10
CompilerCase #PB_OS_MacOS
#AF_INET6 = 30
CompilerEndSelect
#PF_UNSPEC = #AF_UNSPEC
#PF_INET = #AF_INET
#PF_INET6 = #AF_INET6
#AI_CANONNAME = 2
#SOCK_STREAM = 1
;-- Structures
CompilerIf Not Defined(in_addr, #PB_Structure)
Structure in_addr Align #PB_Structure_AlignC
StructureUnion
s_b.a[4]
s_w.u[2]
s_addr.l
EndStructureUnion
EndStructure
CompilerEndIf
CompilerIf Not Defined(in6_addr, #PB_Structure)
Structure in6_addr Align #PB_Structure_AlignC
s6_addr.a[16]
EndStructure
CompilerEndIf
CompilerIf Not Defined(SOCKADDR, #PB_Structure)
Structure SOCKADDR Align #PB_Structure_AlignC
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
sa_len.a
sa_family.a
CompilerElse
sa_family.u
CompilerEndIf
sa_data.a[14]
EndStructure
CompilerEndIf
CompilerIf Not Defined(SOCKADDR_IN4, #PB_Structure)
Structure SOCKADDR_IN4 Align #PB_Structure_AlignC
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
sin_len.a
sin_family.a
CompilerElse
sin_family.u
CompilerEndIf
sin_port.u
sin_addr.in_addr
sin_zero.a[8]
EndStructure
CompilerEndIf
CompilerIf Not Defined(SOCKADDR_IN6, #PB_Structure)
Structure SOCKADDR_IN6 Align #PB_Structure_AlignC
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
sin6_len.a
sin6_family.a
CompilerElse
sin6_family.u
CompilerEndIf
sin6_port.u
sin6_flowinfo.l
sin6_addr.in6_addr
sin6_scope_id.l
EndStructure
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Structure addrinfo Align #PB_Structure_AlignC
ai_flags.l
ai_family.l
ai_socktype.l
ai_protocol.l
ai_addrlen.l
StructureUnion
*ai_addr.SOCKADDR
*ai_addr_in.SOCKADDR_IN4
*ai_addr_in6.SOCKADDR_IN6
EndStructureUnion
*ai_canonname
*ai_next.addrinfo
EndStructure
CompilerElse
Structure addrinfo Align #PB_Structure_AlignC
ai_flags.l
ai_family.l
ai_socktype.l
ai_protocol.l
ai_addrlen.l
*ai_canonname
StructureUnion
*ai_addr.SOCKADDR
*ai_addr_in.SOCKADDR_IN4
*ai_addr_in6.SOCKADDR_IN6
EndStructureUnion
*ai_next.addrinfo
EndStructure
CompilerEndIf
;-
Procedure GetHostByName(HostName.s)
Protected r1.l, *host_name, dwError.l, *remoteHost.HOSTENT_FIX, *h_addr.in_addr, *h_addr6.in_addr, i
*host_name = Ascii(Hostname)
*remoteHost = gethostbyname_(*host_name)
If *remoteHost
With *remoteHost
Select \h_addrtype
Case #AF_INET
If \h_addr_list[0]
*h_addr = \h_addr_list[0]\i
r1 = *h_addr\s_addr
EndIf
Default
r1 = 0
EndSelect
EndWith
Else
r1 = 0
EndIf
ProcedureReturn r1
EndProcedure
; ----
CompilerIf #PB_Compiler_IsMainFile
r1 = GetHostByName("raspberrypi5")
Debug IPString(r1)
r1 = GetHostByName("server")
Debug IPString(r1)
r1 = GetHostByName("www.purebasic.fr")
Debug IPString(r1)
CompilerEndIf
Re: PeekB Error with PB 6.10
Posted: Fri May 17, 2024 11:23 am
by STARGÅTE
tatanas wrote: Fri May 17, 2024 11:20 am
Thank you both of you. I thought it could be a bug because It starts to crash right after the update to 6.10.
Of course it was a bug. But it was a bug in the code itself, not in PureBasic

.
Re: PeekB Error with PB 6.10
Posted: Fri May 17, 2024 11:30 am
by mk-soft
This will happen to you more often now. Addresses have always been a pointer or an integer. However, many still used long for addresses, which is an error.
It used to fit into a long because of the OS limitation and the old memory management.
Not any more.