Author: rfm
Date: Sat Aug 29 22:12:33 2015
New Revision: 38946

URL: http://svn.gna.org/viewcvs/gnustep?rev=38946&view=rev
Log:
Safer debug logging for http request/response

Modified:
    libs/base/trunk/ChangeLog
    libs/base/trunk/Headers/GNUstepBase/NSData+GNUstepBase.h
    libs/base/trunk/Source/Additions/NSData+GNUstepBase.m
    libs/base/trunk/Source/GSHTTPURLHandle.m

Modified: libs/base/trunk/ChangeLog
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/ChangeLog?rev=38946&r1=38945&r2=38946&view=diff
==============================================================================
--- libs/base/trunk/ChangeLog   (original)
+++ libs/base/trunk/ChangeLog   Sat Aug 29 22:12:33 2015
@@ -1,6 +1,9 @@
 2015-08-29  Richard Frith-Macdonald <[email protected]>
 
        * Source/Additions/GSMime.m: Improve descriptions for debug.
+       * Source/Additions/NSData+GNUstepBase.m: Add escaped representation.
+       * Source/GSHTTPURLHandle.m: Use escaped text format for debug log
+       (and plist armored format) to ensure that we safely log binary data
 
 2015-08-24  Richard Frith-Macdonald <[email protected]>
 

Modified: libs/base/trunk/Headers/GNUstepBase/NSData+GNUstepBase.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Headers/GNUstepBase/NSData%2BGNUstepBase.h?rev=38946&r1=38945&r2=38946&view=diff
==============================================================================
--- libs/base/trunk/Headers/GNUstepBase/NSData+GNUstepBase.h    (original)
+++ libs/base/trunk/Headers/GNUstepBase/NSData+GNUstepBase.h    Sat Aug 29 
22:12:33 2015
@@ -47,6 +47,18 @@
  */
 + (id) dataWithRandomBytesOfLength: (NSUInteger)length;
 
+/** Returns an NSString object containing a backslash escaped representation
+ * of the receiver.
+ */
+- (NSString*) escapedRepresentation;
+
+/**
+ * Returns a buffer containing an ASCII backslash escaped representation
+ * of the receiver, (and optionally the size of the buffer excluding
+ * the trailing nul terminator).
+ */
+- (char*) escapedRepresentation: (NSUInteger*)length;
+
 /** Returns data formed by gunzipping the contents of the receiver.<br />
  * If the receiver did not contain data produced by gzip, this method
  * simply returns the receiver.<br />
@@ -70,22 +82,21 @@
  */
 - (BOOL) isGzipped;
 
-/**
- * Returns an NSString object containing an ASCII hexadecimal representation
+/** Returns an NSString object containing an ASCII hexadecimal representation
  * of the receiver.  This means that the returned object will contain
  * exactly twice as many characters as there are bytes as the receiver,
  * as each byte in the receiver is represented by two hexadecimal digits.<br />
  * The high order four bits of each byte is encoded before the low
  * order four bits.  Capital letters 'A' to 'F' are used to represent
- * values from 10 to 15.<br />
- * If you need the hexadecimal representation as raw byte data, use code
- * like -
- * <example>
- *   hexData = [[sourceData hexadecimalRepresentation]
- *     dataUsingEncoding: NSASCIIStringEncoding];
- * </example>
+ * values from 10 to 15.
  */
 - (NSString*) hexadecimalRepresentation;
+
+/** Returns a buffer containing an ASCII string with a nul terminated
+ * hexadecimal representation of the receiver, (and optionally the size
+ * of the buffer excluding the trailing nul terminator).
+ */
+- (char*) hexadecimalRepresentation: (NSUInteger*)length;
 
 /**
  * Initialises the receiver with the supplied string data which contains

Modified: libs/base/trunk/Source/Additions/NSData+GNUstepBase.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/Additions/NSData%2BGNUstepBase.m?rev=38946&r1=38945&r2=38946&view=diff
==============================================================================
--- libs/base/trunk/Source/Additions/NSData+GNUstepBase.m       (original)
+++ libs/base/trunk/Source/Additions/NSData+GNUstepBase.m       Sat Aug 29 
22:12:33 2015
@@ -116,33 +116,107 @@
   return AUTORELEASE(d);
 }
 
-/**
- * Returns an NSString object containing an ASCII hexadecimal representation
- * of the receiver.  This means that the returned object will contain
- * exactly twice as many characters as there are bytes as the receiver,
- * as each byte in the receiver is represented by two hexadecimal digits.<br />
- * The high order four bits of each byte is encoded before the low
- * order four bits.  Capital letters 'A' to 'F' are used to represent
- * values from 10 to 15.<br />
- * If you need the hexadecimal representation as raw byte data, use code
- * like -
- * <example>
- *   hexData = [[sourceData hexadecimalRepresentation]
- *     dataUsingEncoding: NSASCIIStringEncoding];
- * </example>
- */
+- (NSString*) escapedRepresentation
+{
+  char          *buf;
+  NSUInteger    len;
+  NSString      *string;
+
+  buf = [self escapedRepresentation: &len];
+  string = [[NSString alloc] initWithBytesNoCopy: buf
+                                          length: len
+                                        encoding: NSASCIIStringEncoding
+                                    freeWhenDone: YES];
+  return AUTORELEASE(string);
+}
+
+- (char*) escapedRepresentation: (NSUInteger*)length
+{
+  const uint8_t *bytes = (const uint8_t*)[self bytes];
+  uint8_t       *buf;
+  NSUInteger    count = [self length];
+  NSUInteger    size = count + 1;
+  NSUInteger    index;
+  NSUInteger    pos;
+
+  for (index = 0; index < count; index++)
+    {
+      uint8_t   b = bytes[index];
+
+      if ('\n' == b) size++;
+      else if ('\r' == b) size++;
+      else if ('\t' == b) size++;
+      else if ('\\' == b) size++;
+      else if (!isprint(b)) size += 3;
+    }
+  buf = (uint8_t*)malloc(size);
+  for (pos = index = 0; index < count; index++)
+    {
+      uint8_t   b = bytes[index];
+
+      if ('\n' == b)
+        {
+          buf[pos++] = '\\';
+          buf[pos++] = 'n';
+        }
+      else if ('\r' == b)
+        {
+          buf[pos++] = '\\';
+          buf[pos++] = 'r';
+        }
+      else if ('\t' == b)
+        {
+          buf[pos++] = '\\';
+          buf[pos++] = 't';
+        }
+      else if ('\\' == b)
+        {
+          buf[pos++] = '\\';
+          buf[pos++] = '\\';
+        }
+      else if (!isprint(b))
+        {
+          sprintf((char*)&buf[pos], "\\x%02x", b);
+          pos += 4;
+        }
+      else
+        {
+          buf[pos++] = b;
+        }
+    }
+  buf[pos] = '\0';
+  if (0 != length)
+    {
+      *length = pos;
+    }
+  return (char*)buf;
+}
+
 - (NSString*) hexadecimalRepresentation
