cSvn CGI Script

cSvn CGI Script – is a web frontend for Subversion™ Repositories

115 Commits   0 Branches   5 Tags   |
Index: configure.ac
===================================================================
--- configure.ac	(revision 57)
+++ configure.ac	(revision 58)
@@ -117,6 +117,7 @@
 dnl ============================================================
 dnl ============================================================
 AC_MSG_CFG_PART(Test for libraries)
+AC_CHECK_LIB([pcre],[pcre_compile],[],[AC_MSG_ERROR([Unable to find required libpcre])])
 AC_CHECK_LIB([pcre32],[pcre32_compile],[],[AC_MSG_ERROR([Unable to find required libpcre32])])
 AC_CHECK_LIB([rt],[aio_suspend],[],[AC_MSG_ERROR([Unable to find required librt])])
 AC_CHECK_LIB([m],[round],[],[AC_MSG_ERROR([Unable to find required libm])])
Index: csvncgi/strbuf.c
===================================================================
--- csvncgi/strbuf.c	(revision 57)
+++ csvncgi/strbuf.c	(revision 58)
@@ -24,6 +24,7 @@
 #include <grp.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <pcre.h>
 
 #include <nls.h>
 
@@ -482,7 +483,67 @@
   }
 }
 
+static int is_html_quoted( const char *str )
+{
+  int         rc = 0;
+  int         match[32];
+  const char *error = NULL;
+  int         offset = 0;
+  const char  pattern[] = "^(&[#A-Za-z0-9]*;)";
 
+  pcre *regexp = pcre_compile( pattern, 0, &error, &offset, NULL );
+  if( regexp == NULL )
+  {
+    return 0; /* PCRE compilation failed */
+  }
+
+  rc = pcre_exec( regexp, NULL, (PCRE_SPTR)str, (int)strlen(str), 0, 0,
+                  match, sizeof(match)/sizeof(match[0]) );
+  if( rc < 0 )
+  {
+    pcre_free( regexp ); /* not match */
+    return 0;
+  }
+  else
+  {
+    pcre_free( regexp ); /* match */
+    return 1;
+  }
+}
+
+void strbuf_addstr_html_quoted( struct strbuf *sb, const char *s )
+{
+  while( *s )
+  {
+    size_t len = strcspn( s, "\"<>&" );
+    strbuf_add( sb, s, len );
+    s += len;
+
+    switch( *s )
+    {
+      case '"':
+        strbuf_addstr( sb, "&quot;" );
+        break;
+      case '<':
+        strbuf_addstr( sb, "&lt;" );
+        break;
+      case '>':
+        strbuf_addstr( sb, "&gt;" );
+        break;
+      case '&':
+        if( !is_html_quoted( s ) )
+          strbuf_addstr( sb, "&amp;" );
+        else
+          strbuf_addch( sb, *s );
+        break;
+      case 0:
+        return;
+    }
+    s++;
+  }
+}
+
+
 /* urlencode: */
 
 int is_rfc3986_reserved_or_unreserved( char ch )
Index: csvncgi/strbuf.h
===================================================================
--- csvncgi/strbuf.h	(revision 57)
+++ csvncgi/strbuf.h	(revision 58)
@@ -170,8 +170,9 @@
 extern ssize_t strbuf_write( struct strbuf *sb, int fd );
 
 
-/* XML quoted: */
+/* XML/HTML quoted: */
 extern void strbuf_addstr_xml_quoted( struct strbuf *sb, const char *s );
+extern void strbuf_addstr_html_quoted( struct strbuf *sb, const char *s );
 
 /* urlencode: */
 typedef int (*char_predicate)(char ch);
Index: csvncgi/ui-blame.c
===================================================================
--- csvncgi/ui-blame.c	(revision 57)
+++ csvncgi/ui-blame.c	(revision 58)
@@ -64,16 +64,17 @@
   {
     char cmd[1024];
     struct strbuf buf = STRBUF_INIT;
-    pid_t p = (pid_t) -1;
-    int   rc;
+    char  *raw = NULL;
+    pid_t  p = (pid_t) -1;
+    int    rc;
 
     if( revision )
       snprintf( (char *)&cmd[0], 1024,
-                "svn blame --revision %d %s/%s/%s 2>/dev/null | sed 's,\\&,\\&amp;,g' | sed 's,<,\\&lt;,g' | sed 's,>,\\&gt;,g'",
+                "svn blame --revision %d %s/%s/%s 2>/dev/null",
                 revision, co_prefix, repo_path, relative_path );
     else
       snprintf( (char *)&cmd[0], 1024,
-                "svn blame %s/%s/%s 2>/dev/null | sed 's,\\&,\\&amp;,g' | sed 's,<,\\&lt;,g' | sed 's,>,\\&gt;,g'",
+                "svn blame %s/%s/%s 2>/dev/null",
                 co_prefix, repo_path, relative_path );
     p = sys_exec_command( &buf, cmd );
     rc = sys_wait_command( p, NULL );
@@ -83,10 +84,11 @@
       return;
     }
 
