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

Program or API for saving Variables as loadable files

Started by Lithia, 05 February 2013 - 02:18 PM
Lithia #1
Posted 05 February 2013 - 03:18 PM
Does any pro know of a program or api or would like to create a program
that saves a single lined file that can be loaded by another program for example

API would be

save.variable("passwordmenu", "5464")
which would generate a file called passwordmenu looking like

set passwordmenu = 5464
end

so i could do

while true do
shell.run("passwordmenu") -- loads the Variables
print("please enter password")
input = io.read("*")
 if input == passwordmenu then
  print("Welcome")
 else
  print("invalid input: ", input)
 end
end

the variable files could be also used to save Useful variables and load them when the program starts back up again
like passwords and important data Created by the program its self
theoriginalbit #2
Posted 05 February 2013 - 03:23 PM
Please note: We are not coding monkeys, so most of the time we won't do this. However this is small and easy so i will
SpoilerThe Code:

local filePath = "some/path/andFile"

local function loadPass()
  local handler = fs.open(filePath, "r")
  if handler then
	local pass = handler.readLine()
	handler.close()
	return pass
  end
  print("Cannot open file for read")
  error()
end

local function savePass( pass )
  local handler = fs.open(filePath, "w")
  if handler then
	handler.write(pass)
	handler.close()
	return true
  end
  print("Cannot open file for write")
  error()
end

the variable files could be also used to save Useful variables and load them when the program starts back up again
like passwords and important data Created by the program its self
I'm writing a configuration utility. And its released, see signature for link to my programs.. however modifying the above code could give you the same result.
Edited on 05 February 2013 - 03:43 PM
PhilHibbs #3
Posted 05 February 2013 - 10:14 PM
set passwordmenu = 5464
end
so i could do
while true do
shell.run("passwordmenu") -- loads the Variables
print("please enter password")
input = io.read("*")
if input == passwordmenu then
  print("Welcome")
else
  print("invalid input: ", input)
end
end

He he, ever heard of an injection attack? That's where someone sets their password to:
1 end while true do turtle.dig() turtle.forward() end
So you need some validation around the password entry if you're going to allow other people to enter passwords that will be stored in this manner. If you're hard-coding the password yourself so only you can access it, then this kind of attack is not a problem. Also this probably isn't running on a turtle.

I just realised that the password file is execute as a series of CraftOS commands and not as lua script, so my example won't work. I don't know if there is a way of injecting into a CraftOS script in the same manner, I can't find a CraftOS command list or syntax reference anywhere. But the principle is, never execute anything that a user has entered unless you have validated that it cannot contain anything executable.
Lithia #4
Posted 05 February 2013 - 11:05 PM
set passwordmenu = 5464
end
so i could do
while true do
shell.run("passwordmenu") -- loads the Variables
print("please enter password")
input = io.read("*")
if input == passwordmenu then
  print("Welcome")
else
  print("invalid input: ", input)
end
end

He he, ever heard of an injection attack? That's where someone sets their password to:
1 end while true do turtle.dig() turtle.forward() end
So you need some validation around the password entry if you're going to allow other people to enter passwords that will be stored in this manner. If you're hard-coding the password yourself so only you can access it, then this kind of attack is not a problem. Also this probably isn't running on a turtle.

I just realised that the password file is execute as a series of CraftOS commands and not as lua script, so my example won't work. I don't know if there is a way of injecting into a CraftOS script in the same manner, I can't find a CraftOS command list or syntax reference anywhere. But the principle is, never execute anything that a user has entered unless you have validated that it cannot contain anything executable.

I probably wont have that problem because the files are Program Generated and the computer has a type of Custom File protection that i made to stop people from tampering with files

—-
theoriginalbit #5
Posted 05 February 2013 - 11:11 PM
He he, ever heard of an injection attack? That's where someone sets their password to:
1 end while true do turtle.dig() turtle.forward() end
So you need some validation around the password entry if you're going to allow other people to enter passwords that will be stored in this manner. If you're hard-coding the password yourself so only you can access it, then this kind of attack is not a problem. Also this probably isn't running on a turtle.
Or just allow them to type whatever they want and use the method that I proposed. if the file is opened with fs api when data is read it is a string, the only way to get an "injection" to work with that is if you did
loadstring(theFileData)()
but then you are deliberately allowing for it.
PixelToast #6
Posted 06 February 2013 - 04:36 PM
http://pixeltoast.x6...cc/apis/infutil
savePrefs and readPrefs
if you dont want to use my serialization then use textutils :P/>
comparison:
Spoilertextutils:

