diff options
author | Varriount <Varriount@users.noreply.github.com> | 2014-05-21 17:56:54 -0400 |
---|---|---|
committer | Varriount <Varriount@users.noreply.github.com> | 2014-05-21 17:56:54 -0400 |
commit | 2232c187a7d297a0b45256ad32c88528efad750c (patch) | |
tree | 0a3a6b874fe60f090321fd75c1f35eb3e911a141 /doc/manual.txt | |
parent | 8581fb715f9e619ff55ff277098c1811cce878ef (diff) | |
parent | a16f762ce267d9aaa871f6a594f63ae6642f35a8 (diff) | |
download | Nim-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.txt | 65 |
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 |