Skip to content

Commit b97da08

Browse files
authored
[chip-tool] Add support for hex:/str: prefixed OCTET_STRING for complex arguments instead of always assuming this is an hex string (#23967)
1 parent 8a9ac9b commit b97da08

File tree

4 files changed

+96
-17
lines changed

4 files changed

+96
-17
lines changed

examples/chip-tool/commands/clusters/ComplexArgument.h

+49-7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@
1616
*
1717
*/
1818

19+
/**
20+
* This file allocate/free memory using the chip platform abstractions
21+
* (Platform::MemoryCalloc and Platform::MemoryFree) for hosting a subset of the
22+
* data model internal types until they are consumed by the DataModel::Encode machinery:
23+
* - chip::app:DataModel::List<T>
24+
* - chip::ByteSpan
25+
* - chip::CharSpan
26+
*
27+
* Memory allocation happens during the 'Setup' phase, while memory deallocation happens
28+
* during the 'Finalize' phase.
29+
*
30+
* The 'Finalize' phase during the destructor phase, and if needed, 'Finalize' will call
31+
* the 'Finalize' phase of its descendant.
32+
*/
33+
1934
#pragma once
2035

2136
#include <app-common/zap-generated/cluster-objects.h>
@@ -173,17 +188,44 @@ class ComplexArgumentParser
173188
return CHIP_ERROR_INVALID_ARGUMENT;
174189
}
175190

176-
if (strlen(value.asCString()) % 2 != 0)
191+
auto str = value.asString();
192+
auto size = str.size();
193+
uint8_t * buffer = nullptr;
194+
195+
if (IsStrString(str.c_str()))
177196
{
178-
ChipLogError(chipTool, "Error while encoding %s as an octet string: Odd number of characters.", label);
179-
return CHIP_ERROR_INVALID_STRING_LENGTH;
197+
// Skip the prefix
198+
str.erase(0, kStrStringPrefixLen);
199+
size = str.size();
200+
201+
buffer = static_cast<uint8_t *>(chip::Platform::MemoryCalloc(size, sizeof(uint8_t)));
202+
memcpy(buffer, str.c_str(), size);
180203
}
204+
else
205+
{
206+
if (IsHexString(str.c_str()))
207+
{
208+
// Skip the prefix
209+
str.erase(0, kHexStringPrefixLen);
210+
size = str.size();
211+
}
212+
213+
if (size % 2 != 0)
214+
{
215+
ChipLogError(chipTool, "Error while encoding %s as a hex string: Odd number of characters.", label);
216+
return CHIP_ERROR_INVALID_STRING_LENGTH;
217+
}
181218

182-
size_t size = strlen(value.asCString());
183-
auto buffer = static_cast<uint8_t *>(chip::Platform::MemoryCalloc(size / 2, sizeof(uint8_t)));
184-
size_t octetCount = chip::Encoding::HexToBytes(value.asCString(), size, buffer, size / 2);
219+
buffer = static_cast<uint8_t *>(chip::Platform::MemoryCalloc(size / 2, sizeof(uint8_t)));
220+
size = chip::Encoding::HexToBytes(str.c_str(), size, buffer, size / 2);
221+
if (size == 0)
222+
{
223+
ChipLogError(chipTool, "Error while encoding %s as a hex string.", label);
224+
return CHIP_ERROR_INTERNAL;
225+
}
226+
}
185227

186-
request = chip::ByteSpan(buffer, octetCount);
228+
request = chip::ByteSpan(buffer, size);
187229
return CHIP_NO_ERROR;
188230
}
189231

examples/chip-tool/commands/clusters/JsonParser.h

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#pragma once
2020

21+
#include "../common/CustomStringPrefix.h"
22+
2123
#include <json/json.h>
2224
#include <lib/core/Optional.h>
2325

examples/chip-tool/commands/common/Command.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
*/
1818

1919
#include "Command.h"
20+
#include "CustomStringPrefix.h"
21+
#include "platform/PlatformManager.h"
2022

2123
#include <functional>
2224
#include <netdb.h>
@@ -362,10 +364,9 @@ bool Command::InitArgument(size_t argIndex, char * argValue)
362364
// We support two ways to pass an octet string argument. If it happens
363365
// to be all-ASCII, you can just pass it in. Otherwise you can pass in
364366
// "hex:" followed by the hex-encoded bytes.
365-
size_t argLen = strlen(argValue);
366-
static constexpr char hexPrefix[] = "hex:";
367-
constexpr size_t prefixLen = ArraySize(hexPrefix) - 1; // Don't count the null
368-
if (strncmp(argValue, hexPrefix, prefixLen) == 0)
367+
size_t argLen = strlen(argValue);
368+
369+
if (IsHexString(argValue))
369370
{
370371
// Hex-encoded. Decode it into a temporary buffer first, so if we
371372
// run into errors we can do correct "argument is not valid" logging
@@ -381,7 +382,8 @@ bool Command::InitArgument(size_t argIndex, char * argValue)
381382
return false;
382383
}
383384

384-
size_t octetCount = chip::Encoding::HexToBytes(argValue + prefixLen, argLen - prefixLen, buffer.Get(), argLen);
385+
size_t octetCount =
386+
chip::Encoding::HexToBytes(argValue + kHexStringPrefixLen, argLen - kHexStringPrefixLen, buffer.Get(), argLen);
385387
if (octetCount == 0)
386388
{
387389
return false;
@@ -393,13 +395,11 @@ bool Command::InitArgument(size_t argIndex, char * argValue)
393395
}
394396

395397
// Just ASCII. Check for the "str:" prefix.
396-
static constexpr char strPrefix[] = "str:";
397-
constexpr size_t strPrefixLen = ArraySize(strPrefix) - 1; // Don't count the null
398-
if (strncmp(argValue, strPrefix, strPrefixLen) == 0)
398+
if (IsStrString(argValue))
399399
{
400400
// Skip the prefix
401-
argValue += strPrefixLen;
402-
argLen -= strPrefixLen;
401+
argValue += kStrStringPrefixLen;
402+
argLen -= kStrStringPrefixLen;
403403
}
404404
*value = chip::ByteSpan(chip::Uint8::from_char(argValue), argLen);
405405
return true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2022 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
#pragma once
20+
21+
static constexpr char kHexStringPrefix[] = "hex:";
22+
constexpr size_t kHexStringPrefixLen = ArraySize(kHexStringPrefix) - 1; // Don't count the null
23+
24+
static constexpr char kStrStringPrefix[] = "str:";
25+
constexpr size_t kStrStringPrefixLen = ArraySize(kStrStringPrefix) - 1; // Don't count the null
26+
27+
inline bool IsHexString(const char * str)
28+
{
29+
return strncmp(str, kHexStringPrefix, kHexStringPrefixLen) == 0;
30+
}
31+
32+
inline bool IsStrString(const char * str)
33+
{
34+
return strncmp(str, kStrStringPrefix, kStrStringPrefixLen) == 0;
35+
}

0 commit comments

Comments
 (0)