This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
powerboat9's profile picture

crash any computer using gps.locate()

Started by powerboat9, 22 August 2016 - 12:59 AM
powerboat9 #1
Posted 22 August 2016 - 02:59 AM
Code

As I demonstrated earlier today on Lurcraft Relived, gps.locate only verifies that the gps hosts it receives messages from are sending tables with 3 coords (the location of the GPS host), but doesn't test to see if the coords are numbers. Sending three tables is enough to trip up an attempt to display the coords using tostring, or to trip up the latter attempt to do subtraction on a malformed vector.
Edited on 29 August 2016 - 12:09 AM
Lupus590 #2
Posted 22 August 2016 - 01:03 PM
the vector API should probably check that what it's getting is numbers too: https://github.com/a...rom/apis/vector


Untested code fixes, mainly for Dan200
Vector APIMake sure args are numbers
function new( x, y, z )
local v = {
  x = tonumber(x) or 0,
  y = tonumber(y) or 0,
  z = tonumber(z) or 0
}
setmetatable( v, vmetatable )
return v
end
GPS APIMake sure GPS host positions are not nil
function locate( _nTimeout, _bDebug )
	-- Let command computers use their magic fourth-wall-breaking special abilities
	if commands then
		return commands.getBlockPosition()
	end
-- Find a modem
local sModemSide = nil
for n,sSide in ipairs( rs.getSides() ) do
  if peripheral.getType( sSide ) == "modem" and peripheral.call( sSide, "isWireless" ) then
   sModemSide = sSide
   break
  end
end
if sModemSide == nil then
  if _bDebug then
   print( "No wireless modem attached" )
  end
  return nil
end

if _bDebug then
  print( "Finding position..." )
end

-- Open a channel
local modem = peripheral.wrap( sModemSide )
local bCloseChannel = false
if not modem.isOpen( os.getComputerID() ) then
  modem.open( os.getComputerID() )
  bCloseChannel = true
end

-- Send a ping to listening GPS hosts
modem.transmit( CHANNEL_GPS, os.getComputerID(), "PING" )

-- Wait for the responses
local tFixes = {}
local pos1, pos2 = nil, nil
sBadPositionError = "GPS replied with bad position, check your GPS hosts."
local timeout = os.startTimer( _nTimeout or 2 )
while true do
  local e, p1, p2, p3, p4, p5 = os.pullEvent()
  if e == "modem_message" then
   -- We received a reply from a modem
   local sSide, sChannel, sReplyChannel, tMessage, nDistance = p1, p2, p3, p4, p5
   if sSide == sModemSide and sChannel == os.getComputerID() and sReplyChannel == CHANNEL_GPS and nDistance then
	-- Received the correct message from the correct modem: use it to determine position
	if type(tMessage) == "table" and #tMessage == 3 then
	 local tFix = { vPosition = vector.new( assert(tMessage[1], sBadPositionError), assert(tMessage[2], sBadPositionError),assert(tMessage[3], sBadPositionError) ), nDistance = nDistance }
	 if _bDebug then
	  print( tFix.nDistance.." metres from "..tostring( tFix.vPosition ) )
	 end
	 if tFix.nDistance == 0 then
		 pos1, pos2 = tFix.vPosition, nil
	 else
						table.insert( tFixes, tFix )
						if #tFixes >= 3 then
							if not pos1 then
								pos1, pos2 = trilaterate( tFixes[1], tFixes[2], tFixes[#tFixes] )
							else
								pos1, pos2 = narrow( pos1, pos2, tFixes[#tFixes] )
							end
						end
					end
	 if pos1 and not pos2 then
	  break
	 end
	end
   end
  
  elseif e == "timer" then
   -- We received a timeout
   local timer = p1
   if timer == timeout then
	break
   end

  end
end

-- Close the channel, if we opened one
if bCloseChannel then
  modem.close( os.getComputerID() )
end

-- Return the response
if pos1 and pos2 then
  if _bDebug then
   print( "Ambiguous position" )
   print( "Could be "..pos1.x..","..pos1.y..","..pos1.z.." or "..pos2.x..","..pos2.y..","..pos2.z )
  end
  return nil
elseif pos1 then
  if _bDebug then
   print( "Position is "..pos1.x..","..pos1.y..","..pos1.z )
  end
  return pos1.x, pos1.y, pos1.z
else
  if _bDebug then
   print( "Could not determine position" )
  end
  return nil
end
end

Also, I've posted this to GitHub:https://github.com/dan200/ComputerCraft/issues/138
Edited on 22 August 2016 - 11:32 AM
powerboat9 #3
Posted 22 August 2016 - 07:20 PM
I made a resource pack to fix the bugs.
Edited on 29 August 2016 - 04:41 PM