/** * Parse the string at *STR as an revision and save the result in * *OPT_REV. After returning successfully, *STR points at next * character in *STR where further parsing can be done. */ static svn_error_t * string_to_opt_revision(svn_opt_revision_t *opt_rev, const char **str, apr_pool_t *pool) { const char *s = *str; SVN_ERR_ASSERT(opt_rev); while (*s && *s != ':') ++s; /* Should not find a \0. */ if (!*s) return svn_error_createf (SVN_ERR_INCORRECT_PARAMS, NULL, _("Found an unexpected \\0 in the file external '%s'"), *str); if (0 == strncmp(*str, "HEAD:", 5)) { opt_rev->kind = svn_opt_revision_head; } else { svn_revnum_t rev; const char *endptr; SVN_ERR(svn_revnum_parse(&rev, *str, &endptr)); SVN_ERR_ASSERT(endptr == s); opt_rev->kind = svn_opt_revision_number; opt_rev->value.number = rev; } *str = s + 1; return SVN_NO_ERROR; }
/* Convert the C string in *TEXT to a revision number and return it in *REV. * Overflows, negative values other than -1 and terminating characters other * than 0x20 or 0x0 will cause an error. Set *TEXT to the first char after * the initial separator or to EOS. */ static svn_error_t * parse_revnum(svn_revnum_t *rev, const char **text) { const char *string = *text; if ((string[0] == '-') && (string[1] == '1')) { *rev = SVN_INVALID_REVNUM; string += 2; } else { SVN_ERR(svn_revnum_parse(rev, string, &string)); } if (*string == ' ') ++string; else if (*string != '\0') return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Invalid character in revision number")); *text = string; return SVN_NO_ERROR; }
static svn_error_t * test_revnum_parse(apr_pool_t *pool) { const char **t; const char *failure_tests[] = { "", "abc", "-456", NULL }; const char *success_tests[] = { "0", "12345", "12345ABC", NULL }; /* These tests should succeed. */ for (t=success_tests; *t; ++t) { svn_revnum_t rev = -123; const char *endptr; /* Do one test with a NULL end pointer and then with non-NULL pointer. */ SVN_ERR(svn_revnum_parse(&rev, *t, NULL)); SVN_ERR(svn_revnum_parse(&rev, *t, &endptr)); if (-123 == rev) return svn_error_createf (SVN_ERR_TEST_FAILED, NULL, "svn_revnum_parse('%s') should change the revision for " "a good string", *t); if (endptr == *t) return svn_error_createf (SVN_ERR_TEST_FAILED, NULL, "End pointer for svn_revnum_parse('%s') should not " "point to the start of the string", *t); } /* These tests should fail. */ for (t=failure_tests; *t; ++t) { svn_revnum_t rev = -123; const char *endptr; /* Do one test with a NULL end pointer and then with non-NULL pointer. */ svn_error_t *err = svn_revnum_parse(&rev, *t, NULL); svn_error_clear(err); err = svn_revnum_parse(&rev, *t, &endptr); if (! err) return svn_error_createf (SVN_ERR_TEST_FAILED, NULL, "svn_revnum_parse('%s') succeeded when it should " "have failed", *t); svn_error_clear(err); if (-123 != rev) return svn_error_createf (SVN_ERR_TEST_FAILED, NULL, "svn_revnum_parse('%s') should not change the revision " "for a bad string", *t); if (endptr != *t) return svn_error_createf (SVN_ERR_TEST_FAILED, NULL, "End pointer for svn_revnum_parse('%s') does not " "point to the start of the string", *t); } return SVN_NO_ERROR; }
/* Conforms to svn_ra_serf__xml_closed_t */ static svn_error_t * item_closed(svn_ra_serf__xml_estate_t *xes, void *baton, int leaving_state, const svn_string_t *cdata, apr_hash_t *attrs, apr_pool_t *scratch_pool) { list_context_t *list_ctx = baton; if (leaving_state == AUTHOR) { /* For compatibility with liveprops, current servers will not use * base64-encoding for "binary" user names bu simply drop the * offending control chars. * * We might want to switch to revprop-style encoding, though, * and this is the code to do that. */ const char *encoding = svn_hash_gets(attrs, "encoding"); if (encoding) { /* Check for a known encoding type. This is easy -- there's only one. */ if (strcmp(encoding, "base64") != 0) { return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Unsupported encoding '%s'"), encoding); } cdata = svn_base64_decode_string(cdata, scratch_pool); } /* Remember until the next ITEM closing tag. */ svn_stringbuf_set(list_ctx->author_buf, cdata->data); list_ctx->author = list_ctx->author_buf->data; } else if (leaving_state == ITEM) { const char *dirent_path = cdata->data; const char *kind_word, *date, *crev, *size; svn_dirent_t dirent = { 0 }; kind_word = svn_hash_gets(attrs, "node-kind"); size = svn_hash_gets(attrs, "size"); dirent.has_props = svn_hash__get_bool(attrs, "has-props", FALSE); crev = svn_hash_gets(attrs, "created-rev"); date = svn_hash_gets(attrs, "date"); /* Convert data. */ dirent.kind = svn_node_kind_from_word(kind_word); if (size) SVN_ERR(svn_cstring_atoi64(&dirent.size, size)); else dirent.size = SVN_INVALID_FILESIZE; if (crev) SVN_ERR(svn_revnum_parse(&dirent.created_rev, crev, NULL)); else dirent.created_rev = SVN_INVALID_REVNUM; if (date) SVN_ERR(svn_time_from_cstring(&dirent.time, date, scratch_pool)); if (list_ctx->author) dirent.last_author = list_ctx->author; /* Invoke RECEIVER */ SVN_ERR(list_ctx->receiver(dirent_path, &dirent, list_ctx->receiver_baton, scratch_pool)); /* Reset buffered info. */ list_ctx->author = NULL; } return SVN_NO_ERROR; }