// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab /* * Ceph - scalable distributed file system * * Copyright (C) 2011 New Dream Network * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software * Foundation. See file COPYING. * */ #include "common/escape.h" #include #include /* * Some functions for escaping RGW responses */ /* Static string length */ #define SSTRL(x) ((sizeof(x)/sizeof(x[0])) - 1) #define LESS_THAN_XESCAPE "<" #define AMPERSAND_XESCAPE "&" #define GREATER_THAN_XESCAPE ">" #define SGL_QUOTE_XESCAPE "'" #define DBL_QUOTE_XESCAPE """ int escape_xml_attr_len(const char *buf) { const char *b; int ret = 0; for (b = buf; *b; ++b) { unsigned char c = *b; switch (c) { case '<': ret += SSTRL(LESS_THAN_XESCAPE); break; case '&': ret += SSTRL(AMPERSAND_XESCAPE); break; case '>': ret += SSTRL(GREATER_THAN_XESCAPE); break; case '\'': ret += SSTRL(SGL_QUOTE_XESCAPE); break; case '"': ret += SSTRL(DBL_QUOTE_XESCAPE); break; default: // Escape control characters. if (((c < 0x20) && (c != 0x09) && (c != 0x0a)) || (c == 0x7f)) { ret += 6; } else { ret++; } } } // leave room for null terminator ret++; return ret; } void escape_xml_attr(const char *buf, char *out) { char *o = out; const char *b; for (b = buf; *b; ++b) { unsigned char c = *b; switch (c) { case '<': memcpy(o, LESS_THAN_XESCAPE, SSTRL(LESS_THAN_XESCAPE)); o += SSTRL(LESS_THAN_XESCAPE); break; case '&': memcpy(o, AMPERSAND_XESCAPE, SSTRL(AMPERSAND_XESCAPE)); o += SSTRL(AMPERSAND_XESCAPE); break; case '>': memcpy(o, GREATER_THAN_XESCAPE, SSTRL(GREATER_THAN_XESCAPE)); o += SSTRL(GREATER_THAN_XESCAPE); break; case '\'': memcpy(o, SGL_QUOTE_XESCAPE, SSTRL(SGL_QUOTE_XESCAPE)); o += SSTRL(SGL_QUOTE_XESCAPE); break; case '"': memcpy(o, DBL_QUOTE_XESCAPE, SSTRL(DBL_QUOTE_XESCAPE)); o += SSTRL(DBL_QUOTE_XESCAPE); break; default: // Escape control characters. if (((c < 0x20) && (c != 0x09) && (c != 0x0a)) || (c == 0x7f)) { snprintf(o, 7, "&#x%02x;", c); o += 6; } else { *o++ = c; } break; } } // null terminator *o = '\0'; } #define DBL_QUOTE_JESCAPE "\\\"" #define BACKSLASH_JESCAPE "\\\\" #define TAB_JESCAPE "\\t" #define NEWLINE_JESCAPE "\\n" int escape_json_attr_len(const char *buf, int src_len) { const char *b; int ret = 0; int i; for (i = 0, b = buf; i < src_len; ++i, ++b) { unsigned char c = *b; switch (c) { case '"': ret += SSTRL(DBL_QUOTE_JESCAPE); break; case '\\': ret += SSTRL(BACKSLASH_JESCAPE); break; case '\t': ret += SSTRL(TAB_JESCAPE); break; case '\n': ret += SSTRL(NEWLINE_JESCAPE); break; default: // Escape control characters. if ((c < 0x20) || (c == 0x7f)) { ret += 6; } else { ret++; } } } // leave room for null terminator ret++; return ret; } void escape_json_attr(const char *buf, int src_len, char *out) { char *o = out; const char *b; int i; for (i = 0, b = buf; i < src_len; ++i, ++b) { unsigned char c = *b; switch (c) { case '"': // cppcheck-suppress invalidFunctionArg memcpy(o, DBL_QUOTE_JESCAPE, SSTRL(DBL_QUOTE_JESCAPE)); o += SSTRL(DBL_QUOTE_JESCAPE); break; case '\\': // cppcheck-suppress invalidFunctionArg memcpy(o, BACKSLASH_JESCAPE, SSTRL(BACKSLASH_JESCAPE)); o += SSTRL(BACKSLASH_JESCAPE); break; case '\t': // cppcheck-suppress invalidFunctionArg memcpy(o, TAB_JESCAPE, SSTRL(TAB_JESCAPE)); o += SSTRL(TAB_JESCAPE); break; case '\n': // cppcheck-suppress invalidFunctionArg memcpy(o, NEWLINE_JESCAPE, SSTRL(NEWLINE_JESCAPE)); o += SSTRL(NEWLINE_JESCAPE); break; default: // Escape control characters. if ((c < 0x20) || (c == 0x7f)) { snprintf(o, 7, "\\u%04x", c); o += 6; } else { *o++ = c; } break; } } // null terminator *o = '\0'; }