Just starting out? Need help? Post your questions and find answers here.
tatanas
Enthusiast
Posts: 260 Joined: Wed Nov 06, 2019 10:28 am
Location: France
Post
by tatanas » Fri May 17, 2024 10:18 am
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.
Windows 10 Pro x64
PureBasic 6.20 x64
STARGÅTE
Addict
Posts: 2260 Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:
Post
by STARGÅTE » Fri May 17, 2024 10:30 am
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.
infratec
Always Here
Posts: 7662 Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany
Post
by infratec » Fri May 17, 2024 11:11 am
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
tatanas
Enthusiast
Posts: 260 Joined: Wed Nov 06, 2019 10:28 am
Location: France
Post
by tatanas » Fri May 17, 2024 11:20 am
Thank you both of you. I thought it could be a bug because It started to crash right after the update to 6.10.
Last edited by
tatanas on Fri May 17, 2024 11:24 am, edited 1 time in total.
Windows 10 Pro x64
PureBasic 6.20 x64
mk-soft
Always Here
Posts: 6320 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Fri May 17, 2024 11:23 am
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
Last edited by
mk-soft on Fri May 17, 2024 2:08 pm, edited 2 times in total.
STARGÅTE
Addict
Posts: 2260 Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:
Post
by STARGÅTE » Fri May 17, 2024 11:23 am
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
.
mk-soft
Always Here
Posts: 6320 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Fri May 17, 2024 11:30 am
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.