Skip to content

Commit ec7aad4

Browse files
Merge pull request firmata#41 from mmurdoch/dev
Fixed issue firmata#36 (setFirmwareVersion leaks memory)
2 parents ac9da77 + 99d350b commit ec7aad4

File tree

3 files changed

+42
-65
lines changed

3 files changed

+42
-65
lines changed

Firmata.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ void FirmataClass::endSysex(void)
4949
FirmataClass::FirmataClass()
5050
{
5151
firmwareVersionCount = 0;
52+
firmwareVersionVector = 0;
5253
systemReset();
5354
}
5455

@@ -126,6 +127,9 @@ void FirmataClass::setFirmwareNameAndVersion(const char *name, byte major, byte
126127
firmwareVersionCount = strlen(name) + 2;
127128
filename = name;
128129
}
130+
131+
free(firmwareVersionVector);
132+
129133
firmwareVersionVector = (byte *) malloc(firmwareVersionCount);
130134
firmwareVersionVector[firmwareVersionCount] = 0;
131135
firmwareVersionVector[0] = major;
@@ -136,6 +140,13 @@ void FirmataClass::setFirmwareNameAndVersion(const char *name, byte major, byte
136140
// (char)major, (char)minor, firmwareVersionVector);
137141
}
138142

143+
void FirmataClass::unsetFirmwareVersion()
144+
{
145+
firmwareVersionCount = 0;
146+
free(firmwareVersionVector);
147+
firmwareVersionVector = 0;
148+
}
149+
139150
//------------------------------------------------------------------------------
140151
// Serial Receive Handling
141152

@@ -179,7 +190,7 @@ void FirmataClass::processInput(void)
179190
int command;
180191

181192
// TODO make sure it handles -1 properly
182-
193+
183194
if (parsingSysex) {
184195
if(inputData == END_SYSEX) {
185196
//stop sysex byte

Firmata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class FirmataClass
9898
void printFirmwareVersion(void);
9999
//void setFirmwareVersion(byte major, byte minor); // see macro below
100100
void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
101+
void unsetFirmwareVersion();
101102
/* serial receive handling */
102103
int available(void);
103104
void processInput(void);

test/unit/firmata_test/firmata_test.ino

Lines changed: 29 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -13,83 +13,47 @@ void loop()
1313
suite.run();
1414
}
1515

16-
class InMemoryStream : public Stream
17-
{
18-
public:
19-
virtual ~InMemoryStream()
20-
{
21-
}
22-
23-
size_t write(uint8_t val)
24-
{
25-
_bytesWritten += (char) val;
26-
27-
return size_t(1);
28-
}
29-
30-
void flush()
31-
{
32-
}
33-
34-
const String& bytesWritten()
35-
{
36-
return _bytesWritten;
37-
}
38-
39-
void nextByte(byte b)
40-
{
41-
_nextByte = b;
42-
}
43-
44-
int available()
45-
{
46-
return 1;
47-
}
48-
49-
int read()
50-
{
51-
return _nextByte;
52-
}
53-
54-
int peek()
55-
{
56-
return _nextByte;
57-
}
58-
59-
private:
60-
String _bytesWritten;
61-
byte _nextByte;
62-
};
63-
6416
void assertStringsEqual(Test& __test__, const char* expected, const String& actual)
6517
{
6618
size_t expectedLength = strlen(expected);
6719
assertEquals(expectedLength, actual.length());
68-
for (size_t i = 0; i < strlen(expected); i++)
20+
for (size_t i = 0; i < expectedLength; i++)
6921
{
7022
assertEquals(expected[i], actual[i]);
7123
}
7224
}
7325

26+
test(setFirmwareVersionDoesNotLeakMemory)
27+
{
28+
Firmata.setFirmwareVersion(1, 0);
29+
int initialMemory = freeMemory();
30+
31+
Firmata.setFirmwareVersion(1, 0);
32+
33+
assertEquals(0, initialMemory - freeMemory());
34+
35+
Firmata.unsetFirmwareVersion();
36+
}
37+
7438
test(beginPrintsVersion)
7539
{
76-
InMemoryStream stream;
40+
FakeStream stream;
7741

7842
Firmata.begin(stream);
7943

8044
char expected[] =
8145
{
82-
0xF9, // Version reporting identifier
83-
2, // Major version number
84-
3, // Minor version number
46+
REPORT_VERSION,
47+
FIRMATA_MAJOR_VERSION,
48+
FIRMATA_MINOR_VERSION,
8549
0
8650
};
8751
assertStringsEqual(__test__, expected, stream.bytesWritten());
8852
}
8953

9054
void processMessage(const byte* message, size_t length)
9155
{
92-
InMemoryStream stream;
56+
FakeStream stream;
9357
Firmata.begin(stream);
9458

9559
for (size_t i = 0; i < length; i++)
@@ -107,8 +71,14 @@ void writeToDigitalPort(byte port, int value)
10771
_digitalPortValue = value;
10872
}
10973

74+
void setupDigitalPort() {
75+
_digitalPort = 0;
76+
_digitalPortValue = 0;
77+
}
78+
11079
test(processWriteDigital_0)
11180
{
81+
setupDigitalPort();
11282
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
11383

11484
byte message[] = { DIGITAL_MESSAGE, 0, 0 };
@@ -119,6 +89,7 @@ test(processWriteDigital_0)
11989

12090
test(processWriteDigital_127)
12191
{
92+
setupDigitalPort();
12293
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
12394

12495
byte message[] = { DIGITAL_MESSAGE, 127, 0 };
@@ -127,18 +98,9 @@ test(processWriteDigital_127)
12798
assertEquals(127, _digitalPortValue);
12899
}
129100

130-
test(processWriteDigitalStripsTopBit)
131-
{
132-
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
133-
134-
byte message[] = { DIGITAL_MESSAGE, B11111111, 0 };
135-
processMessage(message, 3);
136-
137-
assertEquals(B01111111, _digitalPortValue);
138-
}
139-
140101
test(processWriteDigital_128)
141102
{
103+
setupDigitalPort();
142104
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
143105

144106
byte message[] = { DIGITAL_MESSAGE, 0, 1 };
@@ -149,6 +111,7 @@ test(processWriteDigital_128)
149111

150112
test(processWriteLargestDigitalValue)
151113
{
114+
setupDigitalPort();
152115
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
153116

154117
byte message[] = { DIGITAL_MESSAGE, 0x7F, 0x7F };
@@ -160,6 +123,7 @@ test(processWriteLargestDigitalValue)
160123

161124
test(defaultDigitalWritePortIsZero)
162125
{
126+
setupDigitalPort();
163127
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
164128

165129
byte message[] = { DIGITAL_MESSAGE, 0, 0 };
@@ -170,6 +134,7 @@ test(defaultDigitalWritePortIsZero)
170134

171135
test(specifiedDigitalWritePort)
172136
{
137+
setupDigitalPort();
173138
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
174139

175140
byte message[] = { DIGITAL_MESSAGE + 1, 0, 0 };

0 commit comments

Comments
 (0)