Skip to content

Decode() accepts latitude digits beyond North Pole #184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
viettaml opened this issue Jul 27, 2018 · 13 comments
Closed

Decode() accepts latitude digits beyond North Pole #184

viettaml opened this issue Jul 27, 2018 · 13 comments
Assignees

Comments

@viettaml
Copy link
Contributor

"C2000000+" is a slice at the North Pole. But Decode() will accept "F2000000+" and return a CodeArea with latitude values of 110 degrees.

Now that I think about it, Decode() has no way of signaling an error other than returning an invalid CodeArea, so maybe the solution is to add an IsValid() method to CodeArea.

@viettaml viettaml changed the title Decode() accepts latitude digits "past" North Pole Decode() accepts latitude digits beyond North Pole Jul 27, 2018
@viettaml
Copy link
Contributor Author

(Forgot to mention I observed this in the cpp implementation; can't speak to the others.)

@viettaml
Copy link
Contributor Author

viettaml commented Aug 2, 2018

Looking at the Decode() implementation some more, it's clear that it doesn't perform any sort of validation. And maybe that's intentional, in which case the correct "fix" would be for openlocationcode::IsValid() to reject codes such as "F2...".

@bocops
Copy link
Contributor

bocops commented Aug 2, 2018

(Forgot to mention I observed this in the cpp implementation; can't speak to the others.)

Seems to be true for the Java implementation as well. There's isValidCode(String) which does check the first two characters of a plus code - but that method doesn't seem to be called from decode() either directly or indirectly.

@bocops
Copy link
Contributor

bocops commented Aug 2, 2018

Actually, disregard that. In the Java implementation, an OpenLocationCode object can only be created with a code string that passed the isValidCode() check in the first place.

@zongweil
Copy link
Contributor

zongweil commented Aug 2, 2018

@drinckes what do you think about this? Should we modify isValid in the C++ implementation?

@viettaml
Copy link
Contributor Author

viettaml commented Aug 2, 2018

I think maybe this is working as intended, and that what I think of as "IsValid()" is actually fulfilled by "IsFull()" which does appear to validate (albeit inefficiently) the first two digits.

@drinckes
Copy link
Contributor

drinckes commented Aug 3, 2018

I'm not a c++ expert so I'm happy to defer to others on what the best solution is. Since we don't throw exceptions, we're going to accept an invalid string and return something. The question is, what should the something be?

I'm tending to lean away from adding a flag attribute to the codeArea but I'm reasonably happy with saying that a code area that is all zeros (lat lo, lat hi, lng lo, lng hi, codelen) indicates invalid input, and following @viettaml original suggestion to (at least for C++) add an isValid() to the codearea class.

That means:

  • there will be some languages where bad input results in throwing an exception (Java, Javascript) or returning an error (Go)
  • in other languages decode() returns a CodeArea object with an isValid() method, and encode() with invalid input returns an empty string (say)

What do you think?

@viettaml
Copy link
Contributor Author

viettaml commented Aug 6, 2018

SGTM. I'll have a go at implementing this when I have a few minutes. Thanks!

@viettaml
Copy link
Contributor Author

viettaml commented Aug 6, 2018

#185

@drinckes
Copy link
Contributor

drinckes commented Aug 7, 2018

An alternative (and I know you did just send a pr), would be to refactor decode() to take as arguments the code string, and a pointer to a CodeArea, and return a bool depending on whether the code string was valid:

  ca = openlocationcode::CodeArea();
  if (openlocationcode::Decode(query, &ca)) {
    // the query was a valid code, ca now holds the decoded values.
  } else {
    // query is not a valid code
  }

That would change the method signature though. At first thought that's a disadvantage, but it would mean that because the code would have to be refactored, anyone using this method would be more likely to add this kind of check to it.

@viettaml what do you think? (It's ok to say "yeah nah".)

@viettaml
Copy link
Contributor Author

viettaml commented Aug 7, 2018

I'm reluctant to change the syntax of an existing function, though I'm more open to adding or overloading the function. That being said, even after my PR Decode() doesn't do a full job of validating codes, so I wouldn't want users relying on it to do so (they should use "IsFull()" instead or first, which does seem to reject the out-of-range codes that initially prompted this report, in addition to various other syntactic errors).

With that in mind, following the philosophy of avoiding duplicated or overlapping functionality in an API, I'm inclined to leave Decode() as-is. By the same argument my PR isn't strictly necessary, and I'd be okay with that too.

@drinckes
Copy link
Contributor

Let's close this since we seem to have settled on doing nothing. ;-)

Feel free to reopen if you change your mind!

@fulldecent
Copy link
Contributor

fulldecent commented Apr 25, 2021

A full code MUST match one these regular expressions:

  1. /^[2-9C][2-9CFGHJMPQRV]0{6}\+$/
    
  2. /^[2-9C][2-9CFGHJMPQRV][2-9CFGHJMPQRVWX]{2}0{4}\+$/
    
  3. /^[2-9C][2-9CFGHJMPQRV][2-9CFGHJMPQRVWX]{4}0{2}\+$/
    
  4. /^[2-9C][2-9CFGHJMPQRV][2-9CFGHJMPQRVWX]{6}\+([2-9CFGHJMPQRVWX]{2,7})?$/
    

I am working to add this to the specification.

And so the above is not valid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants