Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8333590

UnmodifiableHeaders.toString() returns a value that represents empty headers

XMLWordPrintable

    • b26
    • generic
    • generic
    • Verified

      ADDITIONAL SYSTEM INFORMATION :
      java.specification.version=22
      java.vm.vendor=Oracle Corporation
      java.vm.specification.version=22
      os.name=Windows 10
      sun.java.launcher=SUN_STANDARD
      java.specification.vendor=Oracle Corporation
      java.version.date=2024-03-19
      java.vm.specification.vendor=Oracle Corporation
      java.specification.name=Java Platform API Specification
      java.runtime.version=22+36-2370
      os.version=10.0
      java.runtime.name=OpenJDK Runtime Environment
      java.vm.name=OpenJDK 64-Bit Server VM
      java.version=22
      java.vendor=Oracle Corporation
      java.vm.version=22+36-2370

      A DESCRIPTION OF THE PROBLEM :
      I was playing around with the com.sun.net.httpserver package and noticed that when trying to print the contents of the request headers returned from HttpExchange.getRequestHeaders() it was falsely outputting an empty map even though a previous call to .getSize() returned 4.

      Upon further investigation, I figured that the following call stack leads to:

      `HttpExchangeImpl::getRequestHeaders()`
      -> `ExchangeImpl::getRequestHeaders()`
          -> `return Headers.of(req.headers());`

      `Headers::of` returns a new instance of `UnmodifiableHeaders`.
      This class defines a field `map`, which is also defined in the parent class `Headers`. All headers are stored inside the map defined in the `UnmodifiableHeaders` class. The problem is, `UnmodifiableHeaders` does not override `toString`. Therefore, when trying to call `toString` on a `UnmodifiableHeaders` instance, the parent's `toString` method gets called which prints the contents of the `map` variable defined in the parent class. Which will be empty.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Reproduction is very easy.

      Step 1: Create an instance of `Headers` and add one or more header entries to it.
      Step 2: Create a copy (instance of `UnmodifiableHeaders`) of the instance using the static factory method `Headers::of`.
      Step 3: Make a call to `toString` on the created copy and print the result.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Calling `toString` on an instance of `UnmodifiableHeaders` should print the headers contained in the instance.
      ACTUAL -
      Calling `.toString` on an instance of `UnmodifiableHeaders` will always print `Headers { {} }`

      ---------- BEGIN SOURCE ----------
      import com.sun.net.httpserver.Headers;

      public class BugReproduction {
          public static void main(String[] args) {
              Headers headers = new Headers();
              headers.add("K", "V");
              Headers copy = Headers.of(headers);
              System.out.println("headers: " + headers);
              System.out.println("copy: " + copy);
          }
      }
      ---------- END SOURCE ----------

      FREQUENCY : always


            jpai Jaikiran Pai
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: