• GuruBob (unregistered)

    validateUserInput("FRIST")

  • Hal (unregistered)

    The totally wrong validation aside the rubyist could be forgiven for the gratuitous to_s. It’s entirely possible some String like but not a string thing might get passed in; for a example an object representing a database attribute, where to_s is probably a synonym for .value. It’s also possible in the case of alternative implementations of ruby you might get a nonnative String like a Java String.

    In the worst case calling to_s probably rolls up to Object’s to_s and that will get you a string representation if it’s I’d. So if the situation is you expect a string but their is any potential for the caller to send you something that naturaly coerces to a ruby string; it’s probably faster to just do a to_s than it would be to type test and then validate. The to_s will protect you from a no method exception if you subsequently call String functions and if your validation is strong you can still raise your own argument error exception based on the data being not what you were expecting.

  • Sole Purpose Of Visit (unregistered) in reply to Hal

    I'll assert that "coercing something into a string" is a dangerous thing to do in any language (unless purely for display purposes).

    I believe, for example, that Ruby supports something like

    double d = 123.456
    string s = d.to_str
    

    (Syntax probably wrong). Now, this version might or might not be validated correctly. Imagine the case where the string is formatted in some way, for some locale, for some purpose, possibly by override. I can definitely see this coming out with a "phone number" that is not a valid phone number, but is still a valid string.

    Plus which, if you are going to validate phone numbers when storing them in a database, stick the validation in the database. This is not rocket science.

  • Early bird (unregistered)

    When dealing with user inputs we (a team of devs and I) generally don't get away with assumptions like "the data in the database is valid". We usually end up with validations in JavaScript that run client side, then we validate again in the controllers that runs server side, and there's some basic validation on the DB side. Any layer that touches user input without validation gets flagged by our static code analysis tools. In effect, duplicate code is required to pass security scans.

    So seeing this snippet of code that validates the phone number again doesn't seem out of place at all to me. Sure it's not a great implementation, but the article makes it sound doing any validation on 'trusted user input' here is the WTF. User in put isn't trustworthy because one link in the chain checked it. Should a compromise occur in any one layer, it's the validation in other layers that might prevent it from spreading.

    Am I the only one bending over backwards like this to comply with code scanning tools?

  • Hal (unregistered) in reply to Sole Purpose Of Visit

    Assert it all you like - but your argument boils down then to thou shalt always use a language with strict type safety.

    That is a supportable position. However a lot of the software world has not embraced that ideological purity. In my view if you expect to get a String as an input a few things are already true:

    1. hopefully we are already nearly in the realm of display or reporting logic because if we were trying to do any calculating on strings beside maybe counting them, we already have a huge a mess on our hands.

    2. we have some strict rules and standards we can apply to the input string to know that it is valid, because lets face it if I think there is any possibility the caller could send me the wrong type of thing - its a for damn sure they could send me a malformed string...

    So I come back to in a language like Ruby if its already the case where I expect a type String, and I plan to do some validation on it; then I believe the right thing to do is just call .to_s on the input. This is after all what the standard library does in most such cases. The alternative would be do test the result of .is_a? String, or .instance_of? String and raise an exception if I get something else. That is a lot more code than just .to_s, which will be no-op (returns self) if its already a String, or probably does the right thing if it runs out to something like a MyDatabaseEngine::QueryResult::Field instance. At that point either I can verify its valid using some combination of String instance methods and Regex or raise an exception anyway. If something does not have a to_s implementation i'll get something like "#YourFancyObject:0x0000000FFFFFF0a". If I can't tell that isn't what I expected - String is probably so far the right way to be passing data around the whole situation is hopeless, or we are in a domain like 'names of people' and the calling code is so wrong raising an ArgumentError here really going to help anyone find the source of the bug either.

  • (nodebb) in reply to Sole Purpose Of Visit

    Though it may be worthwhile to do some simple redundant validation at an outer level (to save a call to the inner level and the network trip in between), provided that it doesn't (a) block any inputs that should be valid, or (b) burn more processing time than is justified by the savings.

  • Randal L. Schwartz (google)

    /\A\+[0-9]+\Z/ is wrong. You almost always want capital A in the front and lowercase z in the end. RTFM for how that is different.

  • Yikes (unregistered) in reply to Randal L. Schwartz

    RTFM available here: http://ruby-doc.com/docs/ProgrammingRuby/html/language.html#UJ

    \Z is indeed kind of funny

  • (nodebb)

    If I'm not mistaken, according ITU standards for international telephony, phone numbers can have a total of up to 15 digits, country code included, preceding zeroes and any non-numeric characters excluded. How many below that is up to each country though, so technically the minimum is 2 digits (a one-digit country code followed by a one-digit internal phone number). Any check on the length of a fully qualified phone number should always look for 2 to 15 digits.

  • (nodebb)

    So Ruby regexes are TRWTF, amirite?

  • (nodebb) in reply to Steve_The_Cynic

    @Steve_The_Cynic you could leave "Ruby" or "regexes" out of your question and I'm still in agreement.

  • (nodebb)

    I miss named exchanges on USA phone numbers.... I will forever be a Juniper-8

  • Sole Purpose Of Visit (unregistered) in reply to Hal

    That's true, and I do like strong typing.

    But this field is not a string. It is a phone number, and phone numbers have their own semantics. Coercion to a string ain't gonna be helpful, no matter where you put it.

    Since the phone number is persisted in the database, it is obviously important that the semantics of the phone number are also implemented in the database. (I'd accept an ORM solution, provided that this is the only way into the database.) As such, you're going to have to respect the interface offered by the database -- in this case, a string. Not doing so is just loading a shotgun and pointing it at your feet.

    Validation on input? (Say, a web page.) Also a good idea, for obvious reasons. And if you want to coerce that input into a string, and do other validation checks, go ahead. But it won't matter a damn if it doesn't meet the database schema. Which will hopefully be strongly typed .... to a valid phone number. (I18N being presumably a conjoined requirement.)

  • Conradus (unregistered) in reply to TheCPUWizard

    Named exchanges? Jeez, and I thought I was an old cuss, and the only way I know about named exchanges is from old movies and Stan Freberg ("They took away our Murray Hills").

  • (nodebb) in reply to TheCPUWizard

    I was National-6. My cousin in the next town over had a Yukon-6 number.

  • (nodebb)

    The real WTF is using Ruby.

    Oh how I hated that piece of
    crap back when I was forced to use it.

  • WTFGuy (unregistered)

    Aree 100% W Sole Purpose of Visit that there ought to be strongly typed objects representing e.g. phone numbers (and all other business concepts) everywhere. All such objects being directly serializable over the wire and to/from any form of file or database storage and with all such gizmos fully inter-language and inter-machine interchangeable.

    Sadly that nirvana state is the opposite of the way development has gone in the last 20+ years. Instead strings with implied business domain semantics are the lingua franca (more like an impoverished pidgin actually) of multi-tiered multi-vendored development.

    Given we've got to do this job (i.e. all our jobs) the ugly way, let's at least all learn to do themwell. Unlike the devs in today's example.

  • David Mårtensson (unregistered) in reply to Early bird

    I agree.

    Unless the database can enforce fully valid data we should not trust the database. If the database is a string and we need to enforce some subset of a string, we should check.

    Even if the current code inserting into the database do such checks, there are not guarantee that future code will and I have seen to many cases where strange things end up in phone number fields ... because it was possible.

    And with the general problem of validating international phone numbers, such validation is often either to forgiving or to strict and in the second case its often made less strict when to many customers are affected.

    Common case is adding multiple numbers after each other, with out without a comma to separate them.

  • Richard A. O'Keefe (unregistered)
    Comment held for moderation.

Leave a comment on “A Valid Call”

Log In or post as a guest

Replying to comment #:

« Return to Article