-
-
Notifications
You must be signed in to change notification settings - Fork 86
Fix #139: Handle non-ASCII characters correctly when annotating text #143
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
Changes from 4 commits
3506cfb
cc93232
e324c82
0ff2f82
ffb5045
bee95aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,12 +50,10 @@ final class ColorConsoleAnnotator extends ConsoleAnnotator<Object> { | |
| private static final long serialVersionUID = 1; | ||
|
|
||
| private final String colorMapName; | ||
| private final String charset; | ||
|
|
||
| ColorConsoleAnnotator(String colorMapName, String charset) { | ||
| ColorConsoleAnnotator(String colorMapName) { | ||
| this.colorMapName = colorMapName; | ||
| this.charset = charset; | ||
| LOGGER.fine("creating annotator with colorMapName=" + colorMapName + " charset=" + charset); | ||
| LOGGER.fine("creating annotator with colorMapName=" + colorMapName); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -70,12 +68,12 @@ class EmitterImpl implements AnsiAttributeElement.Emitter { | |
| int lastPoint = -1; // multiple HTML tags may be emitted for one control sequence | ||
| @Override | ||
| public void emitHtml(String html) { | ||
| LOGGER.finest("emitting " + html + " @" + incoming.getCount()); | ||
| LOGGER.log(Level.FINEST, "emitting {0} @{1}/{2}", new Object[] { html, incoming.getCount(), s.length() }); | ||
| text.addMarkup(incoming.getCount(), html); | ||
| if (incoming.getCount() != lastPoint) { | ||
| lastPoint = incoming.getCount(); | ||
| int hide = incoming.getCount() - outgoing.getCount() - adjustment; | ||
| LOGGER.finest("hiding " + hide + " @" + (outgoing.getCount() + adjustment)); | ||
| LOGGER.log(Level.FINEST, "hiding {0} @{1}", new Object[] { hide, outgoing.getCount() + adjustment }); | ||
| text.addMarkup(outgoing.getCount() + adjustment, outgoing.getCount() + adjustment + hide, "<!--", "-->"); | ||
| adjustment += hide; | ||
| } | ||
|
|
@@ -85,7 +83,14 @@ public void emitHtml(String html) { | |
| CountingOutputStream incoming = new CountingOutputStream(new AnsiHtmlOutputStream(outgoing, colorMap, emitter)); | ||
| emitter.incoming = incoming; | ||
| try { | ||
| byte[] data = s.getBytes(charset); | ||
| /* | ||
| * We only use AnsiHtmlOutputStream for its calls to Emitter.emitHtml when it encounters ANSI escape | ||
| * sequences. The output of the stream will be discarded. We encode the String using US_ASCII because | ||
| * all ANSI escape sequences can be represented in ASCII using a single byte, and any non-ASCII | ||
| * characters will be replaced with '?', which is good, since it means that byte offsets will match | ||
|
||
| * character offsets in the emitter without any extra work. | ||
| */ | ||
| byte[] data = s.getBytes("US-ASCII"); | ||
| for (int i = 0; i < data.length; i++) { | ||
| // Do not use write(byte[]) as offsets in incoming would not be accurate. | ||
| incoming.write(data[i]); | ||
|
|
@@ -107,7 +112,7 @@ public ConsoleAnnotator<Object> newInstance(Object context) { | |
| if (context instanceof Run) { | ||
| ColorizedAction action = ((Run) context).getAction(ColorizedAction.class); | ||
| if (action != null) { | ||
| return new ColorConsoleAnnotator(action.colorMapName, ((Run) context).getCharset().name()); | ||
| return new ColorConsoleAnnotator(action.colorMapName); | ||
| } | ||
| } else if (Jenkins.get().getPlugin("workflow-api") != null && context instanceof FlowNode) { | ||
| FlowNode node = (FlowNode) context; | ||
|
|
@@ -122,7 +127,7 @@ public ConsoleAnnotator<Object> newInstance(Object context) { | |
| if (exec instanceof Run) { | ||
| ColorizedAction action = ((Run) exec).getAction(ColorizedAction.class); | ||
| if (action != null) { | ||
| return new ColorConsoleAnnotator(action.colorMapName, /* JEp-206 */ "UTF-8"); | ||
| return new ColorConsoleAnnotator(action.colorMapName); | ||
| } | ||
| } | ||
| } | ||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this could cause issues if someone upgraded the plugin to the version with this fix and then downgraded to 0.6.0, but it's not clear to me what the lifecycle of a serialized
ConsoleAnnotatorwould be to know for sure if it would matter.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is only serialized while a
consolepage for a running build is being held open, so I do not think you need to care.