-    if( buf.buf[0] )
-    {
-      strbuf_addbuf( sb, (const struct strbuf *)&buf );
-    }
+    raw = strbuf_detach( &buf, NULL );
+    strbuf_addstr_xml_quoted( &buf, (const char *)raw );
+    free( raw );
+
+    strbuf_addbuf( sb, (const struct strbuf *)&buf );
     strbuf_release( &buf );
   }
 
Index: csvncgi/ui-diff.c
===================================================================
--- csvncgi/ui-diff.c	(revision 57)
+++ csvncgi/ui-diff.c	(revision 58)
@@ -63,11 +63,12 @@
   {
     char cmd[1024];
     struct strbuf buf = STRBUF_INIT;
-    pid_t p = (pid_t) -1;
-    int   rc;
+    char  *raw = NULL;
+    pid_t  p = (pid_t) -1;
+    int    rc;
 
     snprintf( (char *)&cmd[0], 1024,
-              "svn diff --revision %d:%d %s/%s/%s 2>/dev/null | sed 's,\\&,\\&amp;,g' | sed 's,<,\\&lt;,g' | sed 's,>,\\&gt;,g'",
+              "svn diff --revision %d:%d %s/%s/%s 2>/dev/null",
               revision-1, revision, co_prefix, repo_path, relative_path );
     p = sys_exec_command( &buf, cmd );
     rc = sys_wait_command( p, NULL );
@@ -77,10 +78,11 @@
       return;
     }
 
-    if( buf.buf[0] )
-    {
-      strbuf_addbuf( sb, (const struct strbuf *)&buf );
-    }
+    raw = strbuf_detach( &buf, NULL );
+    strbuf_addstr_xml_quoted( &buf, (const char *)raw );
+    free( raw );
+
+    strbuf_addbuf( sb, (const struct strbuf *)&buf );
     strbuf_release( &buf );
   }
 
Index: csvncgi/ui-file.c
===================================================================
--- csvncgi/ui-file.c	(revision 57)
+++ csvncgi/ui-file.c	(revision 58)
@@ -129,16 +129,17 @@
   {
     char cmd[1024];
     struct strbuf buf = STRBUF_INIT;
-    pid_t p = (pid_t) -1;
-    int   rc;
+    char  *raw = NULL;
+    pid_t  p = (pid_t) -1;
+    int    rc;
 
     if( revision )
       snprintf( (char *)&cmd[0], 1024,
-                "svn cat --revision %d %s/%s/%s 2>/dev/null | sed 's,\\&,\\&amp;,g' | sed 's,<,\\&lt;,g' | sed 's,>,\\&gt;,g'",
+                "svn cat --revision %d %s/%s/%s 2>/dev/null",
                 revision, co_prefix, repo_path, relative_path );
     else
       snprintf( (char *)&cmd[0], 1024,
-                "svn cat %s/%s/%s 2>/dev/null | sed 's,\\&,\\&amp;,g' | sed 's,<,\\&lt;,g' | sed 's,>,\\&gt;,g'",
+                "svn cat %s/%s/%s 2>/dev/null",
                 co_prefix, repo_path, relative_path );
     p = sys_exec_command( &buf, cmd );
     rc = sys_wait_command( p, NULL );
@@ -148,10 +149,11 @@
       return;
     }
 
-    if( buf.buf[0] )
-    {
-      strbuf_addbuf( sb, (const struct strbuf *)&buf );
-    }
+    raw = strbuf_detach( &buf, NULL );
+    strbuf_addstr_xml_quoted( &buf, (const char *)raw );
+    free( raw );
+
+    strbuf_addbuf( sb, (const struct strbuf *)&buf );
     strbuf_release( &buf );
   }
 
Index: doc/test.txt
===================================================================
--- doc/test.txt	(revision 57)
+++ doc/test.txt	(nonexistent)
@@ -1,2 +0,0 @@
-
-char *s= " \"amp\"  \&quot; < > & &#8211; &lt; eeee &gt; ";