From a9299d47744dac7a17940f93d478894e9da4788b Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Thu, 19 May 2016 15:59:50 -0400 Subject: [PATCH] Fix: Correctly compute Java agent list loggers response size The code was assuming that (number of characters == number of bytes), which is not always the case! The notions of number of bytes and data sizes only make sense when the strings are encoded into byte arrays. The response's getBytes() method should the only one handling these concepts. Signed-off-by: Alexandre Montplaisir Signed-off-by: Mathieu Desnoyers --- .../ust/agent/client/SessiondCommand.java | 8 +++--- .../client/SessiondListLoggersCommand.java | 25 +++++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java index 7cde4a35..8b04f4bb 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java @@ -82,17 +82,17 @@ abstract class SessiondCommand { * formatted. */ protected static String readNextString(ByteBuffer buffer) { - int length = buffer.getInt(); - if (length < 0) { + int nbBytes = buffer.getInt(); + if (nbBytes < 0) { /* The string length should be positive */ return null; } - if (length == 0) { + if (nbBytes == 0) { /* The string is explicitly an empty string */ return ""; } - byte[] stringBytes = new byte[length]; + byte[] stringBytes = new byte[nbBytes]; buffer.get(stringBytes); return new String(stringBytes, SESSIOND_PROTOCOL_CHARSET).trim(); } diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java index 1c7ef9b4..4dee6ae4 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java @@ -34,13 +34,7 @@ class SessiondListLoggersCommand extends SessiondCommand { @Override public LttngAgentResponse execute(ILttngTcpClientListener agent) { final Collection loggerList = agent.listAvailableEvents(); - int dataSize = 0; - - for (String event : agent.listAvailableEvents()) { - dataSize += event.length() + 1; - } - - return new SessiondListLoggersResponse(loggerList, dataSize); + return new SessiondListLoggersResponse(loggerList); } private static class SessiondListLoggersResponse extends LttngAgentResponse { @@ -48,11 +42,9 @@ class SessiondListLoggersCommand extends SessiondCommand { private final static int SIZE = 12; private final Collection loggers; - private final int dataSize; - public SessiondListLoggersResponse(Collection loggers, int dataSize) { + public SessiondListLoggersResponse(Collection loggers) { this.loggers = loggers; - this.dataSize = dataSize; } @Override @@ -63,15 +55,26 @@ class SessiondListLoggersCommand extends SessiondCommand { @Override public byte[] getBytes() { + /* + * Compute the data size, which is the number of bytes of each + * encoded string, +1 per string for the \0 + */ + int dataSize = 0; + for (String logger : loggers) { + dataSize += logger.getBytes(SESSIOND_PROTOCOL_CHARSET).length + 1; + } + + /* Prepare the buffer */ byte data[] = new byte[SIZE + dataSize]; ByteBuffer buf = ByteBuffer.wrap(data); buf.order(ByteOrder.BIG_ENDIAN); - /* Returned code */ + /* Write the header section of the response */ buf.putInt(getReturnCode().getCode()); buf.putInt(dataSize); buf.putInt(loggers.size()); + /* Write the payload */ for (String logger : loggers) { buf.put(logger.getBytes(SESSIOND_PROTOCOL_CHARSET)); /* NULL terminated byte after the logger name. */ -- 2.34.1