/* Parse the NUL-terminated ID part at DATA and write the result into *PART. * Return TRUE if no errors were detected. */ static svn_boolean_t part_parse(svn_fs_fs__id_part_t *part, const char *data) { const char *end; /* special case: ID inside some transaction */ if (data[0] == '_') { part->revision = SVN_INVALID_REVNUM; part->number = svn__base36toui64(&data, data + 1); return *data == '\0'; } /* special case: 0 / default ID */ if (data[0] == '0' && data[1] == '\0') { part->revision = 0; part->number = 0; return TRUE; } /* read old style / new style ID */ part->number = svn__base36toui64(&data, data); if (data[0] != '-') { part->revision = 0; return *data == '\0'; } return locale_independent_strtol(&part->revision, data+1, &end); }
/* Parse the transaction id in DATA and store the result in *TXN_ID. * Return FALSE if there was some problem. */ static svn_boolean_t txn_id_parse(svn_fs_fs__id_part_t *txn_id, const char *data) { const char *end; if (!locale_independent_strtol(&txn_id->revision, data, &end)) return FALSE; data = end; if (*data != '-') return FALSE; ++data; txn_id->number = svn__base36toui64(&data, data); return *data == '\0'; }
svn_error_t * svn_fs_fs__parse_representation(representation_t **rep_p, svn_stringbuf_t *text, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { representation_t *rep; char *str; apr_int64_t val; char *string = text->data; svn_checksum_t *checksum; const char *end; rep = apr_pcalloc(result_pool, sizeof(*rep)); *rep_p = rep; SVN_ERR(parse_revnum(&rep->revision, (const char **)&string)); /* initialize transaction info (never stored) */ svn_fs_fs__id_txn_reset(&rep->txn_id); /* while in transactions, it is legal to simply write "-1" */ str = svn_cstring_tokenize(" ", &string); if (str == NULL) { if (rep->revision == SVN_INVALID_REVNUM) return SVN_NO_ERROR; return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); } SVN_ERR(svn_cstring_atoi64(&val, str)); rep->item_index = (apr_uint64_t)val; str = svn_cstring_tokenize(" ", &string); if (str == NULL) return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); SVN_ERR(svn_cstring_atoi64(&val, str)); rep->size = (svn_filesize_t)val; str = svn_cstring_tokenize(" ", &string); if (str == NULL) return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); SVN_ERR(svn_cstring_atoi64(&val, str)); rep->expanded_size = (svn_filesize_t)val; /* Read in the MD5 hash. */ str = svn_cstring_tokenize(" ", &string); if ((str == NULL) || (strlen(str) != (APR_MD5_DIGESTSIZE * 2))) return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_md5, str, scratch_pool)); memcpy(rep->md5_digest, checksum->digest, sizeof(rep->md5_digest)); /* The remaining fields are only used for formats >= 4, so check that. */ str = svn_cstring_tokenize(" ", &string); if (str == NULL) return SVN_NO_ERROR; /* Read the SHA1 hash. */ if (strlen(str) != (APR_SHA1_DIGESTSIZE * 2)) return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1, str, scratch_pool)); rep->has_sha1 = checksum != NULL; memcpy(rep->sha1_digest, checksum->digest, sizeof(rep->sha1_digest)); /* Read the uniquifier. */ str = svn_cstring_tokenize("/", &string); if (str == NULL) return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); SVN_ERR(svn_fs_fs__id_txn_parse(&rep->uniquifier.noderev_txn_id, str)); str = svn_cstring_tokenize(" ", &string); if (str == NULL || *str != '_') return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); ++str; rep->uniquifier.number = svn__base36toui64(&end, str); if (*end) return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); return SVN_NO_ERROR; }