On Feb 26, 2014, at 4:30 AM, yun...@apache.org wrote:

> Repository: trafficserver
> Updated Branches:
>  refs/heads/master 6d4005f8b -> 38996681d
> 
> 
> TS-2576: Add Oct/Hex escape representation into LogFormat
> 
> Introudce two escape representations into LogFormat:
> * Oct escape sequence:
>  '\abc': a,b,c should be one of [0-9], and
>          (a*8^2 + b*8 + c) should be greater than 0 and less than 255.
> 
> * Hex escape sequence:
>  '\xab': a,b should be one of [0-9, a-f, A-F], and
>          (a*16 + b) should be greater than 0 and less than 255.
> 
> Signed-off-by: Yunkai Zhang <qiushu....@taobao.com>

Nice! We should add these notes to 
doc/reference/configuration/logs_xml.config.en.rst

> 
> 
> Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
> Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/38996681
> Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/38996681
> Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/38996681
> 
> Branch: refs/heads/master
> Commit: 38996681d870249f923e07e5311f983372307316
> Parents: 6d4005f
> Author: Yunkai Zhang <qiushu....@taobao.com>
> Authored: Tue Feb 18 18:26:20 2014 +0800
> Committer: Yunkai Zhang <qiushu....@taobao.com>
> Committed: Wed Feb 26 20:29:21 2014 +0800
> 
> ----------------------------------------------------------------------
> CHANGES                    |   2 +
> proxy/logging/LogFormat.cc | 108 +++++++++++++++++++++++++++++++++++++---
> proxy/logging/LogFormat.h  |   1 +
> 3 files changed, 103 insertions(+), 8 deletions(-)
> ----------------------------------------------------------------------
> 
> 
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/38996681/CHANGES
> ----------------------------------------------------------------------
> diff --git a/CHANGES b/CHANGES
> index 150a243..5b374ec 100644
> --- a/CHANGES
> +++ b/CHANGES
> @@ -1,6 +1,8 @@
>                                                          -*- coding: utf-8 -*-
> Changes with Apache Traffic Server 5.0.0
> 
> +  *) [TS-2576] Add Oct/Hex escape representation into LogFormat
> +
>   *) [TS-2494] fix the crash that return the stale cached document
>    when os is down, even if it`s status is not 200 (ok).
>   *) [TS-2590] Translate documentation into Japanese.
> 
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/38996681/proxy/logging/LogFormat.cc
> ----------------------------------------------------------------------
> diff --git a/proxy/logging/LogFormat.cc b/proxy/logging/LogFormat.cc
> index 80e46f4..b5c50f3 100644
> --- a/proxy/logging/LogFormat.cc
> +++ b/proxy/logging/LogFormat.cc
> @@ -555,6 +555,77 @@ LogFormat::parse_symbol_string(const char 
> *symbol_string, LogFieldList *field_li
>   return field_count;
> }
> 
> +//
> +// Parse escape string, supports two forms:
> +//
> +// 1) Octal representation: '\abc', for example: '\060'
> +//    0 < (a*8^2 + b*8 + c) < 255
> +//
> +// 2) Hex representation: '\xab', for exampe: '\x3A'
> +//    0 < (a*16 + b) < 255
> +//
> +// Return -1 if the beginning four characters are not valid
> +// escape sequence, otherwise reutrn unsigned char value of the
> +// escape sequence in the string.
> +//
> +// NOTE: The value of escape sequence should be greater than 0
> +//       and less than 255, since:
> +//       - 0 is terminator of string, and
> +//       - 255('\377') has been used as LOG_FIELD_MARKER.
> +//
> +int
> +LogFormat::parse_escape_string(const char *str, int len)
> +{
> +  int sum, start = 0;
> +  unsigned char a, b, c;
> +
> +  if (str[start] != '\\' || len < 2)
> +    return -1;
> +
> +  if (str[start + 1] == '\\')
> +    return '\\';
> +
> +  if (len < 4)
> +    return -1;
> +
> +  a = (unsigned char)str[start + 1];
> +  b = (unsigned char)str[start + 2];
> +  c = (unsigned char)str[start + 3];
> +
> +  if (isdigit(a) && isdigit(b) && isdigit(b)) {
> +
> +    sum = (a - '0')*64 + (b - '0')*8 + (c - '0');
> +
> +    if (sum == 0 || sum >= 255) {
> +      Warning("Octal escape sequence out of range: \\%c%c%c, treat it as 
> normal string\n", a, b, c);
> +      return -1;
> +    } else
> +      return sum;
> +
> +  } else if (tolower(a) == 'x' && isxdigit(b) && isxdigit(c)) {
> +    int i, j;
> +    if (isdigit(b))
> +      i = b - '0';
> +    else
> +      i = toupper(b) - 'A' + 10;
> +
> +    if (isdigit(c))
> +      j = c - '0';
> +    else
> +      j = toupper(c) - 'A' + 10;
> +
> +    sum = i*16 + j;
> +
> +    if (sum == 0 || sum >= 255) {
> +      Warning("Hex escape sequence out of range: \\%c%c%c, treat it as 
> normal string\n", a, b, c);
> +      return -1;
> +    } else
> +      return sum;
> +  }
> +
> +  return -1;
> +}
> +
> /*-------------------------------------------------------------------------
>   LogFormat::parse_format_string
> 
> @@ -594,6 +665,7 @@ LogFormat::parse_format_string(const char *format_str, 
> char **printf_str, char *
>   unsigned field_count = 0;
>   unsigned field_len;
>   unsigned start, stop;
> +  int escape_char;
> 
>   for (start = 0; start < len; start++) {
>     //
> @@ -623,21 +695,41 @@ LogFormat::parse_format_string(const char *format_str, 
> char **printf_str, char *
>         fields_pos += field_len;
>         (*printf_str)[printf_pos++] = LOG_FIELD_MARKER;
>         ++field_count;
> +        start = stop;
>       } else {
>         //
> -        // This was not a logging field spec after all, so copy it
> -        // over to the printf string as is.
> +        // This was not a logging field spec after all,
> +        // then try to detect and parse escape string.
>         //
> -        memcpy(&(*printf_str)[printf_pos], &format_str[start], stop - start 
> + 1);
> -        printf_pos += stop - start + 1;
> +        escape_char = parse_escape_string(&format_str[start], (len - start));
> +
> +        if (escape_char == '\\') {
> +          start += 1;
> +          (*printf_str)[printf_pos++] = (char)escape_char;
> +        } else if (escape_char >= 0) {
> +          start += 3;
> +          (*printf_str)[printf_pos++] = (char)escape_char;
> +        } else {
> +          memcpy(&(*printf_str)[printf_pos], &format_str[start], stop - 
> start + 1);
> +          printf_pos += stop - start + 1;
> +        }
>       }
> -      start = stop;
>     } else {
>       //
> -      // This was not the start of a logging field spec, so simply
> -      // put this char into the printf_str.
> +      // This was not the start of a logging field spec,
> +      // then try to detect and parse escape string.
>       //
> -      (*printf_str)[printf_pos++] = format_str[start];
> +      escape_char = parse_escape_string(&format_str[start], (len - start));
> +
> +      if (escape_char == '\\') {
> +        start += 1;
> +        (*printf_str)[printf_pos++] = (char)escape_char;
> +      } else if (escape_char >= 0) {
> +        start += 3;
> +        (*printf_str)[printf_pos++] = (char)escape_char;
> +      } else {
> +        (*printf_str)[printf_pos++] = format_str[start];
> +      }
>     }
>   }
> 
> 
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/38996681/proxy/logging/LogFormat.h
> ----------------------------------------------------------------------
> diff --git a/proxy/logging/LogFormat.h b/proxy/logging/LogFormat.h
> index da32018..fcc2cef 100644
> --- a/proxy/logging/LogFormat.h
> +++ b/proxy/logging/LogFormat.h
> @@ -83,6 +83,7 @@ public:
>                                               char **file_name, char 
> **file_header, LogFileFormat * file_type);
>   static int parse_symbol_string(const char *symbol_string, LogFieldList 
> *field_list, bool *contains_aggregates);
>   static int parse_format_string(const char *format_str, char **printf_str, 
> char **fields_str);
> +  static int parse_escape_string(const char *str, int len);
> 
>   // these are static because m_tagging_on is a class variable
>   static void turn_tagging_on() { m_tagging_on = true; }
> 

Reply via email to