This has been fixed!
This took a while to triage because it touched a ton of different functions I wasn't used to poking around in, including the post history and post history revision generation.
The Bug
The source of the problem was a function that checked if the post history entry had any content changes. This is a function that effectively hasn't been touched since Atwood first committed it 12 years ago. The original function was:
public bool HasContent()
{
return !(string.IsNullOrEmpty(Tags) && string.IsNullOrEmpty(Title) && !string.IsNullOrEmpty(Body));
}
This function was then modified to add a new component involving checking for some new feature that we haven't shipped. It looked similar to this:
public bool HasContent()
{
return !(NewFeature != NewFeature.None && string.IsNullOrEmpty(Tags) && string.IsNullOrEmpty(Title) && !string.IsNullOrEmpty(Body));
}
This function is kinda hard to read though - applying De Morgan's law we can negate the entire statement to make it a little more readable:
public bool HasContent()
{
return NewFeature == NewFeature.None || !string.IsNullOrEmpty(Tags) || !string.IsNullOrEmpty(Title) || !string.IsNullOrEmpty(Body);
}
The bug here is now pretty clear - we consider anything that has the new feature set to none as having its content changed. Because NewFeature
was an enum
, we have the behavior of default(NewFeature) == 0 == NewFeature.None
, which meant that all post history items had this value set to NewFeature.None
. This meant that all post history items were now considered to have content.
There's a function that transforms the list of post history entries to revision entries, and it depended on this check. With this buggy behavior, it started doing unpredictable things like displaying extra revisions for reopens or showing weird things in the post's timeline. Lots of other things depend of this content check working, so I'm certain that other features on the site were impacted too.
The approximate period of time this bug was live was:
- Start: 2021-09-14 13:50 UTC
- End: 2021-09-15 15:31 UTC
Next Steps
- status-planned I've added items on our technical debt backlog to take care of adding tests/refactoring the
HasContent
function, as well as adding tests for the dependencies of HasContent
that were demonstrating the buggy behavior. This bug is something that automated tests can and should catch - we're just missing test coverage here.
- status-completed During this buggy period, the revision counts were off. Some post history items were being counted as a revision, so this threw off anything that referenced a revision by its number. We have performed a network-wide fix of this data that fixes rollbacks pointing at invalid revisions (there were less than 10 instances of this across the network).
!=
instead of==
. We won't be able to push this tonight because we need to make sure that fixing this doesn't have unintended consequences elsewhere, but we'll be able to get it fixed ASAP tomorrow. Thank you so much for reporting this bug.!=
to==
: $1.00. Cost of knowing which!=
to change: $999.00."