From: stephan Date: Mon, 13 Nov 2023 18:35:37 +0000 (+0000) Subject: JNI: add sqlite3_result_nio_buffer() and tests. Discover that we cannot create sensib... X-Git-Tag: version-3.45.0~169 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=87c407da182f9f8aa69f446988ea05a967ce062a;p=thirdparty%2Fsqlite.git JNI: add sqlite3_result_nio_buffer() and tests. Discover that we cannot create sensible sqlite3_column_nio_buffer() or sqlite3_value_nio_buffer() counterparts because of ByteBuffer interface limitations. FossilOrigin-Name: 44b4df01ff86841fb85b6295cbada422c6ba8a32a420a2e840e2d607b6c90164 --- diff --git a/ext/jni/src/c/sqlite3-jni.c b/ext/jni/src/c/sqlite3-jni.c index e3814825b1..e04b3ab5f3 100644 --- a/ext/jni/src/c/sqlite3-jni.c +++ b/ext/jni/src/c/sqlite3-jni.c @@ -882,7 +882,7 @@ static jbyte * s3jni__jbyteArray_bytes2(JNIEnv * const env, jbyteArray jBA, jsiz ** required so cannot check for that violation. The caller is required ** to ensure that any to-be-bind()ed range fits within SQLITE_LIMIT. */ -/*static*/ void s3jni__get_nio_buffer(JNIEnv * const env, jobject jbb, void **pBuf, jint * pN ){ +static void s3jni__get_nio_buffer(JNIEnv * const env, jobject jbb, void **pBuf, jint * pN ){ *pBuf = 0; *pN = 0; if( jbb ){ @@ -2433,32 +2433,90 @@ S3JniApi(sqlite3_bind_blob(),jint,1bind_1blob)( return (jint)rc; } +/** + Helper for use with s3jni_setup_nio_args(). +*/ +struct S3JniNioArgs { + jobject jBuf; /* input - ByteBuffer */ + jint iBegin; /* input - byte offset */ + jint iN; /* input - byte count to bind */ + jint nBuf; /* output - jBuf's buffer size */ + void * p; /* output - jBuf's buffer memory */ + const void * pStart; /* output - offset of p to bind */ + int iOutLen; /* output - number of bytes from pStart to bind */ +}; +typedef struct S3JniNioArgs S3JniNioArgs; +static const S3JniNioArgs S3JniNioArgs_empty = { + 0,0,0,0,0,0,0 +}; + +/** + Internal helper for sqlite3_bind_nio_buffer() and + sqlite3_result_nio_buffer(). Populates pArgs and returns 0 on + success, non-0 if the operation should fail. The caller is + required to check for SJG.g.cByteBuffer!=0 before calling + this and reporting it in a way appropriate for that routine. + This function may assert() that SJG.g.cByteBuffer is not 0. + + The (jBuffer, iBegin, iN) arguments are the (ByteBuffer, offset, + length) arguments to the bind/result method. +*/ +static int s3jni_setup_nio_args( + JNIEnv *env, S3JniNioArgs * pArgs, + jobject jBuffer, jint iBegin, jint iN +){ + jlong iEnd = 0; + *pArgs = S3JniNioArgs_empty; + pArgs->jBuf = jBuffer; + pArgs->iBegin = iBegin; + pArgs->iN = iN; + assert( SJG.g.cByteBuffer ); + if( pArgs->iBegin<0 ){ + return SQLITE_MISUSE; + } + s3jni_get_nio_buffer(pArgs->jBuf, &pArgs->p, &pArgs->nBuf); + if( !pArgs->p ){ + return SQLITE_MISUSE; + }else if( pArgs->iBegin>=pArgs->nBuf ){ + pArgs->pStart = 0; + pArgs->iOutLen = 0; + return 0; + } + assert( pArgs->nBuf > 0 ); + assert( pArgs->iBegin < pArgs->nBuf ); + iEnd = pArgs->iN<0 ? pArgs->nBuf - pArgs->iBegin : pArgs->iBegin + pArgs->iN; + if( iEnd>(jlong)pArgs->nBuf ) iEnd = pArgs->nBuf - pArgs->iBegin; + if( iEnd - pArgs->iBegin > (jlong)SQLITE_MAX_LENGTH ){ + return SQLITE_TOOBIG; + } + assert( pArgs->iBegin >= 0 ); + assert( iEnd > pArgs->iBegin ); + pArgs->pStart = pArgs->p + pArgs->iBegin; + pArgs->iOutLen = (int)(iEnd - pArgs->iBegin); + assert( pArgs->iOutLen > 0 ); + return 0; +} + S3JniApi(sqlite3_bind_nio_buffer(),jint,1bind_1nio_1buffer)( JniArgsEnvClass, jobject jpStmt, jint ndx, jobject jBuffer, jint iBegin, jint iN ){ sqlite3_stmt * pStmt = PtrGet_sqlite3_stmt(jpStmt); - void * pBuf = 0; - jint nBuf = 0; - jlong iEnd = 0; - if( !SJG.g.cByteBuffer || !pStmt || iBegin<0 ){ - return (jint)SQLITE_MISUSE; - } - s3jni_get_nio_buffer(jBuffer, &pBuf, &nBuf); - if( !pBuf || iBegin>=nBuf ){ - return (jint)sqlite3_bind_null(pStmt, ndx); - } - assert( nBuf > 0 ); - assert( iBegin < nBuf ); - iEnd = iN<0 ? nBuf - iBegin : iBegin + iN; - if( iEnd>(jlong)nBuf ) iEnd = nBuf-iBegin; - if( iEnd-iBegin >(jlong)SQLITE_MAX_LENGTH ){ - return SQLITE_MISUSE; + S3JniNioArgs args; + int rc; + if( !pStmt || !SJG.g.cByteBuffer ) return SQLITE_MISUSE; + rc = s3jni_setup_nio_args(env, &args, jBuffer, iBegin, iN); + if(rc){ + return rc; + }else if( !args.pStart || !args.iOutLen ){ + return sqlite3_bind_null(pStmt, ndx); } - assert( iBegin>=0 ); - assert( iEnd > iBegin ); - return (jint)sqlite3_bind_blob(pStmt, (int)ndx, pBuf + iBegin, - (int)(iEnd - iBegin), SQLITE_TRANSIENT); + assert( args.iOutLen>0 ); + assert( args.nBuf > 0 ); + assert( args.pStart != 0 ); + assert( (args.pStart + args.iOutLen) <= (args.p + args.nBuf) ); + return sqlite3_bind_blob( pStmt, (int)ndx, args.pStart, + args.iOutLen, SQLITE_TRANSIENT ); } S3JniApi(sqlite3_bind_double(),jint,1bind_1double)( @@ -4470,6 +4528,40 @@ S3JniApi(sqlite3_result_java_object(),void,1result_1java_1object)( } } +S3JniApi(sqlite3_result_nio_buffer(),void,1result_1nio_1buffer)( + JniArgsEnvClass, jobject jpCtx, jobject jBuffer, + jint iBegin, jint iN +){ + sqlite3_context * pCx = PtrGet_sqlite3_context(jpCtx); + int rc; + S3JniNioArgs args; + if( !pCx ){ + return; + }else if( !SJG.g.cByteBuffer ){ + sqlite3_result_error( + pCx, "This JVM does not support JNI access to ByteBuffers.", -1 + ); + return; + } + rc = s3jni_setup_nio_args(env, &args, jBuffer, iBegin, iN); + if(rc){ + if( iBegin<0 ){ + sqlite3_result_error(pCx, "Start index may not be negative.", -1); + }else if( SQLITE_TOOBIG==rc ){ + sqlite3_result_error_toobig(pCx); + }else{ + sqlite3_result_error( + pCx, "Invalid arguments to sqlite3_result_nio_buffer().", -1 + ); + } + }else if( !args.pStart || !args.iOutLen ){ + sqlite3_result_null(pCx); + }else{ + sqlite3_result_blob(pCx, args.pStart, args.iOutLen, SQLITE_TRANSIENT); + } +} + + S3JniApi(sqlite3_result_null(),void,1result_1null)( JniArgsEnvClass, jobject jpCx ){ diff --git a/ext/jni/src/c/sqlite3-jni.h b/ext/jni/src/c/sqlite3-jni.h index f306c53fcb..bf1cc56d1e 100644 --- a/ext/jni/src/c/sqlite3-jni.h +++ b/ext/jni/src/c/sqlite3-jni.h @@ -1729,6 +1729,14 @@ JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1int64 JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1java_1object (JNIEnv *, jclass, jobject, jobject); +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_nio_buffer + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;Ljava/nio/ByteBuffer;II)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1nio_1buffer + (JNIEnv *, jclass, jobject, jobject, jint, jint); + /* * Class: org_sqlite_jni_capi_CApi * Method: sqlite3_result_null diff --git a/ext/jni/src/org/sqlite/jni/capi/CApi.java b/ext/jni/src/org/sqlite/jni/capi/CApi.java index 569d8f4a97..d3d434f7d6 100644 --- a/ext/jni/src/org/sqlite/jni/capi/CApi.java +++ b/ext/jni/src/org/sqlite/jni/capi/CApi.java @@ -295,16 +295,16 @@ public final class CApi { range is silently truncated to fit the buffer. If any of the following are true, this function behaves like - sqlite3_bind_null(): the buffer is null, beginPos is past the end - of the buffer, howMany is 0, or the calculated slice of the blob - has a length of 0. + sqlite3_bind_null(): the buffer is null, beginPos is at or past + the end of the buffer, howMany is 0, or the calculated slice of + the blob has a length of 0. If ndx is out of range, it returns SQLITE_RANGE, as documented - for sqlite3_bind_blob(). If any other arguments are invalid or - if sqlite3_jni_supports_nio() is false then SQLITE_MISUSE is + for sqlite3_bind_blob(). If beginPos is negative or if + sqlite3_jni_supports_nio() returns false then SQLITE_MISUSE is returned. Note that this function is bound (as it were) by the - SQLITE_LIMIT_LENGTH constraint and SQLITE_MISUSE is returned if - that's violated. + SQLITE_LIMIT_LENGTH constraint and SQLITE_TOOBIG is returned if + the resulting slice of the buffer exceeds that limit. This function does not modify the buffer's streaming-related cursors. @@ -318,6 +318,10 @@ public final class CApi { buffers and the only such class offered by Java is (apparently) ByteBuffer. + Design note: there are no sqlite3_column_nio_buffer() and + sqlite3_value_nio_buffer() counterparts because the ByteBuffer + interface does not enable sensible implementations of those. + @see https://docs.oracle.com/javase/8/docs/api/java/nio/Buffer.html */ public static native int sqlite3_bind_nio_buffer( @@ -1560,6 +1564,39 @@ public final class CApi { @NotNull sqlite3_context cx, @NotNull Object o ); + /** + Similar to sqlite3_bind_nio_buffer(), this works like + sqlite3_result_blob() but accepts a java.nio.ByteBuffer as its + input source. See sqlite3_bind_nio_buffer() for the semantics of + the second and subsequent arguments. + + If cx is null then this function will silently fail. If + sqlite3_jni_supports_nio() returns false or iBegin is negative, + an error result is set. If (begin+n) extends beyond the end of + the buffer, it is silently truncated to fit. + + If any of the following apply, this function behaves like + sqlite3_result_null(): the blob is null, the resulting slice of + the blob is empty. + + If the resulting slice of the buffer exceeds SQLITE_LIMIT_LENGTH + then this function behaves like sqlite3_result_error_toobig(). + */ + public static native void sqlite3_result_nio_buffer( + @NotNull sqlite3_context cx, @Nullable java.nio.ByteBuffer blob, + int begin, int n + ); + + /** + Convenience overload which uses the whole input object + as the result blob content. + */ + public static void sqlite3_result_nio_buffer( + @NotNull sqlite3_context cx, @Nullable java.nio.ByteBuffer blob + ){ + sqlite3_result_nio_buffer(cx, blob, 0, -1); + } + public static native void sqlite3_result_null( @NotNull sqlite3_context cx ); @@ -1654,6 +1691,27 @@ public final class CApi { sqlite3_result_blob(cx, blob, (int)(null==blob ? 0 : blob.length)); } + /** + Convenience overload which behaves like + sqlite3_result_nio_buffer(). + */ + public static void sqlite3_result_blob( + @NotNull sqlite3_context cx, @Nullable java.nio.ByteBuffer blob, + int begin, int n + ){ + sqlite3_result_nio_buffer(cx, blob, begin, n); + } + + /** + Convenience overload which behaves like the two-argument overload of + sqlite3_result_nio_buffer(). + */ + public static void sqlite3_result_blob( + @NotNull sqlite3_context cx, @Nullable java.nio.ByteBuffer blob + ){ + sqlite3_result_nio_buffer(cx, blob); + } + /** Binds the given text using C's sqlite3_result_blob64() unless: diff --git a/ext/jni/src/org/sqlite/jni/capi/Tester1.java b/ext/jni/src/org/sqlite/jni/capi/Tester1.java index 0587eb6318..b50e3eaac1 100644 --- a/ext/jni/src/org/sqlite/jni/capi/Tester1.java +++ b/ext/jni/src/org/sqlite/jni/capi/Tester1.java @@ -39,12 +39,12 @@ import java.util.concurrent.Future; @interface SingleThreadOnly{} /** - Annotation for Tester1 tests which must only be run if JNI-level support for - java.nio.Buffer is available. + Annotation for Tester1 tests which must only be run if + sqlite3_jni_supports_nio() is true. */ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) -@interface RequiresNioBuffer{} +@interface RequiresJniNio{} public class Tester1 implements Runnable { //! True when running in multi-threaded mode. @@ -565,42 +565,65 @@ public class Tester1 implements Runnable { sqlite3_close_v2(db); } - @RequiresNioBuffer + @RequiresJniNio private void testBindByteBuffer(){ + /* TODO: these tests need to be much more extensive to check the + begin/end range handling. */ + sqlite3 db = createNewDb(); execSql(db, "CREATE TABLE t(a)"); - sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); - java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocateDirect(10); + + final java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocateDirect(10); buf.put((byte)0x31)/*note that we'll skip this one*/ .put((byte)0x32) .put((byte)0x33) - .put((byte)0x34); - int rc = sqlite3_bind_blob(stmt, 1, buf, -1, 0); - affirm( SQLITE_MISUSE==rc ); - rc = sqlite3_bind_blob(stmt, 1, buf, 1, 3); - affirm( 0==rc ); - rc = sqlite3_step(stmt); - affirm(SQLITE_DONE == rc); + .put((byte)0x34) + .put((byte)0x35)/*we'll skip this one too*/; + + final int expectTotal = buf.get(1) + buf.get(2) + buf.get(3); + sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); + affirm( SQLITE_MISUSE == sqlite3_bind_blob(stmt, 1, buf, -1, 0) ); + affirm( 0 == sqlite3_bind_blob(stmt, 1, buf, 1, 3) ); + affirm( SQLITE_DONE == sqlite3_step(stmt) ); sqlite3_finalize(stmt); - stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); - int n = 0; + stmt = prepare(db, "SELECT a FROM t;"); int total = 0; - while( SQLITE_ROW == sqlite3_step(stmt) ){ - byte[] blob = sqlite3_column_blob(stmt, 0); - affirm(3 == blob.length); - int i = 0; - for(byte b : blob){ - affirm( i<=3 ); - affirm(b == buf.get(1 + i++)); - total += b; - } - ++n; + affirm( SQLITE_ROW == sqlite3_step(stmt) ); + byte blob[] = sqlite3_column_blob(stmt, 0); + affirm(3 == blob.length); + int i = 0; + for(byte b : blob){ + affirm( i<=3 ); + affirm(b == buf.get(1 + i++)); + total += b; } + affirm( SQLITE_DONE == sqlite3_step(stmt) ); sqlite3_finalize(stmt); - affirm(1 == n); - affirm(total == 0x32 + 0x33 + 0x34); - /* TODO: these tests need to be much more extensive to check the - begin range handling. */ + affirm(total == expectTotal); + + SQLFunction func = + new ScalarFunction(){ + public void xFunc(sqlite3_context cx, sqlite3_value[] args){ + sqlite3_result_blob(cx, buf, 1, 3); + } + }; + + affirm( 0 == sqlite3_create_function(db, "myfunc", -1, SQLITE_UTF8, func) ); + stmt = prepare(db, "SELECT myfunc()"); + affirm( SQLITE_ROW == sqlite3_step(stmt) ); + blob = sqlite3_column_blob(stmt, 0); + affirm(3 == blob.length); + i = 0; + total = 0; + for(byte b : blob){ + affirm( i<=3 ); + affirm(b == buf.get(1 + i++)); + total += b; + } + affirm( SQLITE_DONE == sqlite3_step(stmt) ); + sqlite3_finalize(stmt); + affirm(total == expectTotal); + sqlite3_close_v2(db); } @@ -1924,9 +1947,10 @@ public class Tester1 implements Runnable { if( forceFail ){ testMethods.add(m); } - }else if( m.isAnnotationPresent( RequiresNioBuffer.class ) + }else if( m.isAnnotationPresent( RequiresJniNio.class ) && !sqlite3_jni_supports_nio() ){ - outln("Skipping test for lack JNI nio.Buffer support: ",name,"()\n"); + outln("Skipping test for lack of JNI java.nio.ByteBuffer support: ", + name,"()\n"); ++nSkipped; }else if( !m.isAnnotationPresent( ManualTest.class ) ){ if( nThread>1 && m.isAnnotationPresent( SingleThreadOnly.class ) ){ diff --git a/manifest b/manifest index 47b34117a7..c74882a340 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C JNI:\sadd\ssqlite3_bind_nio_buffer()\sand\sinitial\stests\sfor\sbinding\sByteBuffer\sobjects\sas\sblobs\son\sJVMs\swhich\shave\sJNI\ssupport\sfor\snio\sbuffers. -D 2023-11-13T14:58:37.421 +C JNI:\sadd\ssqlite3_result_nio_buffer()\sand\stests.\sDiscover\sthat\swe\scannot\screate\ssensible\ssqlite3_column_nio_buffer()\sor\ssqlite3_value_nio_buffer()\scounterparts\sbecause\sof\sByteBuffer\sinterface\slimitations. +D 2023-11-13T18:35:37.387 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -241,8 +241,8 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3 F ext/jni/GNUmakefile f2f3a31923293659b95225e932a286af1f2287d75bf88ad6c0fd1b9d9cd020d4 F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa -F ext/jni/src/c/sqlite3-jni.c a04d0d77e7391a69f7f8ca4b38e24de59b3a8f61610f2e91698c190c07283850 -F ext/jni/src/c/sqlite3-jni.h 2848299f845d36b4b6123d360e7a4eb960d040637a10158079af49f4ded16453 +F ext/jni/src/c/sqlite3-jni.c 56ddb35bbae71123bedd003ae2bf42adae7d683717bb15ac3ed51d16e2b6c3ff +F ext/jni/src/c/sqlite3-jni.h 1f28a6a2beec13a49efdb42804926d2139f6a786558ea52c121ddf0bf39af59a F ext/jni/src/org/sqlite/jni/annotation/NotNull.java 02091a8112e33389f1c160f506cd413168c8dfacbeda608a4946c6e3557b7d5a F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 0b1879852707f752512d4db9d7edd0d8db2f0c2612316ce1c832715e012ff6ba F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca @@ -251,7 +251,7 @@ F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0b72cdff61533b564d65b63 F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759 F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca -F ext/jni/src/org/sqlite/jni/capi/CApi.java 5ef54290c17dca46d7f24001ac3b689559e1b37ee40d06b88fa5315d64863789 +F ext/jni/src/org/sqlite/jni/capi/CApi.java 1517e1f5fc53001b2cb7229a427d33747163f8f37348368fe7c3e14edbb9c512 F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 57e2d275dcebe690b1fc1f3d34eb96879b2d7039bce30b563aee547bf45d8a8b F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 5bfa226a8e7a92e804fd52d6e42b4c7b875fa7a94f8e2c330af8cc244a8920ab @@ -269,7 +269,7 @@ F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 0d1e9afc9ff8a2adb94a155b72385 F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 09bee15aa0eedac68d767ae21d9a6a62a31ade59182a3ccbf036d6463d9e30b1 F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615 F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff2260daa7ce305ff9b5fafd64153a7a28e9d8f000a815f -F ext/jni/src/org/sqlite/jni/capi/Tester1.java 4ec21172917f641787767443f418854329bf9b9779807b644e000dac1ec77013 +F ext/jni/src/org/sqlite/jni/capi/Tester1.java 4d460ccce50e7ef4ce8e1ab5d46ceca70834a798d8a2233c93f4bede9deb6683 F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723 F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java c8bdf7848e6599115d601bcc9427ff902cb33129b9be32870ac6808e04b6ae56 F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 22d365746a78c5cd7ae10c39444eb7bbf1a819aad4bb7eb77b1edc47773a3950 @@ -2139,8 +2139,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0832f9a8e9f574b157c791c5cddc73aff7b2ff403509f5d78f310494d4a7f93d -R 7292f27854539ba720bc8a8fcd0c273f +P b10ce1ef82d84726fbf6a8f624d6530f84fefb505f7868b4a0ea910fed7a877f +R 2f05bfa531dff8515ddabab7cc0cd5f1 U stephan -Z 1881d5bf6b59348a7807616e897efc0f +Z acc87a8d47162ab6fa5eb71b4d2c3712 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 693d450f8a..b2e5d6bd1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b10ce1ef82d84726fbf6a8f624d6530f84fefb505f7868b4a0ea910fed7a877f \ No newline at end of file +44b4df01ff86841fb85b6295cbada422c6ba8a32a420a2e840e2d607b6c90164 \ No newline at end of file