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
CODEC-314: Fix possible IndexOutOfBoundsException thrown by PercentCodec.insertAlwaysEncodeChars() method #222
CODEC-314: Fix possible IndexOutOfBoundsException thrown by PercentCodec.insertAlwaysEncodeChars() method #222
Conversation
Let's just have ONE PR instead of one-liner PRs. Especially since these all claim to fix the exact same kind of issue. Also, you MUST provide a matching test. |
Hi, I have added unit test. I am not sure about combining the PRs since they are opened as 4 different issues in the JIRA. |
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.
Hello @arthurscchan
Please see my comment.
src/test/java/org/apache/commons/codec/net/PercentCodecTest.java
Outdated
Show resolved
Hide resolved
0891e19
to
9845bcc
Compare
In this case, I don't care about mapping PRs to JIRA 1-1. YMMV ;-) I care about making my life easier ;-) |
Hi @arthurscchan, Please help me understand why we need this PR because at first glance this PR could be making the use case worse IMO:
Or am I missing something? |
Hi @garydgregory, In my understanding, the constructor of PecentCodec calls the |
If you want, I don't mind combining all the PRs together, not sure if it is more messy to handle. Although they are throwing similar exceptions, I would say the reason is not too similar IMO. |
@arthurscchan |
Well, at this point, I commented on all PRs, so we might as well leave it as is. |
9845bcc
to
46991d0
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #222 +/- ##
============================================
- Coverage 92.27% 92.23% -0.05%
- Complexity 1742 1747 +5
============================================
Files 67 67
Lines 4584 4595 +11
Branches 709 712 +3
============================================
+ Hits 4230 4238 +8
- Misses 242 243 +1
- Partials 112 114 +2 ☔ View full report in Codecov by Sentry. |
Hi @arthurscchan |
Hi @garydgregory, I think it is a different case. The invalid bytes are provided through constructor, it is only used for the initial setting of the PercentCodec object to set which bytes are to be encoded during the encode or decode method. Thus if we initialise the PercentCodec with a byte array contains invalid bytes, it just mean that the encode method will not encode that byte. It does not affect the encode and decode process at all. Thus the encode / decode method round trip won't be affected and the result is the same as the original input. Maybe I could add a round trip call and ensure the result are the same in the test case. |
Hi @arthurscchan |
Hi @garydgregory, OK. Sorry for not considering in that direction. I will change the code in this PR to wrap around the possible IndexOutOfBoundException in an EncoderException, to at least decrease the change of "unpexected" input thrown directly from the constructor. I will also change a bit on the javadoc comments, mentioning that EncoderException will be thrown by the ctor if invalid bytes exist in the provided byte array. That maybe a better approach. Thanks for your comments. |
TY @arthurscchan |
Signed-off-by: Arthur Chan <arthur.chan@adalogics.com>
Signed-off-by: Arthur Chan <arthur.chan@adalogics.com>
f0859ae
to
e193cd6
Compare
Hi @garydgregory, thanks for your comments and suggestions. I will surely keep that 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.
Hi @arthurscchan
Rethought this a bit, please see my comment.
*/ | ||
public PercentCodec(final byte[] alwaysEncodeChars, final boolean plusForSpace) { | ||
public PercentCodec(final byte[] alwaysEncodeChars, final boolean plusForSpace) throws EncoderException { |
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.
Hi @arthurscchan
Now that I look at this again, it doesn't make sense to me, this seems like the exact use case for an IllegalArgumentException
. In addition, the constructor does not encode anything, so an EncoderException
really does not make sense IMO.
I propose:
diff --git a/src/main/java/org/apache/commons/codec/net/PercentCodec.java b/src/main/java/org/apache/commons/codec/net/PercentCodec.java
index 8e51538..df623df 100644
--- a/src/main/java/org/apache/commons/codec/net/PercentCodec.java
+++ b/src/main/java/org/apache/commons/codec/net/PercentCodec.java
@@ -231,6 +231,9 @@
* @param b the byte that is candidate for min and max limit
*/
private void insertAlwaysEncodeChar(final byte b) {
+ if (b < 0) {
+ throw new IllegalArgumentException("byte must be >= 0");
+ }
this.alwaysEncodeChars.set(b);
if (b < alwaysEncodeCharsMin) {
alwaysEncodeCharsMin = b;
diff --git a/src/test/java/org/apache/commons/codec/net/PercentCodecTest.java b/src/test/java/org/apache/commons/codec/net/PercentCodecTest.java
index 34f8ecb..a537efb 100644
--- a/src/test/java/org/apache/commons/codec/net/PercentCodecTest.java
+++ b/src/test/java/org/apache/commons/codec/net/PercentCodecTest.java
@@ -106,6 +106,12 @@
}
@Test
+ public void testInvalidByte() throws Exception {
+ final byte[] invalid = { (byte) -1, (byte) 'A' };
+ assertThrows(IllegalArgumentException.class, () -> new PercentCodec(invalid, true));
+ }
+
+ @Test
public void testPercentEncoderDecoderWithNullOrEmptyInput() throws Exception {
final PercentCodec percentCodec = new PercentCodec(null, true);
assertNull(percentCodec.encode(null), "Null input value encoding test");
WDYT?
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 think it is a better changes and interpretation of the exceptions. I will change it accordingly.
@garydgregory
Closing: Done. |
PercentCodec.insertAlwaysEncodeChars() method #222
@garydgregory Sorry I am bit busy and did not handle that last week. Thanks for fixing that for me. |
This fixes a possible IndexOutOfBoundsException in src/main/java/org/apache/commons/codec/net/PercentCodec.java thrown by
PercentCodec.insertAlwaysEncodeChars()
method if the initial byte array contains negative bytes which are used as index for the BitSet.This PR adds a conditional check to ensure only valid bytes (positive or zero) are processed.
We found this bug using fuzzing by way of OSS-Fuzz. It is reported at https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64362.