av9ash/GitBugs huggingface dataset:
Bug: Fix spark-version-info.properties not found on Windows
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 04/Dec/22 15:19
Affects Version/s: 3.4.0

h1. *What is the problem?*

The spark-version-info.properties files is read during initialization of SparkContext. The absence of the same causes the Spark AM's launch to fail with the following error -
{code}
22/12/04 17:18:24 ERROR ApplicationMaster: User class threw exception: 
java.lang.ExceptionInInitializerError
	at org.apache.spark.package$.<init>(package.scala:93)
	at org.apache.spark.package$.<clinit>(package.scala)
	at org.apache.spark.SparkContext.$anonfun$new$1(SparkContext.scala:195)
	at org.apache.spark.internal.Logging.logInfo(Logging.scala:60)
	at org.apache.spark.internal.Logging.logInfo$(Logging.scala:59)
	at org.apache.spark.SparkContext.logInfo(SparkContext.scala:84)
	at org.apache.spark.SparkContext.<init>(SparkContext.scala:195)
	at org.apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2739)
	at org.apache.spark.sql.SparkSession$Builder.$anonfun$getOrCreate$2(SparkSession.scala:978)
	at scala.Option.getOrElse(Option.scala:189)
	at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:972)
	at org.apache.spark.examples.SparkPi$.main(SparkPi.scala:30)
	at org.apache.spark.examples.SparkPi.main(SparkPi.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.spark.deploy.yarn.ApplicationMaster$$anon$2.run(ApplicationMaster.scala:747)
Caused by: org.apache.spark.SparkException: Could not find spark-version-info.properties
	at org.apache.spark.package$SparkBuildInfo$.<init>(package.scala:62)
	at org.apache.spark.package$SparkBuildInfo$.<clinit>(package.scala)
	... 18 more
{code}

h1. *Why did the problem happen?*
While building Spark, the spark-version-info.properties file [is generated using bash|https://github.com/apache/spark/blob/d62c18b7497997188ec587e1eb62e75c979c1c93/core/pom.xml#L560-L564]. In Windows environment, if Windows Subsystem for Linux (WSL) is installed, it somehow overrides the other bash executables in the PATH, as noted in SPARK-40739. The bash in WSL has a different mounting configuration and thus, the target location specified for spark-version-info.properties won't be the expected location. Ultimately, this leads to spark-version-info.properties to get excluded from the spark-core jar, thus causing the SparkContext initialization to fail with the above depicted error message.

h1. *How can the problem be solved?*
I propose to fix this issue by enhancing the build system to automatically detect and switch between using Powershell for Windows and Bash for non-Windows OS. This yields a seamless build experience for all the platform users. Particularly for Windows users, to not worry about the conflicts with different bash installations.
Bug: Refactor connect directory structure
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 02/Dec/22 14:58
Affects Version/s: 3.3.2

Currently, `spark/connector/connect/` is a single module that contains both the "server"/service as well as the protobuf definitions.


However, this module can be split into multiple modules - "server" and "common". This brings the advantage of separating out the protobuf generation from the core "server" module for efficient reuse.
Bug: to_char throws NullPointerException when format is null
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 08/Dec/22 21:20
Affects Version/s: 3.4.0

Example:
{noformat}
spark-sql> select to_char(454, null);
[INTERNAL_ERROR] The Spark SQL phase analysis failed with an internal error. You hit a bug in Spark or the Spark plugins you use. Please, report this bug to the corresponding communities or vendors, and provide the full stack trace.
org.apache.spark.SparkException: [INTERNAL_ERROR] The Spark SQL phase analysis failed with an internal error. You hit a bug in Spark or the Spark plugins you use. Please, report this bug to the corresponding communities or vendors, and provide the full stack trace.
...
Caused by: java.lang.NullPointerException
	at org.apache.spark.sql.catalyst.expressions.ToCharacter.numberFormat$lzycompute(numberFormatExpressions.scala:227)
	at org.apache.spark.sql.catalyst.expressions.ToCharacter.numberFormat(numberFormatExpressions.scala:227)
	at org.apache.spark.sql.catalyst.expressions.ToCharacter.numberFormatter$lzycompute(numberFormatExpressions.scala:228)
	at org.apache.spark.sql.catalyst.expressions.ToCharacter.numberFormatter(numberFormatExpressions.scala:228)
	at org.apache.spark.sql.catalyst.expressions.ToCharacter.checkInputDataTypes(numberFormatExpressions.scala:236)
{noformat}
Compare to {{to_binary}}:
{noformat}
spark-sql> SELECT to_binary('abc', null);
NULL
Time taken: 3.097 seconds, Fetched 1 row(s)
spark-sql>
{noformat}
Also compare to {{to_char}} in PostgreSQL 14.6:
{noformat}
select to_char(454, null) is null as to_char_is_null;

 to_char_is_null 
-----------------
 t
(1 row)
{noformat}
Bug: Stage level scheduling, allow to change number of executors
Status: Open | Priority: Major | Resolution: 
Created: 08/Dec/22 11:48
Affects Version/s: 3.3.0

Since the total/max number of executor is constant throughout the application - in dynamic or static allocation - there is loose control over how much GPUs will be requested from the resource manager. 

For example, if an application needs 500 executors for the ETL part (with N cores each), but it needs - *or allowed -* only 50 GPUs for the DL part, in practice it will request at least 500 GPUs from the RM, since `spark.executor.instances` is set to 500. This leads to resource management challenges in multi tenant environments.

A quick workaround is to repartition the RDD to 50 partitions just before switching resources, but it has obvious downsides. 

It would be very helpful if the total/max number of executors could also be configured in the Resource Profile.
Bug: Avoid empty latest KafkaSourceOffset
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 03/Dec/22 19:09
Affects Version/s: 3.3.1

We found the offsetLog recorded an empty offset `{}` for the KafkaSource:

!image-2022-12-04-03-11-11-428.png!
It occurs only once but this empty offset will cause the data duplication.

{*}Root Cause{*}:

The root cause is that Kafka consumer may get empty partitions in extreme cases like getting partitions while Kafka cluster is reassigning partitions.
{code:scala}
// org.apache.spark.sql.kafka010.KafkaOffsetReaderConsumer
  private def partitionsAssignedToConsumer(
      body: ju.Set[TopicPartition] => Map[TopicPartition, Long],
      fetchingEarliestOffset: Boolean = false)
    : Map[TopicPartition, Long] = uninterruptibleThreadRunner.runUninterruptibly {

    withRetriesWithoutInterrupt {
      // Poll to get the latest assigned partitions
      consumer.poll(0)
      val partitions = consumer.assignment() // partitions may be empty

      if (!fetchingEarliestOffset) {
        // Call `position` to wait until the potential offset request triggered by `poll(0)` is
        // done. This is a workaround for KAFKA-7703, which an async `seekToBeginning` triggered by
        // `poll(0)` may reset offsets that should have been set by another request.
        partitions.asScala.map(p => p -> consumer.position(p)).foreach(_ => {})
      }

      consumer.pause(partitions)
      logDebug(s"Partitions assigned to consumer: $partitions.")
      body(partitions)
    }
  }
{code}
*Solution:*
Add offset filter for latestOffset.
Bug: [K8S] Decrement PVC_COUNTER when the pod deletion happens 
Status: In Progress | Priority: Major | Resolution: 
Created: 07/Dec/22 03:06
Affects Version/s: 3.4.0

commit cc55de3 introduced PVC_COUNTER to track outstanding number of PVCs.

PVC_COUNTER should only be decremented when the pod deletion happens (in response to error).

If the PVC isn't created successfully (where PVC_COUNTER isn't incremented) (possibly due to execution not reaching resource(pvc).create() call), we shouldn't decrement the counter.
variable `success` tracks the progress of PVC creation:

value 0 means PVC is not created.
value 1 means PVC has been created.
value 2 means PVC has been created but due to subsequent error, the pod is deleted.
Bug: Rewrite self join in in predicate to aggregate
Status: In Progress | Priority: Major | Resolution: 
Created: 07/Dec/22 02:17
Affects Version/s: 3.4.0

Transforms the SelfJoin resulting in duplicate rows used for IN predicate to aggregation.
For IN predicate, duplicate rows does not have any value. It will be overhead.

Ex: TPCDS Q95: following CTE is used only in IN predicates for only one column comparison ({@code ws_order_number}).
This results in exponential increase in Joined rows with too many duplicate rows.


{code:java}
WITH ws_wh AS
(
       SELECT ws1.ws_order_number,
              ws1.ws_warehouse_sk wh1,
              ws2.ws_warehouse_sk wh2
       FROM   web_sales ws1,
              web_sales ws2
       WHERE  ws1.ws_order_number = ws2.ws_order_number
       AND    ws1.ws_warehouse_sk <> ws2.ws_warehouse_sk)
{code}



Could be optimized as below:


{code:java}
WITH ws_wh AS
    (SELECT ws_order_number
      FROM  web_sales
      GROUP BY ws_order_number
      HAVING COUNT(DISTINCT ws_warehouse_sk) > 1)
{code}


Optimized CTE scans table only once and results in unique rows.
Bug: Inconsistency of spark session in DataFrame in user function for foreachBatch sink in PySpark
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 04/Dec/22 23:36
Affects Version/s: 3.3.2

[https://docs.databricks.com/_static/notebooks/merge-in-streaming.html]

According to some manual testing against above code example in PySpark, it seems like the property of sparkSession in given DataFrame is not the same with cloned session in streaming query. In other words, {{df.sparkSession}} does not seem to be same with the cloned spark session which you can access via {{{}df._jdf.sparkSession(){}}}.

So which session to pick depends on the actual implementation of method in PySpark DataFrame, which users would never know. If it leads to pick the different session than expected, it leads to open backdoor for avoiding restrictions (e.g. AQE), unable to see session scoped resources (e.g. temp view), etc.

So it’s quite critical to sync two sessions to refer the same.
Bug: Reorder the window partition expressions by expression stats
Status: In Progress | Priority: Major | Resolution: 
Created: 02/Dec/22 14:48
Affects Version/s: 3.4.0

We can reorder window partition expressions by the distinct values stats.

Sorting with high cardinality will be faster.

Benchmark result:
{code:java}
Window:                                       Best Time(ms)   Avg Time(ms)   Stdev(ms)    Rate(M/s)   Per Row(ns)   Relative
----------------------------------------------------------------------------------------------------------------------------
Disable reorder window partition expressions          13338          14035        1138          0.0     1333756.2       1.0X
Enable reorder window partition expressions              5981           6030          77          0.0      598102.1       2.2X
{code}
Bug: Find and refactor all cases suitable for using `PhysicalDataType` instead of `DataType`
Status: In Progress | Priority: Major | Resolution: 
Created: 02/Dec/22 03:25
Affects Version/s: 3.4.0

SPARK-41226 Introduce physical data types, and the use PhysicalDataType replace DataType for many case, but there should also be refactorable cases in the code. We can add some task at any time to complete the relevant refactoring
Bug: UNRESOLVED_ROUTINE error class
Status: In Progress | Priority: Major | Resolution: 
Created: 01/Dec/22 21:31
Affects Version/s: 3.4.0

We want to unify and  name:
"_LEGACY_ERROR_TEMP_1041" : \{
  "message" : [
    "Undefined function <name>."  ]
},
_LEGACY_ERROR_TEMP_1242" : \{
  "message" : [
    "Undefined function: <rawName>. This function is neither a built-in/temporary function, nor a persistent function that is qualified as <fullName>."  ]
},"_LEGACY_ERROR_TEMP_1243" : {
  "message" : [
    "Undefined function: <rawName>"  ]
I proposal is:
UNRESOLVED_ROUTINE. routineName => `a`.`b`.`func`, routineSignature => [INT, STRING] , searchPath => [`builtin`, `session`, `hiveMetaStore`.`default`]
This assumes agreement to introduce `builtin` as optional qualifier for builtin functions.
And `session` a optional qualifier for temporary functions (separate PR).

Q: Why ROUTINE?
A: Some day we may want to support PROCEDURES and they will follow the name rule and share the same namespace.

Q:Why A PATH
A: We do follow a hard coded path today with a fixed precedence  rule.

Q: Why provide the signature
A: Longterm we may support overloading of functions by arity, type or even parameter name.
Bug: Memory leak in FileSystem.CACHE when submitting apps to secure cluster using InProcessLauncher
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 20/Dec/22 10:45
Affects Version/s: 3.1.2

When submitting spark application in kerberos environment the credentials of 'current user' (UserGroupInformation.getCurrentUser()) are being modified.
Filesystem.CACHE entries contain 'current user' (with user credentials) as a key.
Submitting many spark applications using InProcessLauncher cause that FileSystem.CACHE becomes bigger and bigger.
Finally process exits because of OutOfMemory error.

Code for reproduction attached.

 

Output from running 'jmap -histo' on reproduction jvm shows that the number of FileSystem$Cache$Key increases in time:

time: #instances class
1671533274: 2 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533335: 11 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533395: 21 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533455: 30 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533515: 39 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533576: 48 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533636: 57 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533696: 66 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533757: 75 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533817: 84 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533877: 93 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533937: 102 org.apache.hadoop.fs.FileSystem$Cache$Key
1671533998: 111 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534058: 120 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534118: 135 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534178: 140 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534239: 150 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534299: 159 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534359: 168 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534419: 177 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534480: 186 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534540: 195 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534600: 204 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534661: 213 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534721: 222 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534781: 231 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534841: 240 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534902: 249 org.apache.hadoop.fs.FileSystem$Cache$Key
1671534962: 257 org.apache.hadoop.fs.FileSystem$Cache$Key
1671535022: 264 org.apache.hadoop.fs.FileSystem$Cache$Key
1671535083: 273 org.apache.hadoop.fs.FileSystem$Cache$Key
1671535143: 282 org.apache.hadoop.fs.FileSystem$Cache$Key
1671535203: 291 org.apache.hadoop.fs.FileSystem$Cache$Key
Bug: The Spark exclude node functionality for YARN should work independently of dynamic allocation
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 19/Dec/22 09:32
Affects Version/s: 3.0.3

The Spark exclude node functionality for Spark on YARN, introduced in SPARK-26688, allows users to specify a list of node names that are excluded from resource allocation. This is done using the configuration parameter: {{spark.yarn.exclude.nodes}}

The feature currently works only for executors allocated via dynamic allocation. To use the feature on Spark 3.3.1, for example, one may set the configurations {{{}spark.dynamicAllocation.enabled{}}}=true, spark.dynamicAllocation.minExecutors=0 and spark.executor.instances=0, thus making Spark spawning executors only via dynamic allocation.

This proposes to document this behavior for the current Spark release and also proposes an improvement of this feature by extending the scope of Spark exclude node functionality for YARN beyond dynamic allocation, which I believe makes it more generally useful.
Bug: Improve/complete PathOutputCommitProtocol support for dynamic partitioning
Status: In Progress | Priority: Minor | Resolution: 
Created: 16/Dec/22 17:45
Affects Version/s: 3.3.1

Followup to SPARK-40034 as 
* that is incomplete as it doesn't record the partitions
* as long at the job doesn't call `newTaskTempFileAbsPath()`, and slow renames are ok, both s3a committers are actually OK to use.

It's only that newTaskTempFileAbsPath operation which is unsupported in s3a committers; the post-job dir rename is O(data) but file by file rename is correct for a non-atomic job commit.

# Cut PathOutputCommitProtocol.newTaskTempFile; to update super partitionPaths (needs a setter). The superclass can't just say if (committer instance of PathOutputCommitter as spark-core needs to compile with older hadoop versions)
# downgrade failure in setup to log (info?)
# retain failure in the newTaskTempFileAbsPath call.

Testing: yes
Bug: Catch specific exceptions for both Spark Connect and PySpark
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 26/Dec/22 11:52
Affects Version/s: 3.4.0

In python/pyspark/sql/tests/test_catalog.py, we should catch more specific exceptions such as AnalysisException. The test is shared in both Spark Connect and PySpark so we should figure the way out to share it.
Bug: Spark UI: In jobs API, numActiveStages can be negative in some cases
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 22/Dec/22 08:05
Affects Version/s: 3.3.1

In API /api/v1/applications/.../jobs, for each job, there's one property called numActiveStages, telling how many active stages of the job.

It is calculated by the following logic:
 * When stage is submitted, numActiveStages += 1.
 * When stage is completed, numActiveStages -= 1.
 * When job is ended, for each pending stage, numActiveStages -= 1.

!image-2022-12-22-16-06-45-367.png!

!image-2022-12-23-13-24-30-412.png!

!image-2022-12-22-16-06-21-180.png!

 

However, there's possibility that there's no stage submitted event for some skipped stages. In this case, when job ends, numActiveStages may be minus. Example:
 # job 0 started with stage 0, 1, 2
 ** stage 0: pending
 ** stage 1: pending
 ** stage 2: pending
 ** numActiveStages: 0
 # stage 0 submitted
 ** stage 0: active
 ** stage 1: pending
 ** stage 2: pending
 ** numActiveStages: 1
 # stage 0 completed
 ** stage 0: completed
 ** stage 1: pending
 ** stage 2: pending
 ** numActiveStages: 0
 # job 0 ended
 ** stage 0: completed
 ** stage 1: skipped
 ** stage 2: skipped
 ** numActiveStages: -2
Bug: Unify the environment variable of *_PROTOC_EXEC_PATH
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 12/Dec/22 04:22
Affects Version/s: 3.4.0

At present, there are 3 similar environment variable of *_PROTOC_EXEC_PATH, but they use the same pb version. Because they are consistent in compilation, so we can unify the environment variable names to simplify.
Bug: Move configuration of `versions-maven-plugin` to parent pom
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 19/Dec/22 02:48
Affects Version/s: 3.4.0

In addition to `test-dependencies.sh`, `release-build.sh` and `release-tag.sh` also using the `build/mvn versions:set` command. So move the configuration of `versions-maven-plugin` to parent pom can unify the `versions-maven-plugin` version used by the whole Spark project.
Bug: Spark SSLOptions sub settings should be set only when ssl is enabled
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 26/Dec/22 13:09
Affects Version/s: 3.4.0

If ${ns}.enabled is false, there is no use of setting rest of ${ns}.* settings in SSLOptions as this requires unnecessary operations to be performed to set these properties. 

for ex: ${ns} - spark.ssl

As per SSLOptions,
 * SSLOptions is intended to provide the maximum common set of SSL settings, which are supported
 * by the protocol, which it can generate the configuration for.
*
 * @param enabled enables or disables SSL; *if it is set to false, the rest of the settings are disregarded*
Bug: Shuffle merge finalization removes the wrong finalization state from the DB
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 30/Dec/22 21:54
Affects Version/s: 3.4.0

During `finalizeShuffleMerge` in external shuffle service, if the finalization request is for a newer shuffle merge id, then we cleanup the existing (older) shuffle details and add the newer entry (for which we got no pushed blocks) to the DB.

Unfortunately, when cleaning up from the DB, we are using the incorrect AppAttemptShuffleMergeId - we remove the latest shuffle merge id instead of the existing entry.

Proposed Fix:

{code}
diff --git a/common/network-shuffle/src/main/java/org/apache/spark/network/shuffle/RemoteBlockPushResolver.java b/common/network-shuffle/src/main/java/org/apache/spark/network/shuffle/RemoteBlockPushResolver.java
index 816d1082850..551104d0eba 100644
--- a/common/network-shuffle/src/main/java/org/apache/spark/network/shuffle/RemoteBlockPushResolver.java
+++ b/common/network-shuffle/src/main/java/org/apache/spark/network/shuffle/RemoteBlockPushResolver.java
@@ -653,9 +653,11 @@ public class RemoteBlockPushResolver implements MergedShuffleFileManager {
         } else if (msg.shuffleMergeId > mergePartitionsInfo.shuffleMergeId) {
           // If no blocks pushed for the finalizeShuffleMerge shuffleMergeId then return
           // empty MergeStatuses but cleanup the older shuffleMergeId files.
+          AppAttemptShuffleMergeId currentAppAttemptShuffleMergeId = new AppAttemptShuffleMergeId(
+                  msg.appId, msg.appAttemptId, msg.shuffleId, mergePartitionsInfo.shuffleMergeId);
           submitCleanupTask(() ->
               closeAndDeleteOutdatedPartitions(
-                  appAttemptShuffleMergeId, mergePartitionsInfo.shuffleMergePartitions));
+                  currentAppAttemptShuffleMergeId, mergePartitionsInfo.shuffleMergePartitions));
         } else {
           // This block covers:
           //  1. finalization of determinate stage
{code}
Bug: Only update SQLMetric value if merging with valid metric
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 07/Dec/22 20:54
Affects Version/s: 3.4.0

We use -1 as initial value of SQLMetric, and change it to 0 while merging with other SQLMetric instances. A SQLMetric will be treated as invalid and filtered out later.

While we are developing with Spark, it is trouble behavior that two invalid SQLMetric instances merge to a valid SQLMetric because merging will set the value to 0.
Bug: Upgrade Apache Ivy to 2.5.1
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 22/Dec/22 08:59
Affects Version/s: 3.3.1

[CVE-2022-37865|https://www.cve.org/CVERecord?id=CVE-2022-37865]
and
[CVE-2022-37866|https://nvd.nist.gov/vuln/detail/CVE-2022-37866]
Bug: Upgrade netty from 4.1.84.Final to 4.1.86.Final
Status: Resolved | Priority: Minor | Resolution: Fixed
Created: 18/Dec/22 21:09
Affects Version/s: 3.4.0

[HAProxyMessageDecoder Stack Exhaustion DoS|https://github.com/netty/netty/security/advisories/GHSA-fx2c-96vj-985v]

and 

[HTTP Response splitting from assigning header value iterator|https://github.com/netty/netty/security/advisories/GHSA-hh82-3pmq-7frp]