Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
These libraries started life (a long time ago) as simple ‘latitude/longitude’ code fragments covering distances and bearings, intended to help people who had little experience of geodesy, and perhaps limited programming experience.
The intention was to have clear, simple illustrative code samples which could be adapted and re-used in other projects (whether those be coded in JavaScript, Java, C++, Excel VBA, or anything else...). With its untyped C-style syntax, JavaScript reads remarkably close to pseudo-code, exposing the algorithms with a minimum of syntactic distractions
While still valid for that purpose, they have grown since then into considerable libraries, based around:
Complementing these are various mapping-related functions covering:
And also functions for historical datum conversions (such as between NAD83, OSGB36, Irl1975, etc) and modern reference frame conversions (such as ITRF2014, ETRF2000, GDA94, etc), and conversions between geodetic (latitude/longitude) coordinates and geocentric cartesian (x/y/z) coordinates.
There are also supporting libraries:
The spherical-earth model provides simple formulae covering most ‘everyday’ accuracy requirements; the ellipsoidal-earth model provides more accurate formulae at the expense of complexity. The vector-based functions provide an alternative approach to the trig-based functions, with some overlapping functionality; which one to use may depend on availability of related functions or on other considerations.
These functions are as language-agnostic as possible, avoiding excessive use of JavaScript-specific language features which would not be recognised by users of other languages (and which might be difficult to translate to other languages). I use Greek letters in variables representing maths symbols conventionally presented as Greek letters: I value the great benefit in legibility over the minor inconvenience in typing.
This version 2 of the library uses JavaScript ES classes and modules to organise the interdependencies; this makes the code both more immediately readable than previously, and also more accessible to non-JavaScript readers (always bearing in mind JavaScript uses prototype-based classes rather than classical inheritance-based classes). For older browsers (or Node.js <8.0.0), v1.1.3 is ES5-based. Note that there are breaking changes in moving from version 1 to version 2.
While some aspects of the library are quite complex to understand and use, basic usage is simple – for instance:
import LatLon from 'geodesy/latlon-spherical.js';
const p1 = new LatLon(52.205, 0.119);
const p2 = new LatLon(48.857, 2.351);
const d = p1.distanceTo(p2); // 404.3×10³ m
import LatLon from 'geodesy/latlon-ellipsoidal-vincenty.js';
const p1 = new LatLon(-37.95103, 144.42487);
const dist = 54972.271;
const brng = 306.86816;
const p2 = p1.destinationPoint(dist, brng); // 37.6528°S, 143.9265°E
Full documentation is available at www.movable-type.co.uk/scripts/geodesy-library.html, and tests in the browser as well as Travis CI.
While originally intended as illustrative code fragments, these functions can be used ‘as-is’; either client-side in-browser, or with Node.js.
The library can be used in the browser by taking a local copy, or loading it from jsDelivr: for example,
<!doctype html><title>geodesy example</title><meta charset="utf-8">
<script type="module">
import LatLon from 'https://cdn.jsdelivr.net/npm/geodesy@2.4.0/latlon-spherical.min.js';
const p1 = new LatLon(50.06632, -5.71475);
const p2 = new LatLon(58.64402, -3.07009);
const d = p1.distanceTo(p2);
console.assert(d.toFixed(3) == '968874.704');
const mid = p1.midpointTo(p2);
console.assert(mid.toString('dms') == '54° 21′ 44″ N, 004° 31′ 51″ W');
</script>
The library can be loaded from npm to be used in a Node.js app (in Node.js v13.2.0+, or Node.js v12.0.0+ using --experimental-modules, or v8.0.0–v12.15.0*) using the esm package:
$ npm install geodesy
$ node
> const { default: LatLon } = await import('geodesy/latlon-spherical.js');
> const p1 = new LatLon(50.06632, -5.71475);
> const p2 = new LatLon(58.64402, -3.07009);
> const d = p1.distanceTo(p2);
> console.assert(d.toFixed(3) == '968874.704');
> const mid = p1.midpointTo(p2);
> console.assert(mid.toString('dms') == '54° 21′ 44″ N, 004° 31′ 51″ W');
To some extent, mixins can be used to add methods of a class to a different class, e.g.:
import LatLon from 'geodesy/latlon-nvector-ellipsoidal.js';
import LatLonV from 'geodesy/latlon-ellipsoidal-vincenty.js';
for (const method of Object.getOwnPropertyNames(LatLonV.prototype)) {
LatLon.prototype[method] = LatLonV.prototype[method];
}
const d = new LatLon(51, 0).distanceTo(new LatLon(52, 1)); // vincenty
const δ = new LatLon(51, 0).deltaTo(new LatLon(52, 1)); // n-vector
More care is of course required if there are conflicting constructors or method names.
For TypeScript users, type definitions are available from DefinitelyTyped: www.npmjs.com/package/@types/geodesy.
Some examples of calculations possible with the libraries:
e.g. for geodesic distance on an ellipsoidal model earth using Vincenty’s algorithm:
import LatLon from 'geodesy/latlon-ellipsoidal-vincenty.js';
const p1 = new LatLon(50.06632, -5.71475);
const p2 = new LatLon(58.64402, -3.07009);
const d = p1.distanceTo(p2);
console.assert(d.toFixed(3) == '969954.166');
e.g. for UTM conversions:
import Utm from 'geodesy/utm.js';
const utm = Utm.parse('48 N 377298.745 1483034.794');
const latlon = utm.toLatLon();
console.assert(latlon.toString('dms', 2) == '13° 24′ 45.00″ N, 103° 52′ 00.00″ E');
console.assert(latlon.toUtm().toString() == '48 N 377298.745 1483034.794';
e.g. for MGRS/NATO map references:
import Mgrs, { LatLon } from 'geodesy/mgrs.js';
const mgrs = Mgrs.parse('31U DQ 48251 11932');
const latlon = mgrs.toUtm().toLatLon();
console.assert(latlon.toString('dms', 2) == '48° 51′ 29.50″ N, 002° 17′ 40.16″ E');
const p = LatLon.parse('51°28′40.37″N, 000°00′05.29″W');
const ref = p.toUtm().toMgrs();
console.assert(ref.toString() == '30U YC 08215 07233');
e.g. for OS grid references:
import OsGridRef, { LatLon } from 'geodesy/osgridref.js';
const gridref = new OsGridRef(651409.903, 313177.270);
const pWgs84 = gridref.toLatLon();
console.assert(pWgs84.toString('dms', 4) == '52° 39′ 28.7230″ N, 001° 42′ 57.7870″ E');
const pOsgb = gridref.toLatLon(LatLon.datums.OSGB36);
console.assert(pOsgb.toString('dms', 4) == '52° 39′ 27.2531″ N, 001° 43′ 04.5177″ E');
e.g. for testing if a point is enclosed within a polygon:
import LatLon from 'geodesy/latlon-nvector-spherical.js';
const polygon = [ new LatLon(48,2), new LatLon(49,2), new LatLon(49,3), new LatLon(48,3) ];
const enclosed = new LatLon(48.9,2.4).isEnclosedBy(polygon);
console.assert(enclosed == true);
e.g. greater parsing & presentation control:
import LatLon from 'geodesy/latlon-spherical.js';
Dms.separator = ' '; // full-space separator between degrees-minutes-seconds
const p1 = LatLon.parse({ lat: '50:03:59N', lng: '005:42:53W' });
const p2 = LatLon.parse('58°38′38″N, 003°04′12″W');
const mid = p1.midpointTo(p2);
console.assert(mid.toString('dms') == '54° 21′ 44″ N, 004° 31′ 50″ W');
e.g. datum conversions:
import LatLon from 'geodesy/latlon-ellipsoidal-datum.js';
const pWgs84 = new LatLon(53.3444, -6.2577);
const pIrl1975 = pWgs84.convertDatum(LatLon.datums.Irl1975);
console.assert(pIrl1975.toString() == '53.3442° N, 006.2567° W');
(The format of the import statements will vary according to deployment).
[2.4.0] - 2022-03-16
FAQs
Libraries of geodesy functions
The npm package geodesy receives a total of 12,260 weekly downloads. As such, geodesy popularity was classified as popular.
We found that geodesy demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.