-
Notifications
You must be signed in to change notification settings - Fork 63
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
RUMM-2651 SR - skip new lines and spaces when obfuscating texts #1078
RUMM-2651 SR - skip new lines and spaces when obfuscating texts #1078
Conversation
return String( | ||
CharArray(text.length) { | ||
val character = text[it] | ||
if (character == CHARACTER_SPACE || character == CHARACTER_NEW_LINE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use character.isWhitespace()
to check this rather than comparing to our own hardcoded values
CharArray(text.length) { | ||
val character = text[it] | ||
if (character == ' ' || character == '\n') { | ||
character | ||
} else { | ||
'x' | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you're duplicating the production algorithm, meaning there's no way your test can fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I know, this is for all the other tests that are not exactly testing the obfuscation, is just that we are asserting everything in those. For all the obfuscation cases I added the 3 tests below.
|
||
// Then | ||
val expectedWireframe = mockButton.toTextWireframe().copy(text = fakeText) | ||
val expectedWireframe = mockTextView.toTextWireframe().copy(text = fakeExpectedText) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should also have a test in the form
val chunk1 = randomText
val chunk2 = randomText
val spacer = randomWhitespace // forge.forge.aWhitespaceString()
val input = chunk1 + spacer + chunk2
val expectedOutput = ("x" * chunk1.length) + spacer + ("x" * chunk2.length)
with this (I don't know if it exist in our repo
operator fun String.times(i: Int) {
val builder = StringBuilder(i * length)
repeat(i) {
builder.append(this)
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point
Codecov Report
@@ Coverage Diff @@
## feature/sdkv2 #1078 +/- ##
=================================================
+ Coverage 82.58% 82.65% +0.07%
=================================================
Files 346 347 +1
Lines 11157 11165 +8
Branches 1831 1832 +1
=================================================
+ Hits 9214 9228 +14
+ Misses 1381 1378 -3
+ Partials 562 559 -3
|
7bb701a
to
52fb574
Compare
52fb574
to
a19d58e
Compare
a19d58e
to
99bb53a
Compare
|
||
internal class StringObfuscator { | ||
fun obfuscate(stringValue: String): String { | ||
return String( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add TODO maybe here, saying it works only for ASCII. Also character can be non-printable Control character, but I guess we can ignore it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that I need to use another method to support all unicode characters the way they are specifying in their comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this won't work properly for Unicode still. For example, let's take the following emoji. It has a code \u1f600
, so it already exceeds char
size (which values go only up to \uffff
, because it can fit only 16 bits), so this single symbol consists of the 2 char
-> "😀".length
will give 2.
But in reality we cannot threat these char
s independently, because first is just a high surrogate and second is the low surrogate. This is how UTF-16 encoding is actually working - it will read the stream of char
of length 16 bits and decide if next char
is a lower surrogate or independent symbol.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I imagine this is the way it should work but I think this will not be a problem. The only issue would be if one of this emojis will contain one of the non printable
characters in their composition. In that case we will brake the text but I am pretty sure Character.isWhitespace()
handles that somehow or maybe these whitespace
characters are not used in emojis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point is that in case of emoji we will have xx
instead of single x
, not sure if this is what we want to achieve (I guess Character.isWhitespace()
will return false
for any surrogate).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah...I don't think this should be an issue as long as we obfuscate the texts. It will be a corner case anyway. I am going to add this explanation there though to have this in mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't say it is a corner case, because there are plenty of symbols with above \uffff
, and if we think of emojis we may find a lot of them in messenger apps, for example, and obfuscation may break formatting. Not a blocker for me, but let's acknowledge this.
assertThat(obfuscatedText).isEqualTo(fakeExpectedText) | ||
} | ||
|
||
private fun String.times(n: Int): String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems the default repeat should do the job?
fakeExpectedChunk3 + | ||
fakeExpectedChunk4 + | ||
fakeExpectedChunk5 | ||
).times(n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need times
call if it just copies the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the times
was more to generate a string with just 'x' of a given size, here it doesn't make sense
754eefd
to
94f9404
Compare
94f9404
to
c82b100
Compare
val character = stringValue[it] | ||
// Using the Character.isWhitespace() function we will support also the UNICODE | ||
// characters according with the docs. Also have in mind that in JAVA the | ||
// `char` primitive is a 16bits long number which covers all the UNICODE characters: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
char
doesn't cover all the Unicode characters. It covers BMP plain Unicode characters, but it doesn't cover Supplementary plain characters (above 0xFFFF
). When we call character.code
we just cast from char
to int
, but to get code
of the symbol from supplementary plain we need to merge 2 chars into single int.
c82b100
to
dfee181
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
|
||
@Test | ||
@TestTargetApi(Build.VERSION_CODES.N) | ||
fun `M mask String W maskString(){string with newline, Android N}`( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not maskString
, but obfuscate
. Same for other tests.
fun `M mask String W maskString(){string with newline, Android N}`( | |
fun `M mask String W obfuscate(){string with newline, Android N}`( |
09bc0c4
to
483486f
Compare
483486f
to
0d1e683
Compare
What does this PR do?
We need to skip the new lines and spaces characters when applying the obfuscation on the text values to keep the aspect ratio of the replicated text view element in the Web Player.
Motivation
What inspired you to submit this pull request?
Additional Notes
Anything else we should know when reviewing?
Review checklist (to be filled by reviewers)