Question about accessing fields in Notecard response

Hello
I have questions about the C code used to access Notecard response:

The example code below is given (in the Arduino library documentation) for retrieving data from the “card.status” request:

char status[20];
if (J *req = notecard.newRequest("card.status")) {
    J *rsp = notecard.requestAndResponse(req);
    notecard.logDebug(JConvertToJSONString(rsp));

    bool connected = JGetBool(rsp, "connected");
    char *tempStatus = JGetString(rsp, "status");
    strlcpy(status, tempStatus, sizeof(status));
    int storage = JGetInt(rsp, "storage");
    int time = JGetInt(rsp, "time");
    bool cell = JGetBool(rsp, "cell");

    notecard.deleteResponse(rsp);
}

I have two questions:

  1. in the line char *tempStatus = JGetString(rsp, "status");
    Since *tempStatus is simply a pointer to the start of a memory area which is going to be overwritten by JGetString( … ), what stops this overwriting other data which may be in memory after the *tempStatus location?

  2. The line strlcpy(status, tempStatus, sizeof(status)); is meant to write the data starting at “tempStatus”, to the location starting at “status”, for "sizeof(status) bytes.
    Shouldn’t it be “sizeof(tempStatus)” instead of “siizeof(status)”?

Thanks
Gary

Hi @GaryQ and welcome to the Blues forum!

I love that you’ve been looking through the implementation and trying to find areas to improve; this is the beauty of open-source software!

  1. Nothing. You are able to corrupt the response you requested from the Notecard if you so choose.

    Admittedly, this is not ideal, and an excellent observation. I agree it would be nice to get a compiler warning if you were about to modify the result, because it is unlikely that would be your intention.
    IIRC, the response buffer is provided exclusively for the user application (and is not consumed by the library), so there is a limited scope to any side-effects from making such a mistake. We are currently investigating the scope of changing this function result, and a handful of other results, over to a const char *, as you have suggested.

  2. No. The size of the buffer is more important, because we could accidentally create a non-NUL-terminated string without it.

    From the strlcpy() man page:

    strlcpy() and strlcat() take the full size of the buffer (not just the length) and guarantee to NUL-terminate the result (as long as size is larger than 0 or, in the case of strlcat(), as long as there is at least one byte free in dst ). Note that a byte for the NUL should be included in size . Also note that strlcpy() and strlcat() only operate on true ‘‘C’’ strings. This means that for strlcpy() src must be NUL-terminated …

    https://linux.die.net/man/3/strlcpy

Sorry for the delay in responding, your message somehow slipped through the cracks. I really do appreciate the thoughtfulness of this post, and we ALWAYS welcome questions and suggestions for improvement like yours!

Sincerely,
Zak

hi Zak
Thanks for the reply.

I’ve been experimenting a lot with the BluesWireless notecard and understand the potential pitfalls a lot better.

BTW, the generally excellent documentation in BW pages is a real help - esp the large number of examples. Great!
It’s such a difference working with the JSON-based BW notecards compared to Telit and Quectel AT-based modules I’ve been using in the past.
Gary

4 Likes