{[1]="something",[2]="something",[3]="something",}
infutil:

{"something","something","something"}
Pharap #7
Posted 06 February 2013 - 06:25 PM
Does any pro know of a program or api or would like to create a program
that saves a single lined file that can be loaded by another program for example

API would be

save.variable("passwordmenu", "5464")
which would generate a file called passwordmenu looking like

set passwordmenu = 5464
end

so i could do

while true do
shell.run("passwordmenu") -- loads the Variables
print("please enter password")
input = io.read("*")
if input == passwordmenu then
  print("Welcome")
else
  print("invalid input: ", input)
end
end

the variable files could be also used to save Useful variables and load them when the program starts back up again
like passwords and important data Created by the program its self

io isn't a valid API, just read is fine. I suggest you have a read of the wiki, it's generally pretty decent (albeit lacking a bit of organisation): http://computercraft.info/wiki/Main_Page
Particularly be sure to read the APIs section, every programming language requires you to know the basic libraries, lua is no exception.
theoriginalbit #8
Posted 06 February 2013 - 06:32 PM
comparison:
Spoilertextutils:

{[1]="something",[2]="something",[3]="something"}
infutil:

{"something","something","something"}
How does infutil handle key/value? Or is it only indexes it removes the key for?


io isn't a valid API
Yes it is http://computercraft.info/wiki/IO_(API)
PixelToast #9
Posted 07 February 2013 - 01:07 PM
How does infutil handle key/value? Or is it only indexes it removes the key for?
it works the same with textutils but cleans up a bit
here is the segment that actually handles the tables:

  local result = "{"
  local aset=1
  local comma=false
  for k,v in pairs(t) do
   comma=true
   if k==aset then
	result = result..serializeImpl(v)..","
	aset=aset+1
   else
	result = result..("["..serializeImpl(k).."]="..serializeImpl(v)..",")
   end
  end
  if comma then
   result=string.sub(result,1,-2)
  end
  result = result.."}"
  return result
it also removes the extra comma at the end of the table
theoriginalbit #10
Posted 07 February 2013 - 02:58 PM
it works the same with textutils but cleans up a bit
here is the segment that actually handles the tables:
-snip-
it also removes the extra comma at the end of the table
Ahh ok cool :)/>

But from what I see in that code snippet (unless I'm just reading it wrong in my tired state) a table like this:

t = {
  "Hello There",
  question = "whats your name?",
  "Thats a nice name",
  ["self obsessed statement"] = "My name Bob is more awesome than yours",
}
Would come out like this because the aset number is only incremented when it comes across the same number

{ "Hello There", ["question"] = "what is your name?", [3] = "Thats a nice name", ["self obsessed statement"] = "My name Bob is more awesome than yours" }
Or am I just reading it wrong?

EDIT: Also I love how you do string dumps of functions :D/> So many times I try to easily save or send my tables but cant because they have functions
PixelToast #11
Posted 07 February 2013 - 04:43 PM
it souldnt do that .-.

i had it detect if the key could be used without the [""]s but it borked in some cases for a reason i forgot
i can try it again if you really hate them :P/>

EDIT:

nope


EDIT2:
explanation

local aset=1 -- look for the first index
for k,v in pairs(t) do -- indexes greater than zero will ALWAYS go in order
    if k==aset then -- if its the next index then compress
        result = result..serializeImpl(v)..","
        aset=aset+1 -- look for the next index
    else -- normal serialization
        result = result..("["..serializeImpl(k).."]="..serializeImpl(v)..",")
    end
end
theoriginalbit #12
Posted 07 February 2013 - 04:54 PM
EDIT:
nope
Ahh soo it seems that pairs puts all the indexes first, then the key/values
PixelToast #13
Posted 07 February 2013 - 05:21 PM
i made it remove [""]s when necicary and fixed newlines making \\\n instead of \\n