lib/ronin/formatting/extensions/sql/string.rb in ronin-sql-0.2.4 vs lib/ronin/formatting/extensions/sql/string.rb in ronin-sql-1.0.0

- old
+ new

@@ -1,11 +1,12 @@ # -# Ronin SQL - A Ronin library providing support for SQL related security -# tasks. +# Ronin SQL - A Ruby DSL for crafting SQL Injections. # -# Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com) +# Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com) # +# This file is part of Ronin SQL. +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # @@ -20,15 +21,80 @@ # class String # + # Escapes an String for SQL. + # + # @param [:single, :double, :tick] quotes (:single) + # Specifies whether to create a single or double quoted string. + # + # @return [String] + # The escaped String. + # + # @raise [TypeError] + # The quotes argument was neither `:single`, `:double` nor `:tick`. + # + # @example + # "O'Brian".sql_escape + # # => "'O''Brian'" + # + # @example Encode with double-quotes: + # "O'Brian".sql_escape(:double) + # # => "\"O'Brian\"" + # + # @api public + # + def sql_escape(quotes=:single) + char = case quotes + when :single then "'" + when :double then '"' + when :tick then '`' + else + raise(ArgumentError,"invalid quoting style #{quotes.inspect}") + end + + return char + gsub(char,char * 2) + char + end + + # + # Unescapes a SQL String. + # + # @return [String] + # The unescaped String. + # + # @raise + # The String was not quoted with single, double or tick-mark quotes. + # + # @example + # "'O''Brian'".sql_unescape + # # => "O'Brian" + # + # @api public + # + # @since 1.0.0 + # + def sql_unescape + char = if (self[0] == "'" && self[-1] == "'") then "'" + elsif (self[0] == '"' && self[-1] == '"') then '"' + elsif (self[0] == '`' && self[-1] == '`') then '`' + else + raise(TypeError,"#{self.inspect} is not properly quoted") + end + + return self[1..-2].gsub(char * 2,char) + end + + # # Returns the SQL hex-string encoded form of the String. # + # @example # "/etc/passwd".sql_encode # # => "0x2f6574632f706173737764" # + # @api public + # def sql_encode return '' if empty? hex_string = '0x' @@ -40,28 +106,35 @@ end # # Returns the SQL decoded form of the String. # + # @example # "'Conan O''Brian'".sql_decode # # => "Conan O'Brian" # - # "0x2f6574632f706173737764".sql_decode + # @example + # "2f6574632f706173737764".sql_decode # # => "/etc/passwd" # + # @raise + # The String is neither hex encoded or SQL escaped. + # + # @see #sql_unescape + # + # @api public + # def sql_decode - if ((self[0...2] == '0x') && (length % 2 == 0)) + if (self =~ /^[0-9a-fA-F]{2,}$/ && (length % 2 == 0)) raw = '' - self[2..-1].scan(/[0-9a-fA-F]{2}/).each do |hex_char| - raw << hex_char.hex.chr + scan(/../) do |hex_char| + raw << hex_char.to_i(16) end return raw - elsif (self[0..0] == "'" && self[-1..-1] == "'") - self[1..-2].gsub(/\\'/,"'").gsub(/''/,"'") else - return self + sql_unescape end end end