668 Commits

Author SHA1 Message Date
Norman Maurer
b14dfbb74c
FastLzFrameDecoder should use allocator to allocate output buffer (#11499)
Motivation:

FastLzFrameDecoder currently not use the allocator to alocate the output buffer. This means that if you use the PooledByteBufAllocator you still can't make use of the pooling. Beside this the decoder also does an uncessary memory copy when no compression is used.

Modifications:

- Allocate the output buffer via the allocator
- Don't allocate and copy if we handle an uncompressed chunk
- Make use of ByteBufChecksum for a few optimizations when running on a recent JDK

Result:

Less allocations when using FastLzFrameDecoder
2021-07-21 22:09:12 +02:00
skyguard1
3859805126
Add StringDecoder test (#11496)
Motivation:

There is no test case of `StringDecoder` here

Modification:

Need to add `StringDecoder` test case

Result:

Added test case of `StringDecoder`

Signed-off-by: xingrufei <xingrufei@sogou-inc.com>
Co-authored-by: xingrufei <xingrufei@sogou-inc.com>
Co-authored-by: Norman Maurer <norman_maurer@apple.com>
2021-07-21 14:31:14 +02:00
Norman Maurer
26cdfe2cde
Add PromiseNotifier static method which takes care of cancel propagation (#11494)
Motivation:

At the moment we not correctly propagate cancellation in some case when we use the PromiseNotifier.

Modifications:

- Add PromiseNotifier static method which takes care of cancellation
- Add unit test
- Deprecate ChannelPromiseNotifier

Result:

Correctly propagate cancellation of operation

Co-authored-by: Nitesh Kant <nitesh_kant@apple.com>
2021-07-21 13:37:32 +02:00
Aayush Atharva
7ec198ddf9
Fix JavaDoc and Run Brotli tests on Windows (#11468)
Motivation:
JavaDoc of StandardCompressionOptions should point towards public methods. Also, Brotli tests were failing on Windows.

Modification:
Fixed JavaDoc and enabled Brotli tests on Windows.

Result:
Better JavaDoc and Brotli tests will run on Windows

Co-authored-by: Norman Maurer <norman_maurer@apple.com>
2021-07-13 16:24:58 +02:00
skyguard1
6ce36f1909
Add zstd http content compression support (#11470)
Motivation:

netty needs to support zstd content-encoding http content compression

Modification:

Add ZstdOptions, and modify HttpContentCompressor and CompressorHttp2ConnectionEncoder to support zstd compression

Result:

netty supports zstd http content compression

Signed-off-by: xingrufei <xingrufei@sogou-inc.com>
2021-07-12 08:49:04 +02:00
Aayush Atharva
fef761d03e
Introduce BrotliEncoder (#11256)
Motivation:
Currently, Netty only has BrotliDecoder which can decode Brotli encoded data. However, BrotliEncoder is missing which will encode normal data to Brotli encoded data.

Modification:
Added BrotliEncoder and CompressionOption

Result:
Fixes #6899.

Co-authored-by: Norman Maurer <norman_maurer@apple.com>
2021-07-08 11:51:27 +02:00
skyguard1
266c987339
[Feature] Add zstd encoder (#11437)
Motivation:

As discussed in #10422, ZstdEncoder can be added separately

Modification:

Add ZstdEncoder separately

Result:

netty supports ZSTD with ZstdEncoder

Signed-off-by: xingrufei <xingrufei@sogou-inc.com>
Co-authored-by: xingrufei <xingrufei@sogou-inc.com>
2021-07-06 14:57:09 +02:00
Norman Maurer
20e4ccbd33
Skip Brotli related tests on platforms which not support Brotli (#11435)
Motivation:

The native module is not yet available on aarch64 Mac / Windows thus causing tests in codec/ to fail (specifically all the Brotli ones, since the module could not be loaded).

Modification:

Disable Brotli tests when platform is not supported

Result:

Tests under codec/ now pass under Mac/aarch64 and Windows/aarch64
2021-07-01 09:59:24 +02:00
Tamara Braun
194a81ff4f
Fix Buffer Overflow During Lz4FrameEncoder Close (#11429)
Motivation:

We failed to account for the last header when estimating the buffer
size. If the data does not compress enough to make space for the
last header we would exceed the ByteBuf's capacity.

Modifications:

Call #ensureWritable with appropriate capacity for footer ByteBuf
befor writing footer.

Result:

If there is not enough space left in the buffer, the buffer will be
expanded.
2021-06-30 18:47:07 +02:00
Norman Maurer
3716575102
Migrate codec to junit5 (#11426) (#11430)
Motivation:

We should update to use junit5 in all modules.

Modifications:

Adjust codec tests to use junit5

Result:

Part of https://github.com/netty/netty/issues/10757
2021-06-30 14:12:50 +02:00
Norman Maurer
0d5774a82b
Make all compression codecs support buffers that don't have arrays (#11383) (#11387)
Motivation:
Various compression codecs are currently hard-coded to only support buffers that are backed by byte-arrays that they are willing to expose.
This is efficient for most of the codecs, but compatibility suffers, as we are not able to freely choose our buffer implementations when compression codecs are involved.

Modification:
Add code to the compression codecs, that allow them to handle buffers that don't have arrays.
For many of the codecs, this unfortunately involves allocating temporary byte-arrays, and copying back-and-forth.
We have to do it that way since some codecs can _only_ work with byte-arrays.
Also add tests to verify that this works.

Result:
It is now possible to use all of our compression codecs with both on-heap and off-heap buffers.
The default buffer choice has not changed, however, so performance should be unaffected.

Co-authored-by: Chris Vest <christianvest_hansen@apple.com>
2021-06-15 08:04:44 +02:00
Riley Park
5e71336ffb Migrate codec tests to JUnit 5 (#11306)
Motivation:

JUnit 5 is more expressive, extensible, and composable in many ways, and it's better able to run tests in parallel.

Modifications:

Use JUnit5 in tests

Result:

Related to https://github.com/netty/netty/issues/10757
2021-05-26 14:11:12 +02:00
Stephane Landelle
400858cd5e
Introduce BrotliDecoder (#10960)
Motivation:

Netty lacks client side support for decompressing Brotli compressed response bodies.

Modification:

* Introduce optional dependency to brotli4j by @hyperxpro. It will be up to the user to provide the brotli4j libraries for the target platform in the classpath. brotli4j is currently available for Linux, OSX and Windows, all for x86 only.
* Introduce BrotliDecoder in codec module
* Plug it onto `HttpContentDecompressor` for HTTP/1 and `DelegatingDecompressorFrameListener` for HTTP/2
* Add test in `HttpContentDecoderTest`
* Add `BrotliDecoderTest` that doesn't extend `AbstractDecoderTest` that looks flaky

Result:

Netty now support decompressing Brotli compressed response bodies.
2021-05-10 15:25:24 +02:00
chenqwwq
b8a5148569
Simplify ByteToMessageDecoder#callDecode (#11224)
Motivation:
After the if case, outSize is always 0, so we can simplify the code.

Modification:
Simplify code by not updating and using `isEmpty()`.

Result:
Clearer than before
2021-05-07 11:37:30 +02:00
Boris Unckel
acd9b383bc
Utilize i.n.u.internal.ObjectUtil to assert Preconditions (codec) (#11170) (#11179)
Motivation:

NullChecks resulting in a NullPointerException or IllegalArgumentException, numeric ranges (>0, >=0) checks, not empty strings/arrays checks must never be anonymous but with the parameter or variable name which is checked. They must be specific and should not be done with an "OR-Logic" (if a == null || b == null) throw new NullPointerEx.

Modifications:

* import static relevant checks
* Replace manual checks with ObjectUtil methods

Result:

All checks needed are done with ObjectUtil, some exception texts are improved.

Fixes #11170
2021-04-22 10:57:40 +02:00
Chris Vest
28d4154fff
Fix hash collision handling in DefaultHeaders iterator remove (#11028)
Motivation:
If two different headers end up in the same hash bucket, and you are iterating the header that is not the first in the bucket, and you use the iterator to remove the first element returned from the iterator, then you would get a NullPointerException.

Modification:
Change the DefaultHeaders iterator remove method, to re-iterate the hash bucket and unlink the entry once found, if we don't have any existing iteration starting point.

Also made DefaultHeaders.remove0 package private to avoid a synthetic method indirection.

Result:
Removing from iterators from DefaultHeaders is now robust towards hash collisions.
2021-02-19 13:29:47 +01:00
Norman Maurer
59b3831bbc
Correctly handle fragmentation in JdkZlibDecoder (#10948)
Motivation:

We had multiple bugs in JdkZlibDecoder which could lead to decoding errors when the data was received in a fragmentated manner.

Modifications:

- Correctly handle skipping of comments
- Correctly handle footer / header decoding
- Add unit test that verifies the correct handling of fragmentation

Result:

Fixes https://github.com/netty/netty/issues/10875
2021-01-18 14:02:37 +01:00
terrarier2111
aba3cc49db
Fixed JavaDoc of LimitingByteInput (#10852)
Motivation:

I found a typo in LimitingByteInput.

Modification:

Fixed the typo in LimitingByteInput

Result:

No typo anymore in LimitingByteInput.
2020-12-10 10:30:25 +01:00
Norman Maurer
9cfe3bf5e3
Fix NPE in ByteToMessageDecoder if the user removes the handler while channelInputClosed(...) is processing the buffer. (#10817)
Motivation:

We need to carefully check for null before we pass the cumulation buffer into decodeLast as callDecode(...) may have removed the codec already and so set cumulation to null.

Modifications:

- Check for null and if we see null use Unpooled.EMPTY_BUFFEr
- Only call decodeLast(...) if callDecode(...) didnt remove the handler yet.

Result:

Fixes https://github.com/netty/netty/issues/10802
2020-11-24 14:08:32 +01:00
Norman Maurer
5ffca6ef4a
Use http in xmlns URIs to make maven release plugin happy again (#10788)
Motivation:

https in xmlns URIs does not work and will let the maven release plugin fail:

```
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.779 s
[INFO] Finished at: 2020-11-10T07:45:21Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.5.3:prepare (default-cli) on project netty-parent: Execution default-cli of goal org.apache.maven.plugins:maven-release-plugin:2.5.3:prepare failed: The namespace xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" could not be added as a namespace to "project": The namespace prefix "xsi" collides with an additional namespace declared by the element -> [Help 1]
[ERROR]
```

See also https://issues.apache.org/jira/browse/HBASE-24014.

Modifications:

Use http for xmlns

Result:

Be able to use maven release plugin
2020-11-10 10:22:35 +01:00
Artem Smotrakov
e5951d46fc
Enable nohttp check during the build (#10708)
Motivation:

HTTP is a plaintext protocol which means that someone may be able
to eavesdrop the data. To prevent this, HTTPS should be used whenever
possible. However, maintaining using https:// in all URLs may be
difficult. The nohttp tool can help here. The tool scans all the files
in a repository and reports where http:// is used.

Modifications:

- Added nohttp (via checkstyle) into the build process.
- Suppressed findings for the websites
  that don't support HTTPS or that are not reachable

Result:

- Prevent using HTTP in the future.
- Encourage users to use HTTPS when they follow the links they found in
  the code.
2020-10-23 14:44:18 +02:00
Norman Maurer
ffbddcd842
Replace deprecated Assert.assertThat(...) with MatcherAssert.assertThat(...) (#10699)
Motivation:

junit deprecated Assert.assertThat(...)

Modifications:

Use MatcherAssert.assertThat(...) as replacement for deprecated method

Result:

Less deprecation warnings
2020-10-18 14:30:52 +02:00
Artem Smotrakov
1ca7d5db81
Fix or suppress LGTM findings (#10689)
Motivation:

LGTM reports multiple issues. They need to be triaged,
and real ones should be fixed.

Modifications:
- Fixed multiple issues reported by LGTM, such as redundant conditions,
  resource leaks, typos, possible integer overflows.
- Suppressed false-positives.
- Added a few testcases.

Result:

Fixed several possible issues, get rid of false alarms in the LGTM report.
2020-10-17 09:49:44 +02:00
Artem Smotrakov
5b55ee434b
Avoid casting numbers to narrower types (#10645)
Motivation:

Avoid implicit conversions to narrower types in
AbstractMemoryHttpData and Bzip2HuffmanStageEncoder classes
reported by LGTM.

Modifications:

Updated the classes to avoid implicit casting to narrower types.
It doesn't look like that an integer overflow is possible there,
therefore no checks for overflows were added.

Result:

No warnings about implicit conversions to narrower types.
2020-10-12 09:33:47 +02:00
Chris Vest
82fa2d780a Remove javassist dependency (#10514)
Motivation:
 Avoid keeping unused dependencies around.

Modification:
 Remove all references to javassist dependency, since it does not appear to be used by anything.

Result:
 One less dependency to worry about.
2020-08-31 09:02:50 +02:00
skyguard1
9f89eb6429
Add IndexOutOfBoundsException error message (#10405)
Motivation:

We should provide details about why an IOOBE was thrown

Modification:

Add IndexOutOfBoundsException error information in io.netty.util.internal.AppendableCharSequence and io.netty.handler.codec.CodecOutputList class

Result:

Easier to debug
2020-07-16 11:37:03 +02:00
Richard Nguyen
322d96ef92
Fix date format in headers to use 2-digit day of month (#10259)
Motivation:

`Date`, `Expires`, and `Set-Cookie` headers are being generated with a 1-digit day of month,
e.g. `Sun, 6 Nov 1994 08:49:37 GMT`. RFC 2616 specifies that `Date` and `Expires` headers should
use "a fixed-length subset of that defined by RFC 1123" which includes a 2-digit day of month.
RFC6265 is lax in it's specification of the `Set-Cookie` header and permits a 2-digit day of month.

See: https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html
See: https://tools.ietf.org/html/rfc1123#page-55
See: https://tools.ietf.org/html/rfc6265#section-5.1.1

Modifications:

- Update `DateFormatter` to correctly implement RFC 2616 headers

Result:

```
Date: Sun, 06 Nov 1994 08:49:37 GMT
Expires: Sun, 06 Nov 1994 08:49:37 GMT
Set-Cookie: id=a3fWa; Expires=Sun, 06 Nov 1994 08:49:37 GMT
```
2020-05-11 08:57:17 +02:00
Piyush Goyal
79915347c6
Cleanup test case (#10232)
* Motivation:

JsonObjectDecoderTest did include 3 println(...) call which was leftover from debugging.

Modifications:

Removed println(...)

Result:

Cleanup

Co-authored-by: Norman Maurer <norman_maurer@apple.com>
2020-05-07 16:10:25 +02:00
feijermu
be28b266d5
Remove unused import in JsonObjectDecoder.java (#10213)
Motivation:

`io.netty.channel.ChannelHandler` is never used in JsonObjectDecoder.java.

Modification:

Just remove this unused import.

Result:

Make the JsonObjectDecoder.java's imports simple and clean.
2020-04-27 13:58:02 +02:00
Norman Maurer
4c9d7492fb
CodecOutputList should be recycled in a finally block (#10186)
Motivation:

To ensure we always recycle the CodecOutputList we should better do it in a finally block

Modifications:

Call CodecOutputList.recycle() in finally

Result:

Less chances of non-recycled lists. Related to https://github.com/netty/netty/issues/10183
2020-04-15 09:08:19 +02:00
水木今山
4d7d249cc3
Fix a mistake in javadoc of ReplayingDecoder (#10129)
Motivation:

In the code example of ReplayingDecoder, an input parameter List<Object> out is missing.

Modification:

Just add this parameter.

Result:

The right doc.
2020-03-23 13:09:21 +01:00
时无两丶
60cbe8b7b2
Let LzfEncoder support length aware ability. (#10082)
Motivation:

Since the LZF support non-compress and compress format, we can let LzfEncoder support length aware ability. It can let the user control compress.

Modification:

When the data length over compressThreshold, LzfEncoder use compress format to compress data. Otherwise, only use non-compress format. Whatever compress format the encoder use, the LzfDecoder can decompress data well.

Result:

Gives users control over compression capabilities
2020-03-11 21:05:22 +01:00
Norman Maurer
65b1713ce7
Update ProtocolDetectionResult to fix typo (#10086)
Motivation:

Correct a typo.

Modification:

Changed a name of a private constant variable, 'NEEDS_MORE_DATE' to 'NEEDS_MORE_DATA'

Result:

Cleanup
2020-03-05 12:42:46 +01:00
Ning Xie
a304d61b26
fix snappy crc32c checksum (#10048)
Motivation:

The Snappy crc32c checksum produced by SnappyFrameEncoder maybe failed to be validated on other languages snappy decoder, such as golang/snappy.

Modification: 

- make the 4-byte cast later after the mask operation. Because whether retaining the higher 4-7 bytes in a long java type will make difference in (checksum >> 15 | checksum << 17) + 0xa282ead8 result.

Result:

Checksum correctly calculated
2020-02-27 09:03:50 +01:00
Rich DiCroce
1543218d3e
Allow a limit to be set on the decompressed buffer size for ZlibDecoders (#9924)
Motivation:
It is impossible to know in advance how much memory will be needed to
decompress a stream of bytes that was compressed using the DEFLATE
algorithm. In theory, up to 1032 times the compressed size could be
needed. For untrusted input, an attacker could exploit this to exhaust
the memory pool.

Modifications:
ZlibDecoder and its subclasses now support an optional limit on the size
of the decompressed buffer. By default, if the limit is reached,
decompression stops and a DecompressionException is thrown. Behavior
upon reaching the limit is modifiable by subclasses in case they desire
something else.

Result:
The decompressed buffer can now be limited to a configurable size, thus
mitigating the possibility of memory pool exhaustion.
2020-01-31 12:11:06 +01:00
时无两丶
b7b6fc13b4 Close encoder when handlerRemoved. (#9950)
Motivation:

We should close encoder when `LzfEncoder` was removed from pipeline.

Modification:

call `encoder.close` when `handlerRemoved` triggered.

Result:

Close encoder to release internal buffer.
2020-01-14 10:51:30 +01:00
Nick Hill
1d22fbd78c Other ByteToMessageDecoder streamlining (#9891)
Motivation

This PR is a reduced-scope replacement for #8931. It doesn't include the
changes related to how/when discarding read bytes is done, which we plan
to address in subsequent updates.

Modifications

- Avoid copying bytes in COMPOSITE_CUMULATOR in all cases, performing a
shallow copy where necessary; also guard against (unusual) case where
input buffer is composite with writer index != capacity
- Ensure we don't pass a non-contiguous buffer when MERGE_CUMULATOR is
used
- Manually inline some calls to ByteBuf#writeBytes(...) to eliminate
redundant checks and reduce stack depth

Also includes prior minor review comments from @trustin

Result

More correct handling of merge/composite cases and
more efficient handling of composite case.
2019-12-23 08:54:31 +01:00
Scott Mitchell
ee7027288e
ByteToMessageDecoder Cumulator improments (#9877)
Motivation:
ByteToMessageDecoder's default MERGE_CUMULATOR will allocate a new buffer and
copy if the refCnt() of the cumulation is > 1. However this is overly
conservative because we maybe able to avoid allocate/copy if the current
cumulation can accommodate the input buffer without a reallocation. Also when the
reallocation and copy does occur the new buffer is sized just large enough to
accommodate the current the current amount of data. If some data remains in the
cumulation after decode this will require a new allocation/copy when more data
arrives.

Modifications:
- Use maxFastWritableBytes to avoid allocation/copy if the current buffer can
  accommodate the input data without a reallocation operation.
- Use ByteBufAllocator#calculateNewCapacity(..) to get the size of the buffer
  when a reallocation/copy operation is necessary.

Result:
ByteToMessageDecoder MERGE_CUMULATOR won't allocate/copy if the cumulation
buffer can accommodate data without a reallocation, and when a reallocation
occurs we are more likely to leave additional space for future data in an effort
to reduce overall reallocations.
2019-12-13 09:48:25 -08:00
时无两丶
0cde4d9cb4 Uniform null pointer check. (#9840)
Motivation:
Uniform null pointer check.

Modifications:

Use ObjectUtil.checkNonNull(...)

Result:
Less code, same result.
2019-12-09 09:47:35 +01:00
Scott Mitchell
15b6ed92a0
SnappyFrameDecoderTest ByteBuf leak (#9854)
Motivation:
SnappyFrameDecoderTest has a few tests which fail to close the EmbeddedChannel
and therefore may leak ByteBuf objects.

Modifications:
- Make sure EmbeddedChannel#finishAndReleaseAll() is called in all tests

Result:
No more leaks from SnappyFrameDecoderTest.
2019-12-06 16:27:03 -08:00
Norman Maurer
d6638d5373
Correctly close EmbeddedChannel and release buffers in SnappyFrameDecoderTest (#9851)
Motivation:

We did not correctly close the `EmbeddedChannel` which would lead to not have `handlerRemoved(...)` called. This can lead to leaks. Beside this we also did not correctly consume produced data which could also show up as a leak.

Modifications:

- Always call `EmbeddedChannel.finish()`
- Ensure we consume all produced data and release it

Result:

No more leaks in test. This showed up in https://github.com/netty/netty/pull/9850#issuecomment-562504863.
2019-12-06 12:02:08 +01:00
Martin Furmanski
88712a9ea2 Improve error handling in ByteToMessageDecoder when expand fails (#9822)
Motivation:

The buffer which the decoder allocates for the expansion can be
leaked if there is a subsequent issue writing to it.

Modifications:
The error handling has been improved so that the new buffer always
is released on failure in the expand.

Result:
The decoder will not leak in this scenario any more.

Fixes: https://github.com/netty/netty/issues/9812
2019-11-28 12:17:44 +01:00
时无两丶
adc4a6170d Clean up expired docs. (#9756)
Motivation:
Since the `extractFrame` has used `retainedSlice` to avoid memory copy, we should clean this doc that was expired.

Result:
Better doc.
2019-11-06 09:43:25 +01:00
Johno Crawford
cf74acfce0 Remove todo in StringEncoder (#9719)
Motivation:

StringEncoder is marked @Shareable and CharsetEncoder is not thread-safe.

Modifications:

Remove TODO.

Result:

Less technical debt.
2019-10-29 19:47:28 +01:00
switchYello
e745ef0645 fix remove handler cause ByteToMessageDecoder out disorder (#9670)
Motivation:

Data flowing in from the decoder flows out in sequence,Whether decoder removed or not.

Modification:

fire data in out and clear out when hander removed
before call method handlerRemoved(ctx)

Result:

Fixes #9668 .
2019-10-21 00:48:30 -07:00
Norman Maurer
3d7dba373f
Eliminate unnessary copy of ByteBuf on ByteToMessageDecoder removal (#9662)
Motivation:

At the moment we do a ByteBuf.readBytes(...) on removal of the ByteToMessageDecoder if there are any bytes left and forward the returned ByteBuf to the next handler in the pipeline. This is not really needed as we can just forward the cumulation buffer directly and so eliminate the extra memory copy

Modifications:

Just forward the cumulation buffer directly on removal of the ByteToMessageDecoder

Result:

Less memory copies
2019-10-16 06:47:59 -07:00
Norman Maurer
6c05d16967
Use @SuppressJava6Requirement for animal sniffer plugin to ensure we always guard correctly (#9655)
Motivation:

We can use the `@SuppressJava6Requirement` annotation to be more precise about when we use Java6+ APIs. This helps us to ensure we always protect these places.

Modifications:

Make use of `@SuppressJava6Requirement` explicit

Result:

Fixes https://github.com/netty/netty/issues/2509.
2019-10-14 15:54:49 +02:00
Nikolay Fedorovskikh
08e9b456a4 Fixes validation of input bytes in the Base64 decoder (#9623)
Motivation:
In the current implementation of Base64 decoder an invalid
character `\u00BD` treated as `=`.
Also character `\u007F` leads to ArrayIndexOutOfBoundsException.

Modification:
Explicitly checks that all input bytes are ASCII characters
(greater than zero). Fix `decodabet` tables.

Result:
Correctly validation input bytes in Base64 decoder.
2019-10-10 20:46:39 +02:00
jingene
c0f9364870 Change the netty.io homepage scheme(http -> https) (#9344)
Motivation:

Netty homepage(netty.io) serves both "http" and "https".
It's recommended to use https than http.
Modification:

I changed from "http://netty.io" to "https://netty.io"
Result:

No effects.
2019-07-09 21:09:42 +02:00
jimin
a0656d2a31 Remove unnecessary code (#9303)
Motivation:

There are is some unnecessary code (like toString() calls) which can be cleaned up.

Modifications:

- Remove not needed toString() calls
- Simplify subString(...) calls
- Remove some explicit casts when not needed.

Result:

Cleaner code
2019-07-04 08:51:47 +02:00