aboutsummaryrefslogtreecommitdiffstats
path: root/facebook/facebook-thrift.c
diff options
context:
space:
mode:
authorjgeboski <jgeboski@gmail.com>2015-12-31 16:11:55 -0500
committerjgeboski <jgeboski@gmail.com>2016-01-01 19:37:58 -0500
commit56d729851a1a431cbdd28b9c5626fd7e1c86d9e0 (patch)
tree8e3558e5f14c0a9d5c392132317b837da5e6e527 /facebook/facebook-thrift.c
parentfd4e4f7195c0fe93713c25d40ce6edaf600a00c6 (diff)
downloadbitlbee-facebook-56d729851a1a431cbdd28b9c5626fd7e1c86d9e0.tar.gz
bitlbee-facebook-56d729851a1a431cbdd28b9c5626fd7e1c86d9e0.tar.bz2
bitlbee-facebook-56d729851a1a431cbdd28b9c5626fd7e1c86d9e0.tar.xz
facebook-api: properly handle optional Thrift fields and scoping
The plugin is required to read Thrift data for the presence states of contacts. The data which is being read has some optional fields, which are rarely not supplied. This has led to this bug being undiscovered for quite some time. Not only was the plugin not properly accounting for optional fields, but also did not account for field scoping. This is not really an issue until a Thrift list is being read, which will cause the identifier to grow with each field read, rather than reset. The field identifier is only relevant to its local scope, nothing more. More importantly, the identifier must be reset with each iteration of a list.
Diffstat (limited to 'facebook/facebook-thrift.c')
-rw-r--r--facebook/facebook-thrift.c37
1 files changed, 15 insertions, 22 deletions
diff --git a/facebook/facebook-thrift.c b/facebook/facebook-thrift.c
index bde1eb1..9604e4d 100644
--- a/facebook/facebook-thrift.c
+++ b/facebook/facebook-thrift.c
@@ -26,7 +26,6 @@ struct _FbThriftPrivate
guint offset;
guint pos;
guint lastbool;
- gint16 lastid;
};
G_DEFINE_TYPE(FbThrift, fb_thrift, G_TYPE_OBJECT);
@@ -330,7 +329,8 @@ fb_thrift_read_str(FbThrift *thft, gchar **value)
}
gboolean
-fb_thrift_read_field(FbThrift *thft, FbThriftType *type, gint16 *id)
+fb_thrift_read_field(FbThrift *thft, FbThriftType *type, gint16 *id,
+ gint16 lastid)
{
FbThriftPrivate *priv;
gint16 i16;
@@ -338,6 +338,7 @@ fb_thrift_read_field(FbThrift *thft, FbThriftType *type, gint16 *id)
g_return_val_if_fail(FB_IS_THRIFT(thft), FALSE);
g_return_val_if_fail(type != NULL, FALSE);
+ g_return_val_if_fail(id != NULL, FALSE);
priv = thft->priv;
if (!fb_thrift_read_byte(thft, &byte)) {
@@ -352,29 +353,22 @@ fb_thrift_read_field(FbThrift *thft, FbThriftType *type, gint16 *id)
*type = fb_thrift_ct2t(byte & 0x0F);
i16 = (byte & 0xF0) >> 4;
- if (*type == FB_THRIFT_TYPE_BOOL) {
- priv->lastbool = 0x01;
-
- if ((byte & 0x0F) == 0x01) {
- priv->lastbool |= 0x01 << 2;
- }
-
- return TRUE;
- }
-
if (i16 == 0) {
- if (!fb_thrift_read_i16(thft, &i16)) {
+ if (!fb_thrift_read_i16(thft, id)) {
return FALSE;
}
} else {
- i16 = priv->lastid + i16;
+ *id = lastid + i16;
}
- if (id != NULL) {
- *id = i16;
+ if (*type == FB_THRIFT_TYPE_BOOL) {
+ priv->lastbool = 0x01;
+
+ if ((byte & 0x0F) == 0x01) {
+ priv->lastbool |= 0x01 << 2;
+ }
}
- priv->lastid = i16;
return TRUE;
}
@@ -585,7 +579,8 @@ fb_thrift_write_str(FbThrift *thft, const gchar *value)
}
void
-fb_thrift_write_field(FbThrift *thft, FbThriftType type, gint16 id)
+fb_thrift_write_field(FbThrift *thft, FbThriftType type, gint16 id,
+ gint16 lastid)
{
FbThriftPrivate *priv;
gint16 diff;
@@ -598,16 +593,14 @@ fb_thrift_write_field(FbThrift *thft, FbThriftType type, gint16 id)
}
type = fb_thrift_t2ct(type);
- diff = id - priv->lastid;
+ diff = id - lastid;
- if ((id <= priv->lastid) || (diff > 0x0F)) {
+ if ((id <= lastid) || (diff > 0x0F)) {
fb_thrift_write_byte(thft, type);
fb_thrift_write_i16(thft, id);
} else {
fb_thrift_write_byte(thft, (diff << 4) | type);
}
-
- priv->lastid = id;
}
void