static svn_error_t * test_stream_base64(apr_pool_t *pool) { svn_stream_t *stream; svn_stringbuf_t *actual = svn_stringbuf_create_empty(pool); svn_stringbuf_t *expected = svn_stringbuf_create_empty(pool); int i; static const char *strings[] = { "fairly boring test data... blah blah", "A", "abc", "012345679", NULL }; stream = svn_stream_from_stringbuf(actual, pool); stream = svn_base64_decode(stream, pool); stream = svn_base64_encode(stream, pool); for (i = 0; strings[i]; i++) { apr_size_t len = strlen(strings[i]); svn_stringbuf_appendbytes(expected, strings[i], len); SVN_ERR(svn_stream_write(stream, strings[i], &len)); } SVN_ERR(svn_stream_close(stream)); SVN_TEST_STRING_ASSERT(actual->data, expected->data); return SVN_NO_ERROR; }
/* This test doesn't test much unless run under valgrind when it triggers the problem reported here: http://mail-archives.apache.org/mod_mbox/subversion-dev/201202.mbox/%[email protected]%3E The two data writes caused the base 64 code to allocate a buffer that was a byte short but exactly matched a stringbuf blocksize. That meant the stringbuf didn't overallocate and a write beyond the end of the buffer occurred. */ static svn_error_t * test_stream_base64_2(apr_pool_t *pool) { const struct data_t { const char *encoded1; const char *encoded2; } data[] = { { "MTI", "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "A23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "B23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "C23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "D23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "E23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "F23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "G23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "H23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "I23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D123456789E" "623456789A123456789B123456789C123456789D123456789E" "723456789A123456789B123456789C123456789D123456789E" "823456789A123456789B123456789C123456789D123456789E" "923456789A123456789B123456789C123456789D123456789E" "J23456789A123456789B123456789C123456789D123456789E" "123456789A123456789B123456789C123456789D123456789E" "223456789A123456789B123456789C123456789D123456789E" "323456789A123456789B123456789C123456789D123456789E" "423456789A123456789B123456789C123456789D123456789E" "523456789A123456789B123456789C123456789D12345" }, { NULL, NULL, }, }; int i; for (i = 0; data[i].encoded1; i++) { apr_size_t len1 = strlen(data[i].encoded1); svn_stringbuf_t *actual = svn_stringbuf_create_empty(pool); svn_stringbuf_t *expected = svn_stringbuf_create_empty(pool); svn_stream_t *stream = svn_stream_from_stringbuf(actual, pool); stream = svn_base64_encode(stream, pool); stream = svn_base64_decode(stream, pool); SVN_ERR(svn_stream_write(stream, data[i].encoded1, &len1)); svn_stringbuf_appendbytes(expected, data[i].encoded1, len1); if (data[i].encoded2) { apr_size_t len2 = strlen(data[i].encoded2); SVN_ERR(svn_stream_write(stream, data[i].encoded2, &len2)); svn_stringbuf_appendbytes(expected, data[i].encoded2, len2); } SVN_ERR(svn_stream_close(stream)); } return SVN_NO_ERROR; }
int main(int argc, char **argv) { svn_error_t *err; apr_status_t apr_err; apr_file_t *source_file; apr_file_t *target_file; svn_stream_t *stdout_stream; svn_txdelta_stream_t *txdelta_stream; svn_txdelta_window_handler_t svndiff_handler; svn_stream_t *encoder; void *svndiff_baton; apr_pool_t *pool; int version = 0; if (argc < 3) { printf("usage: %s source target [version]\n", argv[0]); exit(0); } apr_initialize(); pool = svn_pool_create(NULL); apr_err = apr_file_open(&source_file, argv[1], (APR_READ | APR_BINARY), APR_OS_DEFAULT, pool); if (apr_err) { fprintf(stderr, "unable to open \"%s\" for reading\n", argv[1]); exit(1); } apr_err = apr_file_open(&target_file, argv[2], (APR_READ | APR_BINARY), APR_OS_DEFAULT, pool); if (apr_err) { fprintf(stderr, "unable to open \"%s\" for reading\n", argv[2]); exit(1); } if (argc == 4) version = atoi(argv[3]); svn_txdelta(&txdelta_stream, svn_stream_from_aprfile(source_file, pool), svn_stream_from_aprfile(target_file, pool), pool); err = svn_stream_for_stdout(&stdout_stream, pool); if (err) svn_handle_error2(err, stdout, TRUE, "svndiff-test: "); #ifdef QUOPRINT_SVNDIFFS encoder = svn_quoprint_encode(stdout_stream, pool); #else encoder = svn_base64_encode(stdout_stream, pool); #endif /* use maximum compression level */ svn_txdelta_to_svndiff3(&svndiff_handler, &svndiff_baton, encoder, version, 9, pool); err = svn_txdelta_send_txstream(txdelta_stream, svndiff_handler, svndiff_baton, pool); if (err) svn_handle_error2(err, stdout, TRUE, "svndiff-test: "); apr_file_close(source_file); apr_file_close(target_file); svn_pool_destroy(pool); apr_terminate(); exit(0); }