subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From br...@apache.org
Subject svn commit: r1408325 - /subversion/branches/wc-collate-path/subversion/libsvn_subr/sqlite.c
Date Mon, 12 Nov 2012 15:36:48 GMT
Author: brane
Date: Mon Nov 12 15:36:47 2012
New Revision: 1408325

URL: http://svn.apache.org/viewvc?rev=1408325&view=rev
Log:
On the wc-collate-path branch: Enable GLOB and LIKE operator replacements.

* subversion/libsvn_subr/sqlite.c
  (SQLITE_MAX_LIKE_PATTERN_LENGTH): Limit the pattern lengths.
  (svn_sqlite__db_t): Add third buffer, sqlext_buf3, for glob/like;
  (glob_like_ucs_nfd_common): Common wrapper for svn_utf__glob.
  (glob_ucs_nfd, like_ucs_nfd): GLOB and LIKE user functions.
  (svn_sqlite__open): Initialize all sqlext_* buffers to 800 bytes.
   Register GLOB and LIKE operator replacements.

Modified:
    subversion/branches/wc-collate-path/subversion/libsvn_subr/sqlite.c

Modified: subversion/branches/wc-collate-path/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/libsvn_subr/sqlite.c?rev=1408325&r1=1408324&r2=1408325&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/wc-collate-path/subversion/libsvn_subr/sqlite.c Mon Nov 12 15:36:47
2012
@@ -57,6 +57,11 @@ extern const sqlite3_api_routines *const
 #error SQLite is too old -- version 3.7.12 is the minimum required version
 #endif
 
+/* Limit the length of a GLOB or LIKE pattern. */
+#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
+# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
+#endif
+
 const char *
 svn_sqlite__compiled_version(void)
 {
@@ -105,6 +110,7 @@ struct svn_sqlite__db_t
   /* Buffers for SQLite extensoins. */
   svn_stringbuf_t *sqlext_buf1;
   svn_stringbuf_t *sqlext_buf2;
+  svn_stringbuf_t *sqlext_buf3;
 };
 
 struct svn_sqlite__stmt_t
@@ -881,6 +887,74 @@ collate_ucs_nfd(void *baton,
   return result;
 }
 
+static void
+glob_like_ucs_nfd_common(sqlite3_context *context,
+                         int argc, sqlite3_value **argv,
+                         svn_boolean_t sql_like)
+{
+  svn_sqlite__db_t *const db = sqlite3_user_data(context);
+
+  const char *const pattern = (void*)sqlite3_value_text(argv[0]);
+  const apr_size_t pattern_len = sqlite3_value_bytes(argv[0]);
+  const char *const string = (void*)sqlite3_value_text(argv[1]);
+  const apr_size_t string_len = sqlite3_value_bytes(argv[1]);
+
+  const char *escape = NULL;
+  apr_size_t escape_len = 0;
+
+  svn_boolean_t match;
+  svn_error_t *err;
+
+  if (pattern_len > SQLITE_MAX_LIKE_PATTERN_LENGTH)
+    {
+      sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
+      return;
+    }
+
+  if (argc == 3 && sql_like)
+    {
+      escape = (void*)sqlite3_value_text(argv[2]);
+      escape_len = sqlite3_value_bytes(argv[2]);
+    }
+
+  if (pattern && string)
+    {
+      err = svn_utf__glob(pattern, pattern_len, string, string_len,
+                          escape, escape_len, sql_like,
+                          db->sqlext_buf1, db->sqlext_buf2, db->sqlext_buf3,
+                          &match);
+
+      if (err)
+        {
+          const char *errmsg;
+          svn_stringbuf_ensure(db->sqlext_buf1, 511);
+          errmsg = svn_err_best_message(err,
+                                        db->sqlext_buf1->data,
+                                        db->sqlext_buf1->blocksize);
+          svn_error_clear(err);
+          sqlite3_result_error(context, errmsg, -1);
+          return;
+        }
+
+      sqlite3_result_int(context, match);
+    }
+}
+
+/* Unicode normalizing implementation of GLOB */
+static void
+glob_ucs_nfd(sqlite3_context *context,
+             int argc, sqlite3_value **argv)
+{
+  glob_like_ucs_nfd_common(context, argc, argv, FALSE);
+}
+
+/* Unicode normalizing implementation of LIKE */
+static void
+like_ucs_nfd(sqlite3_context *context,
+             int argc, sqlite3_value **argv)
+{
+  glob_like_ucs_nfd_common(context, argc, argv, TRUE);
+}
 
 svn_error_t *
 svn_sqlite__open(svn_sqlite__db_t **db, const char *path,
@@ -895,12 +969,25 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
 
   SVN_ERR(internal_open(&(*db)->db3, path, mode, scratch_pool));
 
-  (*db)->sqlext_buf1 = svn_stringbuf_create_ensure(4096, result_pool);
-  (*db)->sqlext_buf2 = svn_stringbuf_create_ensure(4096, result_pool);
+  /* Create extension buffers with space for 200 UCS-4 characters. */
+  (*db)->sqlext_buf1 = svn_stringbuf_create_ensure(799, result_pool);
+  (*db)->sqlext_buf2 = svn_stringbuf_create_ensure(799, result_pool);
+  (*db)->sqlext_buf3 = svn_stringbuf_create_ensure(799, result_pool);
+
+  /* Register collation and LIKE and GLOB operator replacements. */
   SQLITE_ERR(sqlite3_create_collation((*db)->db3,
                                       "svn-ucs-nfd", SQLITE_UTF8,
                                       *db, collate_ucs_nfd),
              *db);
+  SQLITE_ERR(sqlite3_create_function((*db)->db3, "glob", 2, SQLITE_UTF8,
+                                     *db, glob_ucs_nfd, NULL, NULL),
+             *db);
+  SQLITE_ERR(sqlite3_create_function((*db)->db3, "like", 2, SQLITE_UTF8,
+                                     *db, like_ucs_nfd, NULL, NULL),
+             *db);
+  SQLITE_ERR(sqlite3_create_function((*db)->db3, "like", 3, SQLITE_UTF8,
+                                     *db, like_ucs_nfd, NULL, NULL),
+             *db);
 
 #ifdef SQLITE3_DEBUG
   sqlite3_trace((*db)->db3, sqlite_tracer, (*db)->db3);



Mime
View raw message