[SPIGOT-749] Instant potions throw NPE if Potion.fromItemStack is used Created: 28/Mar/15  Updated: 26/May/15  Resolved: 26/May/15

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: tastybento Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

1.8.1 craftbukkit


Issue Links:
Cloners
clones SPIGOT-372 CLONE - Instant potions cannot be ext... Closed

 Description   

Potion.fromItemStack(IS); causes this problem IS is itemstack

and here is the log:
/////////////////////////////////////////////////////////////////////////////////////////////////

[Server thread/ERROR]: Could not pass event InventoryOpenEvent to GUI_Shop v0.0.1
org.bukkit.event.EventException
	at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:297) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.TimedRegisteredListener.callEvent(TimedRegisteredListener.java:36) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:501) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:486) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.craftbukkit.v1_8_R1.event.CraftEventFactory.callInventoryOpenEvent(CraftEventFactory.java:692) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.EntityPlayer.openContainer(EntityPlayer.java:641) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.BlockChest.interact(SourceFile:339) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PlayerInteractManager.interact(PlayerInteractManager.java:495) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:693) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:50) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:80) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_11]
	at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_11]
	at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:643) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:284) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:598) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:506) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at java.lang.Thread.run(Unknown Source) [?:1.8.0_11]
Caused by: java.lang.IllegalArgumentException: Instant potions cannot be extended
	at org.apache.commons.lang.Validate.isTrue(Validate.java:136) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.setHasExtendedDuration(Potion.java:268) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.extend(Potion.java:152) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.fromDamage(Potion.java:409) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.fromItemStack(Potion.java:418) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at shop.constant.items.PotionItem.<init>(PotionItem.java:16) ~[?:?]
	at shop.constant.items.CustomItem.toCIFromItemStack(CustomItem.java:206) ~[?:?]
	at shop.event.handler.InventoryEventHandler.serializeItem(InventoryEventHandler.java:100) ~[?:?]
	at shop.event.handler.InventoryEventHandler.onInventoryOpen(InventoryEventHandler.java:48) ~[?:?]
	at sun.reflect.GeneratedMethodAccessor627.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_11]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_11]
	at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:295) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	... 19 more
[03:13:04] [Server thread/ERROR]: Could not pass event InventoryCloseEvent to GUI_Shop v0.0.1
org.bukkit.event.EventException
	at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:297) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.TimedRegisteredListener.callEvent(TimedRegisteredListener.java:36) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:501) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:486) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.craftbukkit.v1_8_R1.event.CraftEventFactory.handleInventoryCloseEvent(CraftEventFactory.java:815) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:1301) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.craftbukkit.v1_8_R1.event.CraftEventFactory.callInventoryOpenEvent(CraftEventFactory.java:684) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.EntityPlayer.openContainer(EntityPlayer.java:641) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.BlockChest.interact(SourceFile:339) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PlayerInteractManager.interact(PlayerInteractManager.java:495) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:693) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:50) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:80) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_11]
	at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_11]
	at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:643) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:284) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:598) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:506) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at java.lang.Thread.run(Unknown Source) [?:1.8.0_11]
Caused by: java.lang.IllegalArgumentException: Instant potions cannot be extended
	at org.apache.commons.lang.Validate.isTrue(Validate.java:136) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.setHasExtendedDuration(Potion.java:268) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.extend(Potion.java:152) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.fromDamage(Potion.java:409) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.fromItemStack(Potion.java:418) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at shop.constant.items.PotionItem.<init>(PotionItem.java:16) ~[?:?]
	at shop.constant.items.CustomItem.toCIFromItemStack(CustomItem.java:206) ~[?:?]
	at shop.event.handler.InventoryEventHandler.serializeItem(InventoryEventHandler.java:100) ~[?:?]
	at shop.event.handler.InventoryEventHandler.onInventoryClose(InventoryEventHandler.java:62) ~[?:?]
	at sun.reflect.GeneratedMethodAccessor609.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_11]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_11]
	at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:295) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	... 21 more
