This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.
Programming in Lua | ||
Part II. Tables and Objects Chapter 12. Data Files and Persistence |
Frequently we need to serialize some data, that is, to convert the data into a stream of bytes or characters, so that we can save it into a file or send it through a network connection. We can represent serialized data as Lua code, in such a way that, when we run the code, it reconstructs the saved values into the reading program.
Usually, if we want to restore the value of a global variable,
our chunk will be something like varname = <exp>
,
where <exp>
is the Lua code to create the value.
The varname
is the easy part,
so let us see how to write the code that creates a value.
For a numeric value, the task is easy:
function serialize (o) if type(o) == "number" then io.write(o) else ... endFor a string value, a naive approach would be something like
if type(o) == "string" then io.write("'", o, "'")However, if the string contains special characters (such as quotes or newlines) the resulting code will not be a valid Lua program. Here, you may be tempted to solve this problem changing quotes:
if type(o) == "string" then io.write("[[", o, "]]")Do not do that! Double square brackets are intended for hand-written strings, not for automatically generated ones. If a malicious user manages to direct your program to save something like
" ]]..os.execute('rm *')..[[ "
(for instance, she can supply that string as her address),
your final chunk will be
varname = [[ ]]..os.execute('rm *')..[[ ]]You will have a bad surprise trying to load this "data".
To quote an arbitrary string in a secure way,
the format
function, from the standard string
library,
offers the option "%q"
.
It surrounds the string with double quotes
and properly escapes double quotes, newlines,
and some other characters inside the string.
Using this feature, our serialize
function now looks like this:
function serialize (o) if type(o) == "number" then io.write(o) elseif type(o) == "string" then io.write(string.format("%q", o)) else ... end
Copyright © 2003–2004 Roberto Ierusalimschy. All rights reserved. |