Short answer: When it’s a JavaScript
arguments
object.
Long answer:
In a JavaScript package I’m writing, I have a function that returns an object.
There’s a bug in it where in certain situations it returns the JavaScript value
true.
I have a test framework set up with Mocha using the Chai assertion library. With
it, I can do
1
expect(result).to.eql(expected);
This means that the result I get back from my function should deeply equal the
expected value. “Deeply equal” means that the objects being compared are
identical — they’re the same type of object and store the same information.
In JavaScript, one would not expect an
Array to be deeply equal to an Object
because they’re different types of objects.
Similarly, but even more confusingly, both an empty Array and an empty Object
are considered to be deeply equal to the JavaScript true value:
12
expect(true).to.eql({});
expect(true).to.eql([]);
Both of these assertions pass.
When I was writing a test to ensure that my function wasn’t returning true,
but instead should be returning {}, I was expecting the assertion to fail. It
didn’t.
Since Chai is open source, I forked it, patched it, and submitted a pull request
to get the fix into the main Chai repository. It makes sure that when deep
equality is done, the types of both objects have to be the same.
This was over a month ago, and my pull request hasn’t been accepted.
See, JavaScript has a builtin arguments object, which is “Array-like” in that
it’s an ordered list of values. When you call a function, it’s the list of
arguments that you passed to that function:
12345
function dumpArgs() {
for (var i = 0; i < arguments.length; i++) {
console.log(i + " : " + arguments[i]);
}
}
This object is kind of like an Array, but the only Array method you can call on it is
length. It’s not an Array object, it’s an Arguments object.
I’m of the opinion that “deeply equals” means that if the objects are different,
they’re not deeply equal. The string "4" might look like it contains the same
value as the integer 4, but you wouldn’t expect them to be deeply equal, because
they’re different types of objects.
My patch hasn’t been pulled because the guy doing the pulling disagrees, which
you can see at the pull request comments. But
only for non-primitive types. “4” is still not deeply equal to 4, but if
arguments is [1,2,3] then that’s equal to the Array [1,2,3].
The Mozilla Developer Network docs say
The arguments object is not an Array. It is similar to an Array, but does not
have any Array properties except length. For example, it does not have the pop
method. However it can be converted to a real Array.
I could change my patch so that if the arguments object is one of the values
being tested, it could be converted to a real Array before doing the check, but
that goes against the concept of deep equality. Two objects of different types
shouldn’t be deeply equal.
So if you’re using the Chai assertion library, and you discover that an empty
Array is equal to true, you’re getting that result because one of the Chai
developers thinks that deeply equals is only applicable some of the time,
because it’s “subtle”.
In part one of this saga
I described how CIBC had sent me a text with a phone number to get them to call
them, and how this is wrong.
I just went through my spam folder and found this gem:
Dear BradCavanagh,
Please contact us as soon as possible at 1-866-454-4339 (in Canada & U.S.) or
416-785-1331 (from elsewhere) to verify recent transactions on your CIBC Credit
Card Account ending in XXXX.
We will also be phoning you at the primary number that we have on file for you
with this message.
We are available by phone 24 hours a day, 7 days a week.
Please do not reply to this e-mail.
If you received this message in error, please send an e-mail to
feedback@cibc.com.
Phishing emails and text messages are often sent out as spam to numerous
recipients and appear to come from legitimate businesses, sometimes even
duplicating legitimate logos and text. Within a phishing email, you may be
requested to click on a link that takes you to a fraudulent site or pop-up
window where you are asked to submit personal and financial information. A
phishing text message may request that you send personal information back to
the sender through text message or call a phone number.
In order to increase the chances of a response, messages may imply a sense of
urgency or an immediate risk to bank accounts or credit cards if you fail to
answer. Special offers and prizes may also be promoted as incentives.
I’ve bolded all of the ways that CIBC’s email falls under CIBC’s own definition
of phishing.
This morning I received a text message purporting to be from
CIBC:
BRAD,¡
Please call CIBC at 1-866-454-4339 to verify recent transactions on your
credit card ending in¡XXXX.
Yes, the ¡s were part of the text message, and I’ve X’ed out the last four
digits in my credit card.
This text came from the number “242-222”. I signed up for CIBC alerts via text
message, and they’ve all come from this number, but there’s nothing guaranteeing
that CIBC did in fact text me to get me to call them. In fact, if you search for 1-866-454-4339, you don’t
get any CIBC webpages in your results.
It’s very nice that CIBC has this service. It was actually a legitimate request,
as someone ordered over $1000 worth of stuff from walmart.com using my credit
card.
But CIBC is doing it wrong. There is nothing on this text message verifying that
this is actually CIBC. Sure, they get the last four digits of my credit card
right, but those are all over the place, and they’re not considered to be sensitive data,
which means that vendors do not need to do anything special to store them. It
would be rather trivial to get the last four digits of my credit card number, my
name, and my phone number, and then send a spoofed SMS.
If I were naive, I’d call the number listed in the text message, tell them my
full credit card number, and they’d be off to the races.
Never trust a text message, voicemail, or email that asks you to call a random
phone number to verify any sort of personal information. Never. Always call a
number that you know for a fact is linked with the company in question. For
CIBC, you can either look at the back of your credit card or look up customer
contact numbers on their website.
What CIBC should do is change their text message to read:
BRAD, please call CIBC Credit Card Services at the number listed on the back
of your Visa card to verify recent transactions on your card ending in XXXX.
It’s a simple change but one that would help make people less likely to fall for
phishing attacks.
CIBC should also list the 1-866-454-4339 number on their website, proving that
it is actually a CIBC number. I didn’t call that number because there’s no way
of verifying that it’s actually CIBC.
A phishing text message may request that you send personal information back to
the sender through text message or call a phone number.
In order to increase the chances of a response, messages may imply a sense of
urgency or an immediate risk to bank accounts or credit cards if you fail to
answer.
CIBC Credit Card Fraud Department, you’re doing it wrong. Even according to your
own website.
If you upgrade Elasticsearch from 0.20 to 0.90, any queries you previously made
using a front slash will fail with an error similar to:
1234567891011
"error" : "SearchPhaseExecutionException[Failed to execute phase [query],
total failure; shardFailures {[tJ5MGSY_RnOHfeAN2O8gnQ][twitter][2]:
SearchParseException[[twitter][2]: from[-1],size[-1]: Parse Failure [Failed to
parse source [{\n \"query\":{\n \"query_string\":{\n
\"query\":\"user:kimchy/banon\"\n }\n }\n}]]]; nested:
QueryParsingException[[twitter] Failed to parse query [user:kimchy/banon]];
nested: ParseException[Cannot parse 'user:kimchy/banon': Lexical error at line
1, column 18. Encountered: <EOF> after : \"/banon\"]; nested:
TokenMgrError[Lexical error at line 1, column 18. Encountered: <EOF> after :
\"/banon\"]; }{[tJ5MGSY_RnOHfeAN2O8gnQ][twitter][0]:
...
If you’re like me, you’re thinking “but my query doesn’t have an EOF in it, it’s
valid JSON”, and you’d be right. Your query is still valid JSON, but it’s no
longer a valid Elasticsearch query.
When Elasticsearch moved from 0.20 to 0.90, they changed versions of Lucene as
well, going from 3 to 4. Under Lucene 4, a query with a slash in it is
interpreted as a regular expression. Your regular expression starts with the
slash, but if you only have one slash, it never ends, so you get the
Encountered: <EOF> after : error.
You will need to convert your queries to escape out slashes. Thus, a 0.20 query
of:
I’m a big supporter of the NDP. I voted for the NDP in the last federal
election. I’ve considered becoming a member of the federal NDP. I agree with a
lot of the NDP’s policies.
But I won’t be voting for them in the 2013 BC election.
I really like what they’re doing around electoral reform, specifically their
promise to ban union and corporate political donations.
I really like that they’ll increase the corporate income tax rate to 12%.
I really like that they’re going to expand the carbon tax to oil and gas
operations, and use a portion of the carbon tax revenues to fund transit and
green programs.
Judy Darcy, the NDP candidate for New Westminster, called me to talk about their
plans for better community healthcare centres, improving families’ access to
health professionals. That nearly won me over.
But I’m still not going to vote for them. They’re a very close second choice,
though.
I’m not voting for them for two reasons:
One, they’re going to win in my riding of New Westminster). In the 16 elections since 1953, the CCF/NDP has won 15 times and the BC Liberal party once. New Westminster is a safe NDP seat. Even the unofficial burger poll has the NDP well ahead. Me not voting for the NDP isn’t going to make a lick of difference in New Westminster.
Two, they don’t go far enough on electoral reform. They’re entrenched as one of
two major parties in BC, and they don’t want to give that up. I would love it if
they revisited some form of proportional representation, but there’s no mention of
that in their platform.
Those two reasons are why I won’t be voting NDP on Tuesday.
On 11 May 2013 the Vancouver Sun published a list of 20 hot topics in the
upcoming BC election with the positions of the four major parties. Based upon
their responses, the BC Liberals have put a lot of their eggs in the Liquified
Natural Gas basket.
The BC Liberals are proposing that LNG be expanded greatly in BC over the coming
years, and the revenues from that will be fed into a BC Prosperity Fund. This
Prosperity Fund is listed in four of the twenty topics:
Housing/poverty: No specific housing promises, but creating of an
LNG-funded BC Prosperity Fund will help ease affordability problems.
Energy/pipelines/LNG: Preconditions demanded before support for Northern
Gateway, Kinder Morgan; LNG to fund new BC Prosperity Fund. Support Kitimat
oil refinery, new fracking rules.
Balanced budgets/debt: Limit government spending growth to GDP; create BC
Prosperity Fund for debt reduction; 50% of excess revenues to debt reduction.
Crown corporations: A third of new BC Prosperity Fund revenues to pay down
BC Ferries debt; accelerate paydown of BC Hydro and Port Mann Bridge debt.
With these kinds of errors in estimating natural gas revenues, the BC Liberals
are gambling on BC’s economic future. Not only that, they’re doing it with a
fossil fuel, in the same month that carbon dioxide levels have passed 400ppm.
We need to reduce the amount of fossil fuels we dig up and burn, not increase.
The BC Liberals are proposing burning and polluting our way to prosperity, which
in this day and age is the last thing we should be doing.
This isn’t the only reason I’m not going to vote for the BC Liberals, but it’s a
fairly major reason.
The BC Conservatives are planning on scrapping the carbon tax,
bribing Lower Mainland drivers with a $408 tax credit for frequent toll and
ferry users, expanding mining, supporting the Northern Gateway
pipeline and Kinder Morgan pipeline expansion, and
so on, and so on.
Those who know me know that I’m pretty left-wing. That’s why I won’t be voting
for the BC Conservatives.
Let’s face reality: the Green Party isn’t going to win the 2013 BC Election.
They might win one or
two seats. They’ll probably get 9-10% of the popular
vote.
And that is why I’m voting for the Green Party on Tuesday.
I’m voting for the Green Party in hopes that the smaller parties’ voices get a
little louder. Getting 10% of the vote but 0% of the seats isn’t fair.
So why the Green Party and not the BC Conservatives? Greens are more leftist,
and they don’t promote a future that’s based on fossil fuel burning. Vancouver
is aiming to become the world’s greenest city by 2020,
and BC should aim to become the greenest province.
They have some wingnut ideas about Smart Meters and BC Hydro (they say they’ll
instruct BC Hydro to provide customers with various concerns with a wired-in
Smart Meter, then say they’d place BC Hydro under the BC Utilities Commission so
that the provincial government can’t interfere in the operations of BC Hydro —
these two things appear to be at odds with each other), but I’m willing to let those slide.
It’s a strategic vote. I know my candidate won’t get elected, but
I hope that enough people province-wide will vote Green (and enough people on
Vancouver Island vote Green to elect a couple to office) so that smaller parties
can get a little more recognition.
Why not the BC NDP? when I did the CBC Vote Compass the Greens and
NDP were tied at the top for my results. The NDP are going to win my riding
whether or not I vote for them. My Green vote is a safe one. If I lived in a
riding where the Liberal stood a chance, I’d probably vote NDP, but I don’t, so
I won’t.
Of course, the election isn’t for another couple of days, so I might change my
mind…
I like to use the phrase “fractally wrong”. Loosely, it means “wrong no matter
how deep you look” or “wrong no matter how many ways you look”. It’s best served
up with an example.
Driving across Vancouver’s west side, wearing a dirt-stained Whitecaps hat, yoga
pants and a black Lululemon sweater, Christy Clark is just another mother
driving her son to school.
She’s been on the road since 5:10 a.m., having taken 11-year-old Hamish to an
early morning goalie clinic across town.
In her son’s bag is the pizza and Krispy Kreme doughnut Clark packed for his
lunch. Left on the dining room table at home is the raffle-ticket sign-up form
that still needs to be completed.
At times, the two seem more like sidekicks – siblings even – than they do mother
and son. And especially so the morning when the two were on their way to
Hamish’s goalie clinic.
“Let’s see you go through this red light,” Hamish challenged as they pulled up
that morning, at 5:15 a.m., to an abandoned Vancouver intersection.
“I might. Don’t test me,” Clark replies.
“Yeah. Go ahead.”
“Should I?”
“There’s no one.”
“Would you go through? You shouldn’t because that would be breaking the law,”
she says.
And with that the car has already sailed underneath the stale red stoplight and
through the empty intersection.
“You always do that,” says Hamish.
Of course, the obvious first level of wrong is that she blew through a red
light. With her son in the car. At her son’s urging. That’s pretty wrong.
But then you dig deeper. She did that with a Vancouver Sun reporter in the back.
That’s stupid, and another level of wrong.
But then you dig deeper. She apparently always does this. That’s another level
of wrong.
But then you dig deeper. “In her son’s bag is the pizza and Krispy Kreme dougnut
Clark packed for his lunch.” Honestly? Her son is athletic (as is evidenced by
being in goalie camp) but gets horrible nutrition for lunch? That’s pretty
wrong.
But then you dig deeper. Her son’s eleven. He’s old enough to pack his own
lunch.
But then you dig deeper. Krispy Kreme is an American company. Why not Tim
Hortons? That’s pretty wrong.