[03:13:04] [Server thread/ERROR]: Could not pass event InventoryOpenEvent to GUI_Shop v0.0.1
org.bukkit.event.EventException
	at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:297) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.TimedRegisteredListener.callEvent(TimedRegisteredListener.java:36) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:501) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:486) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.craftbukkit.v1_8_R1.event.CraftEventFactory.callInventoryOpenEvent(CraftEventFactory.java:692) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.EntityPlayer.openContainer(EntityPlayer.java:641) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.BlockChest.interact(SourceFile:339) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PlayerInteractManager.interact(PlayerInteractManager.java:495) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:693) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:50) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:80) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_11]
	at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_11]
	at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:643) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:284) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:598) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:506) [craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at java.lang.Thread.run(Unknown Source) [?:1.8.0_11]
Caused by: java.lang.IllegalArgumentException: Instant potions cannot be extended
	at org.apache.commons.lang.Validate.isTrue(Validate.java:136) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.setHasExtendedDuration(Potion.java:268) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.extend(Potion.java:152) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.fromDamage(Potion.java:409) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at org.bukkit.potion.Potion.fromItemStack(Potion.java:418) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	at shop.constant.items.PotionItem.<init>(PotionItem.java:16) ~[?:?]
	at shop.constant.items.CustomItem.toCIFromItemStack(CustomItem.java:206) ~[?:?]
	at shop.event.handler.InventoryEventHandler.serializeItem(InventoryEventHandler.java:100) ~[?:?]
	at shop.event.handler.InventoryEventHandler.onInventoryOpen(InventoryEventHandler.java:48) ~[?:?]
	at sun.reflect.GeneratedMethodAccessor627.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_11]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_11]
	at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:295) ~[craftbukkit-1.8.jar:git-Bukkit-40aaa31]
	... 19 more


 Comments   
Comment by Oliver Dunk [ 25/May/15 ]

Opened PR #71 in Bukkit to fix, awaiting feedback.

Comment by tastybento [ 29/Mar/15 ]

Possible fix:

https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/potion/Potion.java

Line 408, add a check for the two instant potions:

if (type != PotionType.INSTANT_DAMAGE && type != PotionType.INSTANT_HEAL) {

Comment by tastybento [ 28/Mar/15 ]

A simple test to see this bug is:

1. Have a player hold a potion of harming, or healing in their inventory, e.g., use creative mode
2. Do something like:

ItemStack[] playerInv = player.getInventory().getContents();
for (ItemStack i : playerInv) {
if (i != null && i.getType().equals(Material.POTION))

{ Potion p = Potion.fromItemStack(i); }

}

You will see the NPE immediately.

Comment by tastybento [ 28/Mar/15 ]

This bug report has been closed as invalid before twice, but it it's a legitimate bug.

CraftBukkit version git-Spigot-c136710-350cb99 (MC: 1.8.3) (Implementing API version 1.8.3-R0.1-SNAPSHOT)

The methods at fault are:

Potion.fromDamage(int)

and

Potion.fromItemStack(ItemStack) <-- this just calls potion fromDamage

Essentially, if a player is holding a potion of harming or healing (both of these are classed as "instant" potions) and this method is used, it will throw a NPE because these kinds of potion cannot be extended. The NPE is being thrown by Spigot/CraftBukkit code that assumes any potion can be extended.

The code that is at fault is this:

public static Potion fromDamage(int damage) {
PotionType type = PotionType.getByDamageValue(damage & POTION_BIT);
Potion potion;
if (type == null || (type == PotionType.WATER && damage != 0))

{ potion = new Potion(damage & NAME_BIT); }

else

{ int level = (damage & TIER_BIT) >> TIER_SHIFT; level++; potion = new Potion(type, level); }

if ((damage & SPLASH_BIT) > 0)

{ potion = potion.splash(); }

if ((damage & EXTENDED_BIT) > 0)

{ potion = potion.extend(); }

return potion;
}

The last part (potion.extend()) throws the NPE.

The fundamental problem is that there is currently no method to check if a potion is "instant" or not. It would have to be checked by name. That is what I do now as a work around, but it would be better to have the internal function do this so this function can be used with any potion that the player has in their inventory.

Generated at Sun Mar 30 01:50:14 UTC 2025 using Jira 10.3.3#10030003-sha1:d220e3fefc8dfc6d47f522d3b9a20c1455e12b7b.