+{
+  char          *buf;
+  NSUInteger    len;
+  NSString      *string;
+
+  buf = [self hexadecimalRepresentation: &len];
+  string = [[NSString alloc] initWithBytesNoCopy: buf
+                                          length: len
+                                        encoding: NSASCIIStringEncoding
+                                    freeWhenDone: YES];
+  return AUTORELEASE(string);
+}
+
+- (char*) hexadecimalRepresentation: (NSUInteger*)length
 {
   static const char    *hexChars = "0123456789ABCDEF";
   unsigned             slen = [self length];
   unsigned             dlen = slen * 2;
   const unsigned char  *src = (const unsigned char *)[self bytes];
-  char                 *dst = (char*)NSZoneMalloc(NSDefaultMallocZone(), dlen);
+  char                 *dst;
   unsigned             spos = 0;
   unsigned             dpos = 0;
-  NSData               *data;
-  NSString             *string;
-
+
+  dst = (char*)malloc(dlen + 1);
   while (spos < slen)
     {
       unsigned char    c = src[spos++];
@@ -150,12 +224,12 @@
       dst[dpos++] = hexChars[(c >> 4) & 0x0f];
       dst[dpos++] = hexChars[c & 0x0f];
     }
-  data = [NSData allocWithZone: NSDefaultMallocZone()];
-  data = [data initWithBytesNoCopy: dst length: dlen];
-  string = [[NSString alloc] initWithData: data
-                                encoding: NSASCIIStringEncoding];
-  RELEASE(data);
-  return AUTORELEASE(string);
+  dst[dpos] = '\0';
+  if (0 != length)
+    {
+      *length = dpos;
+    }
+  return dst;
 }
 
 - (NSData*) gunzipped

Modified: libs/base/trunk/Source/GSHTTPURLHandle.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/GSHTTPURLHandle.m?rev=38946&r1=38945&r2=38946&view=diff
==============================================================================
--- libs/base/trunk/Source/GSHTTPURLHandle.m    (original)
+++ libs/base/trunk/Source/GSHTTPURLHandle.m    Sat Aug 29 22:12:33 2015
@@ -43,6 +43,7 @@
 #import "Foundation/NSValue.h"
 #import "GNUstepBase/GSMime.h"
 #import "GNUstepBase/GSLock.h"
+#import "GNUstepBase/NSData+GNUstepBase.h"
 #import "GNUstepBase/NSString+GNUstepBase.h"
 #import "GNUstepBase/NSURL+GNUstepBase.h"
 #import "NSCallBacks.h"
@@ -230,36 +231,20 @@
 static void
 debugRead(GSHTTPURLHandle *handle, NSData *data)
 {
-  int          len = (int)[data length];
-  const char   *ptr = (const char*)[data bytes];
-  int           pos;
-
-  for (pos = 0; pos < len; pos++)
-    {
-      if (0 == ptr[pos])
-        {
-          NSLog(@"Read for %p of %d bytes - %@", handle, len, data); 
-          return;
-        }
-    }
-  NSLog(@"Read for %p of %d bytes - '%*.*s'", handle, len, len, len, ptr); 
+  unsigned     len = (unsigned)[data length];
+  char         *esc = [data escapedRepresentation: 0];
+
+  NSLog(@"Read for %p of %u bytes - '%s'\n%@", handle, len, esc, data); 
+  free(esc);
 }
 static void
 debugWrite(GSHTTPURLHandle *handle, NSData *data)
 {
-  int          len = (int)[data length];
-  const char   *ptr = (const char*)[data bytes];
-  int           pos = len;
-
-  for (pos = 0; pos < len; pos++)
-    {
-      if (0 == ptr[pos])
-        {
-          NSLog(@"Write for %p of %d bytes - %@", handle, len, data); 
-          return;
-        }
-    }
-  NSLog(@"Write for %p of %d bytes -'%*.*s'", handle, len, len, len, ptr); 
+  unsigned     len = (unsigned)[data length];
+  char         *esc = [data escapedRepresentation: 0];
+
+  NSLog(@"Write for %p of %u bytes - '%s'\n%@", handle, len, esc, data); 
+  free(esc);
 }
 
 + (NSURLHandle*) cachedHandleForURL: (NSURL*)newUrl


_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to