Skip to content

Commit 1fe1dcc

Browse files
Merge pull request firmata#76 from firmata/memory-leak-fix
fixed memory leak in string buffer
2 parents 1bb88b1 + f1c6f12 commit 1fe1dcc

File tree

4 files changed

+24
-22
lines changed

4 files changed

+24
-22
lines changed

Firmata.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,17 +170,24 @@ void FirmataClass::processSysexMessage(void)
170170
case STRING_DATA:
171171
if(currentStringCallback) {
172172
byte bufferLength = (sysexBytesRead - 1) / 2;
173-
char *buffer = (char*)malloc(bufferLength * sizeof(char));
174173
byte i = 1;
175174
byte j = 0;
176175
while(j < bufferLength) {
177-
buffer[j] = (char)storedInputData[i];
176+
// The string length will only be at most half the size of the
177+
// stored input buffer so we can decode the string within the buffer.
178+
storedInputData[j] = storedInputData[i];
178179
i++;
179-
buffer[j] += (char)(storedInputData[i] << 7);
180+
storedInputData[j] += (storedInputData[i] << 7);
180181
i++;
181182
j++;
182183
}
183-
(*currentStringCallback)(buffer);
184+
// Make sure string is null terminated. This may be the case for data
185+
// coming from client libraries in languages that don't null terminate
186+
// strings.
187+
if (storedInputData[j-1] != '\0') {
188+
storedInputData[j] = '\0';
189+
}
190+
(*currentStringCallback)((char*)&storedInputData[0]);
184191
}
185192
break;
186193
default:

Firmata.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
* installed firmware. */
2222
#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
2323
#define FIRMATA_MINOR_VERSION 3 // for backwards compatible changes
24-
#define FIRMATA_BUGFIX_VERSION 6 // for bugfix releases
24+
#define FIRMATA_BUGFIX_VERSION 7 // for bugfix releases
2525

26-
#define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
26+
#define MAX_DATA_BYTES 64 // max number of data bytes in incoming messages
2727

2828
// message command bytes (128-255/0x80-0xFF)
2929
#define DIGITAL_MESSAGE 0x90 // send data for a digital pin

examples/EchoString/EchoString.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void sysexCallback(byte command, byte argc, byte*argv)
2828

2929
void setup()
3030
{
31-
Firmata.setFirmwareVersion(0, 1);
31+
Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
3232
Firmata.attach(STRING_DATA, stringCallback);
3333
Firmata.attach(START_SYSEX, sysexCallback);
3434
Firmata.begin(57600);

test/unit/firmata_test/firmata_test.ino

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,6 @@ void loop()
1818
Test::run();
1919
}
2020

21-
// Note: this test required adding a method (Firmata.unsetFirmwareVersion()) to
22-
// Firmata.cpp solely for the purpose of running this test. The method has been
23-
// removed from Firmata.cpp, but keeping the test here as a recored
24-
// test(setFirmwareVersionDoesNotLeakMemory)
25-
// {
26-
// Firmata.setFirmwareVersion(1, 0);
27-
// int initialMemory = freeMemory();
28-
29-
// Firmata.setFirmwareVersion(1, 0);
30-
31-
// assertEquals(0, initialMemory - freeMemory());
32-
33-
// Firmata.unsetFirmwareVersion();
34-
// }
35-
3621
test(beginPrintsVersion)
3722
{
3823
FakeStream stream;
@@ -140,3 +125,13 @@ test(specifiedDigitalWritePort)
140125

141126
assertEqual(1, _digitalPort);
142127
}
128+
129+
test(setFirmwareVersionDoesNotLeakMemory)
130+
{
131+
Firmata.setFirmwareVersion(1, 0);
132+
int initialMemory = freeMemory();
133+
134+
Firmata.setFirmwareVersion(1, 0);
135+
136+
assertEqual(0, initialMemory - freeMemory());
137+
}

0 commit comments

Comments
 (0)