Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix index limits in Bech32 mutation tests #338

Merged
merged 11 commits into from
May 29, 2019

Conversation

jonathanknowles
Copy link
Member

Issue Number

#331 and #332

Overview

This PR fixes a few issues introduced by PR #332:

  1. The function chooseWithinDataPart gives us an incorrect upper bound for the index in the insertion, mutation, and deletion tests. These tests should actually limit their indices in subtly different ways:

    Test Index Upper Bound Notes
    Insertion T.length originalString (we can insert after the end of a string)
    Mutation T.length originalString - 1
    Deletion T.length originalString - 1
    Swapping T.length originalString - 2 (we swap with the character to the right)
  2. Limiting our choice of index to just the data part means that our tests are weaker than they could be, as we're not testing across the full length of a Bech32 string. Since the checksum is a function of both the data part and the human readable part, it makes sense to mutate all parts of the string.

  3. In particular, we do need to check for mixed case characters at all locations in the string, and not just in the data part. According to the spec:

    Decoders MUST NOT accept strings where some characters are uppercase and some are lowercase (such strings are referred to as mixed case strings).

Changes

I have:

  • Corrected the upper bounds for the insertion, mutation, and deletion tests.
  • Adjusted all tests to test across the full length of a Bech32 string, and not just the data part.
  • Introduced a type Bech32Char, which represents the full range of characters allowed in a Bech32 string. We use this type when generating mutations.

This type represents the set of all characters permitted to appear
within a Bech32 string, including:

 * characters that can appear within the human-readable part.
 * the separator character.
 * characters that can appear within the data part.
Make sure that we have coverage for:

1. Insertions before the start of the string.
2. Insertions in the middle of the string.
3. Insertions after the end of the string.

Additionally, choose from the full range of Bech32 characters, and not just
those allowed in the data part of the string.
Additionally, choose from the full range of Bech32 characters, and not just
those allowed in the data part of the string.
This name is consistent with `Bech32Char`.

Also rename related functions.
(result `shouldBe` Left
(StringToDecodeContainsInvalidChars
[CharPosition index]))
(result `shouldSatisfy` isLeft)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we wanted to be slightly more precise, we could write:

let result = Bech32.decode corruptedString
let resultMatchesExpectations = \case 
        Left StringToDecodeTooShort                 -> True   
        Left StringToDecodeMissingSeparatorChar     -> True   
        Left (StringToDecodeContainsInvalidChars _) -> True   
        _                                           -> False  
return $ counterexample description $ 
    corruptedString /= originalString ==> 
        (T.length corruptedString === T.length originalString)
        .&&.  
        (result `shouldSatisfy` resultMatchesExpectations) 

Copy link
Member Author

@jonathanknowles jonathanknowles May 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @KtorZ

@jonathanknowles I don't think there was an issue here to be honest.... The tests were already limiting their indexes to the worst case (swapping)....

From my understanding, after the merging PR #332, the test suite no longer tests:

  • deletion of characters from the ends of strings.
  • mutation of characters at the ends of strings.
  • insertion of characters at the ends of strings.

This is because the relevant indices will no longer be generated.

Before merging of PR #332, these cases were tested (as far as I can tell). Was there any reason for us to remove coverage of these cases?

@KtorZ
Copy link
Member

KtorZ commented May 29, 2019

@jonathanknowles I don't think there was an issue here to be honest.... The tests were already limiting their indexes to the worst case (swapping).... I mean.. We've already spent A LOT of hours on this encoder / decoder and testing is already very reasonable on that module.

May we please... stop? For any further ideas of improvement, use the blackboard and describe what could be done.

jonathanknowles and others added 2 commits May 29, 2019 08:52
It's possible to change the case of a given character of a Bech32 string
and yet not produce a mixed-case string.

In such cases, we can't expect that the `decode` function will fail with
a `StringToDecodeHasMixedCase` error.

To prevent the test failing, we change the precondition to actually
check that the string is in mixed case.
…ix-mixed-case-test

Strengthen the precondition for the Bech32 mixed-case mutation test.
@jonathanknowles jonathanknowles merged commit 76062e3 into master May 29, 2019
@iohk-bors iohk-bors bot deleted the jonathanknowles/bech32-fix-index-limits branch May 29, 2019 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants