1 /++ 2 Escape special characters in MySQL strings. 3 4 Note, it is strongly recommended to use prepared statements instead of relying 5 on manual escaping, as prepared statements are always safer, better and more 6 reliable (see `mysql.prepared`). But if you absolutely must escape manually, 7 the functionality is provided here. 8 +/ 9 module mysql.escape; 10 11 12 /++ 13 Simple escape function for dangerous SQL characters 14 15 Params: 16 input = string to escape 17 buffer = buffer to use for the output 18 +/ 19 void mysql_escape ( Buffer, Input ) ( Input input, Buffer buffer ) 20 { 21 import std.string : translate; 22 23 immutable string[dchar] transTable = [ 24 '\\' : "\\\\", 25 '\'' : "\\'", 26 '\0' : "\\0", 27 '\n' : "\\n", 28 '\r' : "\\r", 29 '"' : "\\\"", 30 '\032' : "\\Z" 31 ]; 32 33 translate(input, transTable, null, buffer); 34 } 35 36 37 /++ 38 Struct to wrap around a string so it can be passed to formattedWrite and be 39 properly escaped all using the buffer that formattedWrite provides. 40 41 Params: 42 Input = (Template Param) Type of the input 43 +/ 44 struct MysqlEscape ( Input ) 45 { 46 Input input; 47 48 const void toString ( scope void delegate(const(char)[]) sink ) 49 { 50 struct SinkOutputRange 51 { 52 void put ( const(char)[] t ) { sink(t); } 53 } 54 55 SinkOutputRange r; 56 mysql_escape(input, r); 57 } 58 } 59 60 /++ 61 Helper function to easily construct a escape wrapper struct 62 63 Params: 64 T = (Template Param) Type of the input 65 input = Input to escape 66 +/ 67 MysqlEscape!(T) mysqlEscape ( T ) ( T input ) 68 { 69 return MysqlEscape!(T)(input); 70 } 71 72 @("mysqlEscape") 73 debug(MYSQLN_TESTS) 74 unittest 75 { 76 import std.array : appender; 77 78 auto buf = appender!string(); 79 80 import std.format : formattedWrite; 81 82 formattedWrite(buf, "%s, %s, %s, mkay?", 1, 2, 83 mysqlEscape("\0, \r, \n, \", \\")); 84 85 assert(buf.data() == `1, 2, \0, \r, \n, \", \\, mkay?`); 86 }