Moves abstypes content into manual.
This commit is contained in:
parent
4d5ad91775
commit
a16f762ce2
2 changed files with 65 additions and 152 deletions
|
|
@ -1542,6 +1542,10 @@ of a distinct type that it **does not** imply a subtype relation between it
|
|||
and its base type. Explicit type conversions from a distinct type to its
|
||||
base type and vice versa are allowed.
|
||||
|
||||
|
||||
Modelling currencies
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A distinct type can be used to model different physical `units`:idx: with a
|
||||
numerical base type, for example. The following example models currencies.
|
||||
|
||||
|
|
@ -1649,6 +1653,67 @@ certain builtin operations to be lifted:
|
|||
Currently only the dot accessor can be borrowed in this way.
|
||||
|
||||
|
||||
Avoiding SQL injection attacks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An SQL statement that is passed from Nimrod to an SQL database might be
|
||||
modelled as a string. However, using string templates and filling in the
|
||||
values is vulnerable to the famous `SQL injection attack`:idx:\:
|
||||
|
||||
.. code-block:: nimrod
|
||||
import strutils
|
||||
|
||||
proc query(db: TDbHandle, statement: string) = ...
|
||||
|
||||
var
|
||||
username: string
|
||||
|
||||
db.query("SELECT FROM users WHERE name = '$1'" % username)
|
||||
# Horrible security hole, but the compiler does not mind!
|
||||
|
||||
This can be avoided by distinguishing strings that contain SQL from strings
|
||||
that don't. Distinct types provide a means to introduce a new string type
|
||||
``TSQL`` that is incompatible with ``string``:
|
||||
|
||||
.. code-block:: nimrod
|
||||
type
|
||||
TSQL = distinct string
|
||||
|
||||
proc query(db: TDbHandle, statement: TSQL) = ...
|
||||
|
||||
var
|
||||
username: string
|
||||
|
||||
db.query("SELECT FROM users WHERE name = '$1'" % username)
|
||||
# Error at compile time: `query` expects an SQL string!
|
||||
|
||||
|
||||
It is an essential property of abstract types that they **do not** imply a
|
||||
subtype relation between the abtract type and its base type. Explict type
|
||||
conversions from ``string`` to ``TSQL`` are allowed:
|
||||
|
||||
.. code-block:: nimrod
|
||||
import strutils, sequtils
|
||||
|
||||
proc properQuote(s: string): TSQL =
|
||||
# quotes a string properly for an SQL statement
|
||||
return TSQL(s)
|
||||
|
||||
proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
|
||||
# quote each argument:
|
||||
let v = values.mapIt(TSQL, properQuote(it))
|
||||
# we need a temporary type for the type conversion :-(
|
||||
type TStrSeq = seq[string]
|
||||
# call strutils.`%`:
|
||||
result = TSQL(string(frmt) % TStrSeq(v))
|
||||
|
||||
db.query("SELECT FROM users WHERE name = '$1'".TSQL % [username])
|
||||
|
||||
Now we have compile-time checking against SQL injection attacks. Since
|
||||
``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed for nice
|
||||
looking ``TSQL`` string literals. The hypothetical ``TSQL`` type actually
|
||||
exists in the library as the `TSqlQuery type <db_sqlite.html#TSqlQuery>`_ of
|
||||
modules like `db_sqlite <db_sqlite.html>`_.
|
||||
|
||||
|
||||
Void type
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue