From: Ana Bobillo <[email protected]>
Issue #401 reported the type 6 DAC 1 FID 28 and type 8 DAC 1 FID 27 Route Information decoders writing past waypoints[16]. Since 424064a5b the decode loops stop at ROWS(waypoints) and at the end of the message, but waycount is still the raw 5 bit field, 0 to 31. json_aivdm_dump() loops to waycount, so a route with a waycount above 16 is dumped with reads past the end of waypoints[16], and one with fewer waypoints than its waycount is dumped with waypoints the message never sent.
Set waycount to the number of waypoints decoded, as is already done for ncargos, ntidals, ntargets and ngauges. waycount itself is not dumped (www/AIVDM.adoc), and the libgps JSON parser already sets it to the number of waypoints read. Add three synthetic Route Information samples to test/sample.aivdm, two of them with a waycount of 31 and fewer waypoints sent, and regenerate the test/sample.aivdm*.chk files. Signed-off-by: Ana Bobillo <[email protected]> --- Tested: scons check passes. Without the driver_ais.c change, gpsdecode prints 31 waypoints for the two new waycount 31 samples, and a gpsdecode built with -fsanitize=undefined -fstrict-flex-arrays=3 reports "index 16 out of bounds for type 'waypoint_t [16]'" in json_aivdm_dump(). The .chk files were regenerated with the gpsdecode commands of aivdm-makeregress, run by hand: that target did not expand its quoted "test/*.aivdm" glob here. Their lines end in CRLF, which this attachment keeps; git am applies it as is, with a "quoted CRLF detected" warning. drivers/driver_ais.c | 2 ++ test/sample.aivdm | 10 ++++++++++ test/sample.aivdm.chk | 3 +++ test/sample.aivdm.js.chk | 3 +++ test/sample.aivdm.ju.chk | 3 +++ 5 files changed, 21 insertions(+) diff --git a/drivers/driver_ais.c b/drivers/driver_ais.c index a11220172..277c0d659 100644 --- a/drivers/driver_ais.c +++ b/drivers/driver_ais.c @@ -447,6 +447,7 @@ bool ais_binary_decode(const struct gpsd_errout_t *errout, ais->type6.dac1fid28.waypoints[u].lon = SBITS(off + 0, 28); ais->type6.dac1fid28.waypoints[u].lat = SBITS(off + 28, 27); } + ais->type6.dac1fid28.waycount = u; #undef ARRAY_BASE #undef ELEMENT_SIZE ais->type6.structured = true; @@ -781,6 +782,7 @@ bool ais_binary_decode(const struct gpsd_errout_t *errout, ais->type8.dac1fid27.waypoints[u].lon = SBITS(off + 0, 28); ais->type8.dac1fid27.waypoints[u].lat = SBITS(off + 28, 27); } + ais->type8.dac1fid27.waycount = u; #undef ARRAY_BASE #undef ELEMENT_SIZE ais->type8.structured = true; diff --git a/test/sample.aivdm b/test/sample.aivdm index 99b500a59..42cfe3c57 100644 --- a/test/sample.aivdm +++ b/test/sample.aivdm @@ -1074,6 +1074,16 @@ AIVDM,2,2,1,B,00000000000,2*26 !AIVDM,3,3,0,A,Ghm4utWw2P,4*27 # 8|0|002711009|1|16|720:00025e8d136025bd890d5520b2ff0ac000000070202580430d4bbf003f000001027cc3302597b60d4b15003f000000c5c4a9802584cf0d3f45803f000000f47ba58025cdf40d4391003f0000010272bb00258e5f0d44f7c9ff0a # +# Synthetic type 8, DAC 1, FID 27 (IMO 289 Route information - broadcast), +# 3 waypoints +!AIVDM,1,1,,A,83KIkj00Fi=AJfqp0;@HLRRh8Vok@>B4?4CGV079jB29aL4,0*48 +# Same, but the waypoint count says 31. Only the 3 waypoints sent +# may be reported. +!AIVDM,1,1,,A,83KIkj00Fi=AJfqp0;CpLRRh8Vok@>B4?4CGV079jB29aL4,0*73 +# Synthetic type 6, DAC 1, FID 28 (IMO 289 Route information - addressed), +# the waypoint count says 31, but only 2 waypoints are sent. +!AIVDM,1,1,,B,63KIkj0o4d5005hCDFcfN02lv78`d29etl3TQ3i4mqP0,5*0A +# # Extra long type 21 message # from AISHub sample data # has data length of 368 diff --git a/test/sample.aivdm.chk b/test/sample.aivdm.chk index dafa613e4..1b5835d8c 100644 --- a/test/sample.aivdm.chk +++ b/test/sample.aivdm.chk @@ -88,6 +88,9 @@ 8|0|366999607|366|57|510:7ffdef068fbded3c0a1943dfb997b4a10fadec21e6e0a6608f0f44b686a8747ff71e595dcb5ec5b4e05221d886233d2e4916f6eb6fe8ecd38d69792816f3a2d0 8|0|002391100|1|16|240:0000e56a780022b4440a903c3bbf00000130ac568022bab80ad35f803f00 8|0|002711009|1|16|720:00025e8d136025bd890d5520b2ff0ac000000070202580430d4bbf003f000001027cc3302597b60d4b15003f000000c5c4a9802584cf0d3f45803f000000f47ba58025cdf40d4391003f0000010272bb00258e5f0d44f7c9ff0a +8|0|230061000|1|27|226:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +8|0|230061000|1|27|226:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +6|0|230061000|0|230994000|0|1|28|171:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 21|0|004000003|30|IBC G BUOY|1|75943336|22448680|2|2|2|2|1|31|0|0x0|0|0 16|0|439952844|315920|2049|681|230137673|424|419 20|0|002442003|1385|2|7|1125|0|0|0|0|0|0|0|0|0|0|0|0 diff --git a/test/sample.aivdm.js.chk b/test/sample.aivdm.js.chk index 3637b3511..72fcc95eb 100644 --- a/test/sample.aivdm.js.chk +++ b/test/sample.aivdm.js.chk @@ -88,6 +88,9 @@ {"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":366999607,"scaled":true,"dac":366,"fid":57,"data":"510:7ffdef068fbded3c0a1943dfb997b4a10fadec21e6e0a6608f0f44b686a8747ff71e595dcb5ec5b4e05221d886233d2e4916f6eb6fe8ecd38d69792816f3a2d0"} {"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":2391100,"scaled":true,"dac":1,"fid":16,"data":"240:0000e56a780022b4440a903c3bbf00000130ac568022bab80ad35f803f00"} {"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":2711009,"scaled":true,"dac":1,"fid":16,"data":"720:00025e8d136025bd890d5520b2ff0ac000000070202580430d4bbf003f000001027cc3302597b60d4b15003f000000c5c4a9802584cf0d3f45803f000000f47ba58025cdf40d4391003f0000010272bb00258e5f0d44f7c9ff0a"} +{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":230061000,"scaled":true,"dac":1,"fid":27,"linkage":77,"sender":2,"rtype":5,"rtype_text":"Ship route plan","start":"10-23T14:30Z","duration":180,"waypoints":[{"lon":24.9384000,"lat":60.1699000},{"lon":24.9601000,"lat":60.1552000},{"lon":25.0012000,"lat":60.1391000}]} +{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":230061000,"scaled":true,"dac":1,"fid":27,"linkage":77,"sender":2,"rtype":5,"rtype_text":"Ship route plan","start":"10-23T14:30Z","duration":180,"waypoints":[{"lon":24.9384000,"lat":60.1699000},{"lon":24.9601000,"lat":60.1552000},{"lon":25.0012000,"lat":60.1391000}]} +{"class":"AIS","device":"stdin","type":6,"repeat":0,"mmsi":230061000,"scaled":true,"seqno":0,"dest_mmsi":230994000,"retransmit":false,"dac":1,"fid":28,"linkage":77,"sender":2,"rtype":5,"rtype_text":"Ship route plan","start":"10-23T14:30Z","duration":180,"waypoints":[{"lon":24.9384000,"lat":60.1699000},{"lon":24.9601000,"lat":60.1552000}]} {"class":"AIS","device":"stdin","type":21,"repeat":0,"mmsi":4000003,"scaled":true,"aid_type":30,"aid_type_text":"Special Mark","name":"IBC G BUOY","lon":126.5722267,"lat":37.4144667,"accuracy":true,"to_bow":2,"to_stern":2,"to_port":2,"to_starboard":2,"epfd":1,"epfd_text":"GPS","second":31,"regional":0,"off_position":false,"raim":false,"virtual_aid":false} {"class":"AIS","device":"stdin","type":16,"repeat":0,"mmsi":439952844,"scaled":true,"mmsi1":315920,"offset1":2049,"increment1":681,"mmsi2":230137673,"offset2":424,"increment2":419} {"class":"AIS","device":"stdin","type":20,"repeat":0,"mmsi":2442003,"scaled":true,"offset1":1385,"number1":2,"timeout1":7,"increment1":1125,"offset2":0,"number2":0,"timeout2":0,"increment2":0,"offset3":0,"number3":0,"timeout3":0,"increment3":0,"offset4":0,"number4":0,"timeout4":0,"increment4":0} diff --git a/test/sample.aivdm.ju.chk b/test/sample.aivdm.ju.chk index a6759a167..5ed2aa3ab 100644 --- a/test/sample.aivdm.ju.chk +++ b/test/sample.aivdm.ju.chk @@ -88,6 +88,9 @@ {"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":366999607,"scaled":false,"dac":366,"fid":57,"data":"510:7ffdef068fbded3c0a1943dfb997b4a10fadec21e6e0a6608f0f44b686a8747ff71e595dcb5ec5b4e05221d886233d2e4916f6eb6fe8ecd38d69792816f3a2d0"} {"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":2391100,"scaled":false,"dac":1,"fid":16,"data":"240:0000e56a780022b4440a903c3bbf00000130ac568022bab80ad35f803f00"} {"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":2711009,"scaled":false,"dac":1,"fid":16,"data":"720:00025e8d136025bd890d5520b2ff0ac000000070202580430d4bbf003f000001027cc3302597b60d4b15003f000000c5c4a9802584cf0d3f45803f000000f47ba58025cdf40d4391003f0000010272bb00258e5f0d44f7c9ff0a"} +{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":230061000,"scaled":false,"dac":1,"fid":27,"linkage":77,"sender":2,"rtype":5,"rtype_text":"Ship route plan","start":"10-23T14:30Z","duration":180,"waypoints":[{"lon":14963040,"lat":36101940},{"lon":14976060,"lat":36093120},{"lon":15000720,"lat":36083460}]} +{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":230061000,"scaled":false,"dac":1,"fid":27,"linkage":77,"sender":2,"rtype":5,"rtype_text":"Ship route plan","start":"10-23T14:30Z","duration":180,"waypoints":[{"lon":14963040,"lat":36101940},{"lon":14976060,"lat":36093120},{"lon":15000720,"lat":36083460}]} +{"class":"AIS","device":"stdin","type":6,"repeat":0,"mmsi":230061000,"scaled":false,"seqno":0,"dest_mmsi":230994000,"retransmit":false,"dac":1,"fid":28,"linkage":77,"sender":2,"rtype":5,"rtype_text":"Ship route plan","start":"10-23T14:30Z","duration":180,"waypoints":[{"lon":14963040,"lat":36101940},{"lon":14976060,"lat":36093120}]} {"class":"AIS","device":"stdin","type":21,"repeat":0,"mmsi":4000003,"scaled":false,"aid_type":30,"aid_type_text":"Special Mark","name":"IBC G BUOY","accuracy":true,"lon":75943336,"lat":22448680,"to_bow":2,"to_stern":2,"to_port":2,"to_starboard":2,"epfd":1,"epfd_text":"GPS","second":31,"regional":0,"off_position":false,"raim":false,"virtual_aid":false} {"class":"AIS","device":"stdin","type":16,"repeat":0,"mmsi":439952844,"scaled":false,"mmsi1":315920,"offset1":2049,"increment1":681,"mmsi2":230137673,"offset2":424,"increment2":419} {"class":"AIS","device":"stdin","type":20,"repeat":0,"mmsi":2442003,"scaled":false,"offset1":1385,"number1":2,"timeout1":7,"increment1":1125,"offset2":0,"number2":0,"timeout2":0,"increment2":0,"offset3":0,"number3":0,"timeout3":0,"increment3":0,"offset4":0,"number4":0,"timeout4":0,"increment4":0}
