Skip to content

Commit

Permalink
#7662 Make StringBiValue safe against mutations to the underlying Rub…
Browse files Browse the repository at this point in the history
…yString

Fixes #7663
  • Loading branch information
original-brownbear committed Jul 17, 2017
1 parent 745b194 commit 36bf44c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
9 changes: 9 additions & 0 deletions logstash-core/spec/logstash/event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@
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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -20,12 +20,35 @@ public StringBiValue(String javaValue) {
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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void testStringBiValueFromRuby() {
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());
}

Expand Down

0 comments on commit 36bf44c

Please sign in to comment.