summary refs log tree commit diff stats
path: root/doc/manual.txt
diff options
context:
space:
mode:
authorVarriount <Varriount@users.noreply.github.com>2014-05-21 17:56:54 -0400
committerVarriount <Varriount@users.noreply.github.com>2014-05-21 17:56:54 -0400
commit2232c187a7d297a0b45256ad32c88528efad750c (patch)
tree0a3a6b874fe60f090321fd75c1f35eb3e911a141 /doc/manual.txt
parent8581fb715f9e619ff55ff277098c1811cce878ef (diff)
parenta16f762ce267d9aaa871f6a594f63ae6642f35a8 (diff)
downloadNim-2232c187a7d297a0b45256ad32c88528efad750c.tar.gz
Merge pull request #1191 from gradha/pr_removes_abstypes
Moves abstypes content into manual.
Diffstat (limited to 'doc/manual.txt')
-rw-r--r--doc/manual.txt65
1 files changed, 65 insertions, 0 deletions
diff --git a/doc/manual.txt b/doc/manual.txt
index fe4f0c038..a87abab7a 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -1550,6 +1550,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.
 
@@ -1657,6 +1661,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