#7662 Make StringBiValue safe against mutations to the underlying RubyString

Fixes #7663
This commit is contained in:
Armin 2017-07-12 11:50:24 +02:00 committed by Armin Braun
parent 59df92321a
commit 1ebb0e350f
3 changed files with 38 additions and 6 deletions

View file

@ -84,6 +84,15 @@ describe LogStash::Event do
expect(e.get("foo")).to eq("bar")
end
it "should propagate changes to mutable strings to java APIs" do
e = LogStash::Event.new()
e.to_java.setField("foo", "bar")
expect(e.get("foo")).to eq("bar")
e.get("foo").gsub!(/bar/, 'pff')
expect(e.get("foo")).to eq("pff")
expect(e.to_java.getField("foo")).to eq("pff")
end
it "should set deep hash values" do
e = LogStash::Event.new()
expect(e.set("[foo][bar]", "baz")).to eq("baz")

View file

@ -1,15 +1,15 @@
package org.logstash.bivalues;
import com.fasterxml.jackson.annotation.JsonValue;
import java.io.ObjectStreamException;
import org.jruby.Ruby;
import org.jruby.RubyString;
import java.io.ObjectStreamException;
public class StringBiValue extends BiValueCommon<RubyString, String> implements BiValue<RubyString, String> {
public final class StringBiValue extends BiValueCommon<RubyString, String>
implements BiValue<RubyString, String> {
public StringBiValue(RubyString rubyValue) {
this.rubyValue = rubyValue;
javaValue = null;
}
public StringBiValue(String javaValue) {
@ -20,12 +20,35 @@ public class StringBiValue extends BiValueCommon<RubyString, String> implements
private StringBiValue() {
}
@Override
@JsonValue
public String javaValue() {
return rubyValue != null ? rubyValue.toString() : javaValue;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o instanceof BiValue) {
final BiValueCommon<?, ?> other = (BiValueCommon<?, ?>) o;
return other.hasRubyValue() && other.rubyValueUnconverted().equals(rubyValue) ||
(other.hasJavaValue() && other.javaValue().equals(this.javaValue()));
} else {
return String.class.isAssignableFrom(o.getClass()) && this.javaValue().equals(o);
}
}
protected void addRuby(Ruby runtime) {
rubyValue = RubyString.newUnicodeString(runtime, javaValue);
}
@Override
protected void addJava() {
javaValue = rubyValue.asJavaString();
}
@Override
public boolean hasJavaValue() {
return true;
}
// Called when object is to be serialized on a stream to allow the object to substitute a proxy for itself.

View file

@ -29,7 +29,7 @@ public class BiValueTest extends TestBase {
String s = "foo bar baz";
StringBiValue subject = new StringBiValue(RubyString.newString(ruby, s));
assertTrue(subject.hasRubyValue());
assertFalse(subject.hasJavaValue());
assertTrue(subject.hasJavaValue());
assertEquals(s, subject.javaValue());
}