Avoids problems with inappropriate string format strings >>> safeStringFormat('SELECT foo FROM %s LIMIT %d', ('bar', '1')) 'SELECT foo FROM bar LIMIT 1' >>> safeStringFormat("SELECT foo FROM %s WHERE name LIKE '%susan%' LIMIT %d", ('bar', '1')) "SELECT foo FROM bar WHERE name L
(format_, params)
| 2161 | return retVal |
| 2162 | |
| 2163 | def safeStringFormat(format_, params): |
| 2164 | """ |
| 2165 | Avoids problems with inappropriate string format strings |
| 2166 | |
| 2167 | >>> safeStringFormat('SELECT foo FROM %s LIMIT %d', ('bar', '1')) |
| 2168 | 'SELECT foo FROM bar LIMIT 1' |
| 2169 | >>> safeStringFormat("SELECT foo FROM %s WHERE name LIKE '%susan%' LIMIT %d", ('bar', '1')) |
| 2170 | "SELECT foo FROM bar WHERE name LIKE '%susan%' LIMIT 1" |
| 2171 | """ |
| 2172 | |
| 2173 | if format_.count(PAYLOAD_DELIMITER) == 2: |
| 2174 | _ = format_.split(PAYLOAD_DELIMITER) |
| 2175 | _[1] = re.sub(r"(\A|[^A-Za-z0-9])(%d)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>", _[1]) |
| 2176 | retVal = PAYLOAD_DELIMITER.join(_) |
| 2177 | else: |
| 2178 | retVal = re.sub(r"(\A|[^A-Za-z0-9])(%d)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>", format_) |
| 2179 | |
| 2180 | if isinstance(params, six.string_types): |
| 2181 | retVal = retVal.replace("%s", params, 1) |
| 2182 | elif not isListLike(params): |
| 2183 | retVal = retVal.replace("%s", getUnicode(params), 1) |
| 2184 | else: |
| 2185 | start, end = 0, len(retVal) |
| 2186 | match = re.search(r"%s(.+)%s" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER), retVal) |
| 2187 | if match and PAYLOAD_DELIMITER not in match.group(1): |
| 2188 | start, end = match.start(), match.end() |
| 2189 | if retVal.count("%s", start, end) == len(params): |
| 2190 | for param in params: |
| 2191 | index = retVal.find("%s", start) |
| 2192 | if isinstance(param, six.string_types): |
| 2193 | param = param.replace('%', PARAMETER_PERCENTAGE_MARKER) |
| 2194 | retVal = retVal[:index] + getUnicode(param) + retVal[index + 2:] |
| 2195 | else: |
| 2196 | if any('%s' in _ for _ in conf.parameters.values()): |
| 2197 | parts = format_.split(' ') |
| 2198 | for i in xrange(len(parts)): |
| 2199 | if PAYLOAD_DELIMITER in parts[i]: |
| 2200 | parts[i] = parts[i].replace(PAYLOAD_DELIMITER, "") |
| 2201 | parts[i] = "%s%s" % (parts[i], PAYLOAD_DELIMITER) |
| 2202 | break |
| 2203 | format_ = ' '.join(parts) |
| 2204 | |
| 2205 | count = 0 |
| 2206 | while True: |
| 2207 | match = re.search(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", retVal) |
| 2208 | if match: |
| 2209 | try: |
| 2210 | retVal = re.sub(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>" % params[count % len(params)], retVal, 1) |
| 2211 | except re.error: |
| 2212 | retVal = retVal.replace(match.group(0), match.group(0) % params[count % len(params)], 1) |
| 2213 | count += 1 |
| 2214 | else: |
| 2215 | break |
| 2216 | |
| 2217 | if count > len(params) and count % len(params): |
| 2218 | warnMsg = "wrong number of parameters during string formatting. " |
| 2219 | warnMsg += "Please report by e-mail content \"%r | %r | %r\" to '%s'" % (format_, params, retVal, DEV_EMAIL_ADDRESS) |
| 2220 | raise SqlmapValueException(warnMsg) |
no test coverage detected
searching dependent graphs…