Skip to content
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

Allow all immutable List subclasses from Java 11 #10026

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mtughan
Copy link

@mtughan mtughan commented Dec 4, 2024

A previous commit specifically allowed one of the two subclasses used by List.of and List.copyOf, but not the other, which can result in unexpected errors and bugs. Add the other to the default allow list of classes to avoid these.

Testing done

None.

Proposed changelog entries

  • Allow all immutable List subclasses from Java 11 over remoting

Proposed upgrade guidelines

N/A

Submitter checklist

Preview Give feedback

Desired reviewers

N/A

Before the changes are marked as ready-for-merge:

Maintainer checklist

Preview Give feedback

Copy link

welcome bot commented Dec 4, 2024

Yay, your first pull request towards Jenkins core was created successfully! Thank you so much!

A contributor will provide feedback soon. Meanwhile, you can join the chats and community forums to connect with other Jenkins users, developers, and maintainers.

@NotMyFault NotMyFault requested a review from a team December 8, 2024 17:12
Copy link
Member

@timja timja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems ok, do you have a specific need for them though?

@timja
Copy link
Member

timja commented Dec 8, 2024

@jglick / @dwnusbaum any opinion?

@mtughan
Copy link
Author

mtughan commented Dec 9, 2024

seems ok, do you have a specific need for them though?

I used it recently in the Scriptler plugin, which is how I came across this. By only having List12 in there, it only permits the usage of List.of or List.copyOf where exactly 1 or 2 elements are present. Calls with 0 elements or 3 or more will result in using ListN, which wasn't permitted before (hence the need for the class filter file in that commit).

And then while I was here, I also thought that adding the Set and Map versions of the built-in immutable collections would be good. I don't specifically use them right now, but could potentially in the future. There should be no safety issues when using these as they are specifically immutable collections and cannot change; from that point of view, they should be equivalent to Guava's ImmutableList, ImmutableMap, and ImmutableSet, all 3 of which are already allowed in this file.

@timja
Copy link
Member

timja commented Dec 9, 2024

/label ready-for-merge


This PR is now ready for merge, after ~24 hours, we will merge it if there's no negative feedback.

Thanks!

@comment-ops-bot comment-ops-bot bot added the ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback label Dec 9, 2024
@timja timja added the rfe For changelog: Minor enhancement. use `major-rfe` for changes to be highlighted label Dec 9, 2024
jglick
jglick previously requested changes Dec 9, 2024
Copy link
Member

@jglick jglick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-0 I guess. It is not a security threat, but neither is it necessary: jenkinsci/scriptler-plugin#134 (review)

Most of the classes listed in the whitelist were there not because they should be serialized but because they were being serialized by some plugin at the time https://jenkins.io/jep/200 was developed, and it was simpler to allow the class temporarily than to wait for a plugin release removing the usage. New code should only use simple types like ArrayList. Always look at your actual config.xml serial form.

@mtughan
Copy link
Author

mtughan commented Dec 9, 2024

New code should only use simple types like ArrayList. Always look at your actual config.xml serial form.

Why should something like ArrayList be preferred over a JDK built-in immutable collection? Immutable collections are very handy for ensuring that objects don't unexpectedly change and can be used in operations that require hashing, such as sets and maps. I can certainly understand why we would prefer JDK classes over 3rd-party libraries such as Guava, but this is also JDK 9+. I suppose I could call code like Collections.unmodifiableList(new ArrayList<>(parameters)) to accomplish something similar, but that looks much more complicated than List.copyOf(parameters).

In terms of the serialized forms, that's currently fair: using an ArrayList results in

<parameters>
  <org.jenkinsci.plugins.scriptler.config.Parameter>
    <name>test</name>
    <value>value1</value>
  </org.jenkinsci.plugins.scriptler.config.Parameter>
</parameters>

while using List.copyOf currently results in

<parameters class="java.util.ImmutableCollections$List12" resolves-to="java.util.CollSer" serialization="custom">
  <java.util.CollSer>
    <default>
      <tag>1</tag>
    </default>
    <int>1</int>
    <org.jenkinsci.plugins.scriptler.config.Parameter>
      <name>test</name>
      <value>value</value>
    </org.jenkinsci.plugins.scriptler.config.Parameter>
  </java.util.CollSer>
</parameters>

which appears to be because it implements custom serialization methods. But I would argue that the second form should be improved (if possible) rather than always preferring the first form.

@jglick
Copy link
Member

jglick commented Dec 9, 2024

the second form should be improved (if possible)

Core could get additional custom XStream converters if necessary. But it is not necessary: the field in an XStream-serialized class should always use the plainest collection possible types—generally ArrayList or PersistedList or DescribableList. (In the case of a Describable, Set or Map should not generally be used, since core form controls do not really support these types of collections—only a List<T> where T is another nested Describable. The only other recommended field types would be non-collections: String, boolean, int, or long, and maybe enum though I am not sure how well that works.)

A @DataBoundConstructor, @DataBoundSetter, getter matching one of those two, or any other method used programmatically (not called from databinding) may of course include logic to make defensive copies, make collections immutable, add synchronization, etc.

@alecharp alecharp removed the ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback label Dec 9, 2024
@mtughan
Copy link
Author

mtughan commented Dec 9, 2024

I think I see why ArrayList should be preferred now: XStream has built in support for ArrayList specifically (along with HashSet, LinkedHashSet, LinkedList, and Vector) through the CollectionConverter class. So from that standpoint, it makes sense to not add the additional Set and Map implementations here.

I would still argue that we should probably add ListN in addition to List12 here. With List12 being allowed, people may get the idea that List.of or List.copyOf are supported, and it will work in some circumstances (i.e., with 1 or 2 elements being used). However, once a scenario where 0 or 3+ elements are used, then it may unexpectedly break and may be a source of bugs. I recognize that you (@jglick) had already commented on the original change at #6700 (comment), but with that code being part of Jenkins 2.358 and later, I feel it would be better to finish the job and add both.

A previous commit specifically allowed one of the two subclasses used by
`List.of` and `List.copyOf`, but not the other, which can result in
unexpected errors and bugs. Add the other to the default allow list of
classes to avoid these.
@mtughan mtughan force-pushed the allow-immutable-collections branch from 517c7b8 to fc4a567 Compare December 9, 2024 15:58
@mtughan mtughan changed the title Allow all immutable collections from Java 11 Allow all immutable List subclasses from Java 11 Dec 9, 2024
@mtughan
Copy link
Author

mtughan commented Dec 9, 2024

I've pushed a new commit and updated the PR description to reflect that we're only allowing immutable List classes now, not all immutable collections.

@jglick jglick dismissed their stale review December 9, 2024 22:18

As a rule, nothing should ever be added to this whitelist ever again. The damage has already been partially done in this case so this PR is more a matter of completing the mistake. No plugin code should be written which relies on it.

@mtughan
Copy link
Author

mtughan commented Dec 20, 2024

@timja and @jglick, is there anything else preventing this PR from progressing? Or can we have it merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rfe For changelog: Minor enhancement. use `major-rfe` for changes to be highlighted
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants