Skip to content

[Detail Bug] Location factories accept NaN/Infinity/out-of-range coordinates, producing malformed requests #78

@detail-app

Description

@detail-app

Detail Bug Report

https://app.detail.dev/org_befd6425-a158-4e24-9d4d-1e5c08769515/bugs/bug_37f0491a-d529-42ea-bf5b-bf2a9b116b57

Introduced in 33eca2a by @WilliamAGH on Jan 15, 2026

Summary

  • Context: UserLocation.fromLatitudeLongitude(), SearchLocation.fromLatitudeLongitude(), and RouteLocation.fromLatitudeLongitude() do not validate coordinate bounds, creating an inconsistency with DirectionsEndpoint.fromLatitudeLongitude() which does validate.
  • Bug: UserLocation.fromLatitudeLongitude(), SearchLocation.fromLatitudeLongitude(), and RouteLocation.fromLatitudeLongitude() do not validate coordinate bounds, creating an inconsistency with DirectionsEndpoint.fromLatitudeLongitude() which does validate.
  • Actual vs. expected: Actual: invalid coordinates (NaN, Infinity, out-of-range) are accepted and formatted into query strings (e.g., userLocation=NaN%2C-122.4). Expected: fail-fast IllegalArgumentException via Location.validateLatitudeLongitude() with clear messages (e.g., latitude must be finite / within [-90, 90]).
  • Impact: Invalid coordinates (NaN, Infinity, out-of-range) produce malformed query strings; fail-fast validation is bypassed; library exhibits inconsistent behavior for identical operations.

Code with Bug

UserLocation.java:

public static UserLocation fromLatitudeLongitude(double latitude, double longitude) {
    return new UserLocation(formatCoordinatePair(latitude, longitude)); // <-- BUG 🔴 missing coordinate validation
}

DirectionsEndpoint.java (reference behavior):

public static DirectionsEndpoint fromLatitudeLongitude(double latitude, double longitude) {
    Location.validateLatitudeLongitude(latitude, longitude);  // Validates!
    return new DirectionsEndpoint(formatCoordinatePair(latitude, longitude));
}

Explanation

  • Java parsing does not prevent these values: Double.parseDouble("NaN") returns NaN, and Double.parseDouble("Infinity") returns Infinity; out-of-range numerics like "91.0" also parse successfully. Therefore, relying on parsing to reject invalid coordinates is incorrect.
  • There are production paths that pass raw doubles directly to UserLocation.fromLatitudeLongitude() without validation (e.g., CLI parsing env var/flags in AppleMapsCli.java), so invalid input can reach these constructors.
  • RouteLocation is used for required ETA inputs (EtaInput requires origin and destinations), so missing validation affects required request parameters, not just optional hints.
  • A reusable validator already exists (Location.validateLatitudeLongitude) and is already used by DirectionsEndpoint.fromLatitudeLongitude(), indicating the intended pattern.

Codebase Inconsistency

  • DirectionsEndpoint.fromLatitudeLongitude() validates coordinates, but UserLocation/SearchLocation/RouteLocation do not, even though all are constructed from the same lat/long inputs and the docs/tests demonstrate using these factory methods with raw doubles.

Recommended Fix

Add Location.validateLatitudeLongitude(latitude, longitude); to:

  • UserLocation.fromLatitudeLongitude(...)
  • SearchLocation.fromLatitudeLongitude(...)
  • RouteLocation.fromLatitudeLongitude(...)

Example:

public static UserLocation fromLatitudeLongitude(double latitude, double longitude) {
    Location.validateLatitudeLongitude(latitude, longitude);
    return new UserLocation(formatCoordinatePair(latitude, longitude));
}

History

This bug was introduced in commit 33eca2a. The commit created the fromLatitudeLongitude() factory methods for all four coordinate types (UserLocation, SearchLocation, RouteLocation, DirectionsEndpoint) without coordinate bounds validation. Later, commit f83c5e2 added validation to DirectionsEndpoint and created the reusable Location.validateLatitudeLongitude() method, but failed to apply it to the other three types—creating an inconsistent API where only DirectionsEndpoint validates coordinates.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions