[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn commit: r1705391 - in /subversion/trunk: ./ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_diff/ subversion/libsvn_fs_x/ subversion/tests/cmdline/ subversion/tests/libsvn_diff/

From: Daniel Shahaf <d.s_at_daniel.shahaf.name>
Date: Sun, 27 Sep 2015 00:46:47 +0000

Bert Huijben wrote on Sat, Sep 26, 2015 at 10:06:15 +0200:
> A few comments inline.
>

Thanks for the review.

> > + /* ### This is currently not parsed out of "index" lines (where it
> > + * ### serves as an assertion of the executability state, without
> > + * ### changing it). */
> > + svn_tristate_t old_executable_p;
> > + svn_tristate_t new_executable_p;
> > } svn_patch_t;
>
> I'm not sure if we should leave this comment here in the long term...

*shrug* We could put it elsewhere.

> > +/* Return whether the svn:executable proppatch and the out-of-band
> > + * executability metadata contradict each other, assuming both are present.
> > + */
> > +static svn_boolean_t
> > +contradictory_executability(const svn_patch_t *patch,
> > + const prop_patch_target_t *target)
> > +{
> > + switch (target->operation)
> > + {
> > + case svn_diff_op_added:
> > + return patch->new_executable_p == svn_tristate_false;
> > +
> > + case svn_diff_op_deleted:
> > + return patch->new_executable_p == svn_tristate_true;
> > +
> > + case svn_diff_op_unchanged:
> > + /* ### Can this happen? */
> > + return (patch->old_executable_p != svn_tristate_unknown
> > + && patch->new_executable_p != svn_tristate_unknown
> > + && patch->old_executable_p != patch->new_executable_p);
> > +
> > + case svn_diff_op_modified:
> > + /* Can't happen: the property should only ever be added or deleted,
> > + * but never modified from one valid value to another. */
> > + return (patch->old_executable_p != svn_tristate_unknown
> > + && patch->new_executable_p != svn_tristate_unknown
> > + && patch->old_executable_p == patch->new_executable_p);
>
> These can happen when the svn:executable property just changes value (E.g. from '*' to 'x'). That should not happen, but it can.

Right. So _if_ somebody had broken the "value is SVN_PROP_BOOLEAN_VALUE"
invariant, _and_ generated a diff that contains a 'old mode 0755\n new
mode 0755\n' sequence — which, although syntactically valid, wouldn't
be output by any diff program — then they will get a false positive
"Contradictory executability" hard error.

The place to handle broken invariants is at the entry point, which for
patches is parse-diff.c. Would make sense, then, for parse-diff.c to
normalize the 'old value' and 'new value' of svn_prop_is_boolean()
properties to SVN_PROP_BOOLEAN_VALUE, and for patch.c to canonicalize
the ACTUAL/WORKING property value to SVN_PROP_BOOLEAN_VALUE before
trying to apply the patch? (Example: if the property value in the
wc is "yes", and the patch says 'change the property value from "sí" to
unset', parse-diff.c will fold "yes" to "*", patch.c will fold "sí"
to "*", and the patch will apply successfully.)

> > +add_or_delete_single_line(svn_diff_hunk_t **hunk_out,
> > + const char *line,
> > + svn_patch_t *patch,
> > + svn_boolean_t add,
> > + apr_pool_t *result_pool,
> > + apr_pool_t *scratch_pool)
> > +{
> > + svn_diff_hunk_t *hunk = apr_palloc(result_pool, sizeof(*hunk));
>
> As pcalloc() would be safer here...
...
> > + hunk->leading_context = 0;
> > + hunk->trailing_context = 0;
>
> As this patch forgets to set the new booleans added on trunk to signal no EOL markers here.
>
> You might need to set one of them to true though, as I think you are trying to add a property with no end of line.

It's just a merge artifact. I'd rather just initialize the newly-added
members and leave the non-initializing allocation so cc/valgrind can
catch bugs.

I'll initialize them to FALSE for now, to plug the uninitialized memory
access. I'm not sure we need to change that to TRUE; see discussion
under the patch_tests.py hunks, below.

> > +/* Parse the 'old mode ' line of a git extended unidiff. */
> > +static svn_error_t *
> > +git_old_mode(enum parse_state *new_state, char *line, svn_patch_t
> > *patch,
> > + apr_pool_t *result_pool, apr_pool_t *scratch_pool)
> > +{
> > + SVN_ERR(parse_bits_into_executability(&patch->old_executable_p,
> > + line + STRLEN_LITERAL("old mode ")));
> > +
> > +#ifdef SVN_DEBUG
> > + /* If this assert trips, the "old mode" is neither ...644 nor ...755 . */
> > + SVN_ERR_ASSERT(patch->old_executable_p != svn_tristate_unknown);
> > +#endif
>
> I don't think we should leave these enabled even in maintainer mode.
> This will break abilities to apply diffs generated from other tools.

The purpose of the warning is to alert us that there is a syntax we
aren't handling. That's why it's for maintainers only. The assumption
is that maintainers can switch to a release build if they run into this
warning unexpectedly.

I don't think we can convert this to a warning, can we? This API
doesn't have a way to report warnings to its caller.

> (Perhaps even from older Subversion versions as I think you recently
> changed what Subversion generates itself on trunk)
>

You mean r1695384?

Personally, I think rejecting pre-r1695384 patches is _good_, since
thoes patches were simply invalid and would have gotten in the way of
assigning a meaning to the 010000 bit in the future. If we ever find
out that somebody is generating such patches, we can then relax our
parser to accept them.

> > +def patch_ambiguous_executability_contradiction(sbox):
> > + """patch ambiguous svn:executable, bad"""
> > +
> > + sbox.build(read_only=True)
> > + wc_dir = sbox.wc_dir
> > +
> > + unidiff_patch = (
> > + "Index: iota\n"
> > +
> > "===============================================================
> > ====\n"
> > + "diff --git a/iota b/iota\n"
> > + "old mode 100755\n"
> > + "new mode 100644\n"
> > + "Property changes on: iota\n"
> > + "-------------------------------------------------------------------\n"
> > + "Added: svn:executable\n"
> > + "## -0,0 +1 ##\n"
> > + "+*\n"
> > + )
>
> This specifies the addition of the svn:executable property with the non canonical "*\n" value. Is this really what you want to test?
> I think the actual property set code will change it to the proper value, but I would say you need the " \ No newline at end of property" marker here.
>
> The generated patchfile doesn't need it, but it does need the boolean to note the same thing.
>

I don't understand. If the generated patchfile doesn't need the \ line,
then that is a great reason not to have it here, so that we test parsing
the output svn currently generates.

In any case, patch_dir_properties() and patch_add_symlink() are written
without a \ line. I'll make one of them use a \ line so both variants
are tested.

Cheers,

Daniel
Received on 2015-09-27 02:47:04 CEST

This is an archived mail posted to the Subversion Dev mailing list.