package org.sonar.api.batch.sensor.issue.internal;
import com.google.common.base.Preconditions;
-import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.issue.IssueLocation;
import org.sonar.api.batch.sensor.issue.NewIssueLocation;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
+import static org.apache.commons.lang.StringUtils.abbreviate;
+import static org.apache.commons.lang.StringUtils.trim;
public class DefaultIssueLocation implements NewIssueLocation, IssueLocation {
@Override
public DefaultIssueLocation on(InputComponent component) {
- Preconditions.checkArgument(component != null, "Component can't be null");
+ checkArgument(component != null, "Component can't be null");
Preconditions.checkState(this.component == null, "on() already called");
this.component = component;
return this;
@Override
public DefaultIssueLocation message(String message) {
requireNonNull(message, "Message can't be null");
- this.message = StringUtils.abbreviate(StringUtils.trim(message), MESSAGE_MAX_SIZE);
+ if (message.contains("\u0000")) {
+ throw new IllegalArgumentException(unsupportedCharacterError(message, component));
+ }
+ this.message = abbreviate(trim(message), MESSAGE_MAX_SIZE);
return this;
}
+ private static String unsupportedCharacterError(String message, @Nullable InputComponent component) {
+ String error = "Character \\u0000 is not supported in issue message '" + message + "'";
+ if (component != null) {
+ error += ", on component: " + component.toString();
+ }
+ return error;
+ }
+
@Override
public InputComponent inputComponent() {
return this.component;
return this.message;
}
+ public static void main (String[] args) {
+
+ new DefaultIssueLocation().message("pipo");
+
+ }
+
}
package org.sonar.api.batch.sensor.issue.internal;
import org.apache.commons.lang.StringUtils;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.rules.ExpectedException.none;
public class DefaultIssueLocationTest {
@Rule
- public ExpectedException thrown = ExpectedException.none();
+ public ExpectedException thrown = none();
private InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php")
.initMetadata("Foo\nBar\n")
.build();
+ @Test
+ public void should_build() {
+ assertThat(new DefaultIssueLocation()
+ .on(inputFile)
+ .message("pipo bimbo")
+ .message()
+ ).isEqualTo("pipo bimbo");
+ }
+
@Test
public void not_allowed_to_call_on_twice() {
thrown.expect(IllegalStateException.class);
.message(StringUtils.repeat("a", 4001)).message()).hasSize(4000);
}
+ @Test
+ public void prevent_null_character_in_message_text() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Character \\u0000 is not supported in issue message");
+
+ new DefaultIssueLocation()
+ .message("pipo " + '\u0000' + " bimbo");
+ }
+
+ @Test
+ public void prevent_null_character_in_message_text_when_builder_has_been_initialized() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage(customMatcher("Character \\u0000 is not supported in issue message", ", on component: src/Foo.php"));
+
+ new DefaultIssueLocation()
+ .on(inputFile)
+ .message("pipo " + '\u0000' + " bimbo");
+ }
+
+ private Matcher<String> customMatcher(String startWith, String endWith) {
+ return new TypeSafeMatcher<String>() {
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Invalid message");
+ }
+
+ @Override
+ protected boolean matchesSafely(final String item) {
+ return item.startsWith(startWith) && item.endsWith(endWith);
+ }
+ };
+ }
+
}
import org.apache.commons.lang.StringUtils;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.sonar.wsclient.issue.Issue;
import org.sonar.wsclient.issue.IssueQuery;
import org.sonar.wsclient.issue.Issues;
import util.ItUtils;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.rules.ExpectedException.none;
import static util.ItUtils.runProjectAnalysis;
public class IssueCreationTest extends AbstractIssueTest {
+ @Rule
+ public ExpectedException thrown = none();
+
private static final String SAMPLE_PROJECT_KEY = "sample";
private static final int ISSUE_MESSAGE_MAX_LENGTH = 1_333;
assertThat(issue.message()).isEqualTo("Issue With Custom Message");
}
+ @Test
+ public void fail_if_message_contains_null_character(){
+ ORCHESTRATOR.getServer().provisionProject(SAMPLE_PROJECT_KEY, SAMPLE_PROJECT_KEY);
+ ItUtils.restoreProfile(ORCHESTRATOR, getClass().getResource("/issue/IssueCreationTest/with-custom-message.xml"));
+ ORCHESTRATOR.getServer().associateProjectToQualityProfile(SAMPLE_PROJECT_KEY, "xoo", "with-custom-message");
+
+ thrown.expect(java.lang.IllegalStateException.class);
+
+ runProjectAnalysis(ORCHESTRATOR, "shared/xoo-sample", "sonar.customMessage.message", "a \u0000 0message");
+ }
+
@Test
public void plugin_can_override_profile_severity() {
ORCHESTRATOR.getServer().provisionProject(SAMPLE_PROJECT_KEY, SAMPLE_PROJECT_KEY);