← Back to team overview

mosquitto-users team mailing list archive

Re: Payload support Unicode/UTF-8? (mosquitto Python client)

 

Fixed this bug by adding a proper string length calculation before passing the arguments to the lib function. 

- (void)publishString: (NSString *)payload toTopic:(NSString *)topic withQos:(NSUInteger)qos retain:(BOOL)retain {
    const char* cstrTopic = [topic cStringUsingEncoding:NSUTF8StringEncoding];
    const uint8_t* cstrPayload = (const uint8_t*)[payload cStringUsingEncoding:NSUTF8StringEncoding];
    size_t cstrlen = [payload lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    mosquitto_publish(mosq, NULL, cstrTopic, cstrlen, cstrPayload, qos, retain);

}

For others who might use this wrapper to send non-ASCII message, also pushed this to github branch:
https://github.com/horacex/marquette
also updated the pull request to original repo. 

I thought it was caused by my Python code, so spent two days understanding unicode/utf-8 with python, lessons learned. I should have think out the issue is caused by the client earlier.

thanks a lot for helping me narrowing down the problem. 

-Horace


On Mar 18, 2013, at 8:32 PM, horace <contactyunkong@xxxxxxxxx> wrote:

> Sorry. I should say it crashed "the client on the server side due to payload decode failure"  
> 
> Your mosquitto broker is healthy :)
> 
> On Mar 18, 2013, at 6:40 PM, Roger Light <roger@xxxxxxxxxx> wrote:
> 
>> Hi Horace,
>> 
>> I presume you intended this to come to the list rather than just me.
>> 
>>> I tried to pass a Chinese NSString to this method, it actually crashed the
>>> server again, Payload print out as ?.
>> 
>> It crashed mosquitto the broker? I'm definitely interested in that!
>> 
>>> So I think the problem happens either
>>> when this method creating the payload (using NSUTF8StringEncoding) or when
>>> the arguments are passed. I noticed it used [payload length] which is
>>> calculating how many char in the string text, is it ok? or it should
>>> actually using the length of cstrPayload, which is the UTF8 coded CString?
>> 
>> Ultimately the payload length needs to be the number of bytes in
>> cstrPayload, so it seems quite likely you are right that this is where
>> the error is occurring.
>> 
>> Cheers,
>> 
>> Roger
>> 
>> 
>> On Mon, Mar 18, 2013 at 7:50 AM, horace <contactyunkong@xxxxxxxxx> wrote:
>>> Thanks a lot for the help Roger.
>>> 
>>> I tried your code on my server, it works smoothly. all Chinese char are
>>> displayed correctly. So I start to guess it may caused by the payload string
>>> sent from my iPhone app.
>>> 
>>> I am using this wrapper on iPhone to use the libmosquitto (1.1.3):
>>> https://github.com/horacex/marquette
>>> 
>>> I noticed in the MosquittoClient class, the publish method looks like this:
>>> https://github.com/horacex/marquette/blob/master/Classes/MosquittoClient.m#L156
>>> 
>>> - (void)publishString: (NSString *)payload toTopic:(NSString *)topic
>>> withQos:(NSUInteger)qos retain:(BOOL)retain {
>>>   const char* cstrTopic = [topic
>>> cStringUsingEncoding:NSUTF8StringEncoding];
>>>   const uint8_t* cstrPayload = (const uint8_t*)[payload
>>> cStringUsingEncoding:NSUTF8StringEncoding];
>>>   mosquitto_publish(mosq, NULL, cstrTopic, [payload length], cstrPayload,
>>> qos, retain);
>>> 
>>> }
>>> 
>>> I tried to pass a Chinese NSString to this method, it actually crashed the
>>> server again, Payload print out as ?. So I think the problem happens either
>>> when this method creating the payload (using NSUTF8StringEncoding) or when
>>> the arguments are passed. I noticed it used [payload length] which is
>>> calculating how many char in the string text, is it ok? or it should
>>> actually using the length of cstrPayload, which is the UTF8 coded CString?
>>> 
>>> Will do some test.
>>> 
>>> 
>>> int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic,
>>> int payloadlen, const void *payload, int qos, bool retain)
>>> {
>>> struct mosquitto_message_all *message;
>>> uint16_t local_mid;
>>> 
>>> if(!mosq || !topic || qos<0 || qos>2) return MOSQ_ERR_INVAL;
>>> if(strlen(topic) == 0) return MOSQ_ERR_INVAL;
>>> if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return
>>> MOSQ_ERR_PAYLOAD_SIZE;
>>> 
>>> if(_mosquitto_topic_wildcard_len_check(topic) != MOSQ_ERR_SUCCESS){
>>> return MOSQ_ERR_INVAL;
>>> }
>>> 
>>> local_mid = _mosquitto_mid_generate(mosq);
>>> if(mid){
>>> *mid = local_mid;
>>> }
>>> 
>>> if(qos == 0){
>>> return _mosquitto_send_publish(mosq, local_mid, topic, payloadlen, payload,
>>> qos, retain, false);
>>> }else{
>>> message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all));
>>> if(!message) return MOSQ_ERR_NOMEM;
>>> 
>>> message->next = NULL;
>>> message->timestamp = time(NULL);
>>> message->direction = mosq_md_out;
>>> if(qos == 1){
>>> message->state = mosq_ms_wait_puback;
>>> }else if(qos == 2){
>>> message->state = mosq_ms_wait_pubrec;
>>> }
>>> message->msg.mid = local_mid;
>>> message->msg.topic = _mosquitto_strdup(topic);
>>> if(!message->msg.topic){
>>> _mosquitto_message_cleanup(&message);
>>> return MOSQ_ERR_NOMEM;
>>> }
>>> if(payloadlen){
>>> message->msg.payloadlen = payloadlen;
>>> message->msg.payload = _mosquitto_malloc(payloadlen*sizeof(uint8_t));
>>> if(!message->msg.payload){
>>> _mosquitto_message_cleanup(&message);
>>> return MOSQ_ERR_NOMEM;
>>> }
>>> memcpy(message->msg.payload, payload, payloadlen*sizeof(uint8_t));
>>> }else{
>>> message->msg.payloadlen = 0;
>>> message->msg.payload = NULL;
>>> }
>>> message->msg.qos = qos;
>>> message->msg.retain = retain;
>>> message->dup = false;
>>> 
>>> _mosquitto_message_queue(mosq, message);
>>> return _mosquitto_send_publish(mosq, message->msg.mid, message->msg.topic,
>>> message->msg.payloadlen, message->msg.payload, message->msg.qos,
>>> message->msg.retain, message->dup);
>>> }
>>> }
>>> 
>>> 
>>> On Mar 18, 2013, at 1:01 AM, Roger Light <roger@xxxxxxxxxx> wrote:
>>> 
>>> Hi Horace,
>>> 
>>> Is there any chance you could post a non-working demo? I've just put
>>> together an example that works: https://gist.github.com/oojah/5182443
>>> Could you give that a try as well? It would be good to know where
>>> things are going wrong.
>>> 
>>> Regards,
>>> 
>>> Roger
>>> 
>>> 
> 


Follow ups

References