Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
A ruby gem to support validating CSV files to check their syntax and contents.
Add this line to your application's Gemfile:
gem 'csvlint'
And then execute:
$ bundle
Or install it yourself as:
$ gem install csvlint
You can either use this gem within your own Ruby code, or as a standolone command line application
After installing the gem, you can validate a CSV on the command line like so:
csvlint myfile.csv
You will then see the validation result, together with any warnings or errors e.g.
myfile.csv is INVALID
1. blank_rows. Row: 3
1. title_row.
2. inconsistent_values. Column: 14
You can also optionally pass a schema file like so:
csvlint myfile.csv --schema=schema.json
Currently the gem supports retrieving a CSV accessible from a URL, File, or an IO-style object (e.g. StringIO)
require 'csvlint'
validator = Csvlint::Validator.new( "http://example.org/data.csv" )
validator = Csvlint::Validator.new( File.new("/path/to/my/data.csv" ))
validator = Csvlint::Validator.new( StringIO.new( my_data_in_a_string ) )
When validating from a URL the range of errors and warnings is wider as the library will also check HTTP headers for best practices
#invoke the validation
validator.validate
#check validation status
validator.valid?
#access array of errors, each is an Csvlint::ErrorMessage object
validator.errors
#access array of warnings
validator.warnings
#access array of information messages
validator.info_messages
#get some information about the CSV file that was validated
validator.encoding
validator.content_type
validator.extension
validator.row_count
#retrieve HTTP headers from request
validator.headers
The validator supports configuration of the CSV Dialect used in a data file. This is specified by passing a dialect hash to the constructor:
dialect = {
"header" => true,
"delimiter" => ","
}
validator = Csvlint::Validator.new( "http://example.org/data.csv", dialect )
The options should be a Hash that conforms to the CSV Dialect JSON structure.
While these options configure the parser to correctly process the file, the validator will still raise errors or warnings for CSV structure that it considers to be invalid, e.g. a missing header or different delimiters.
Note that the parser will also check for a header
parameter on the Content-Type
header returned when fetching a remote CSV file. As
specified in RFC 4180 the values for this can be present
and absent
, e.g:
Content-Type: text/csv; header=present
The validator provides feedback on a validation result using instances of Csvlint::ErrorMessage
. Errors are divided into errors, warnings and information
messages. A validation attempt is successful if there are no errors.
Messages provide context including:
category
has a symbol that indicates the category or error/warning: :structure
(well-formedness issues), :schema
(schema validation), :context
(publishing metadata, e.g. content type)type
has a symbol that indicates the type of error or warning being reportedrow
holds the line number of the problemcolumn
holds the column number of the issuecontent
holds the contents of the row that generated the error or warningThe following types of error can be reported:
:wrong_content_type
-- content type is not text/csv
:ragged_rows
-- row has a different number of columns (than the first row in the file):blank_rows
-- completely empty row, e.g. blank line or a line where all column values are empty:invalid_encoding
-- encoding error when parsing row, e.g. because of invalid characters:not_found
-- HTTP 404 error when retrieving the data:stray_quote
-- missing or stray quote:unclosed_quote
-- unclosed quoted field:whitespace
-- a quoted column has leading or trailing whitespace:line_breaks
-- line breaks were inconsistent or incorrectly specifiedThe following types of warning can be reported:
:no_encoding
-- the Content-Type
header returned in the HTTP request does not have a charset
parameter:encoding
-- the character set is not UTF-8:no_content_type
-- file is being served without a Content-Type
header:excel
-- no Content-Type
header and the file extension is .xls
:check_options
-- CSV file appears to contain only a single column:inconsistent_values
-- inconsistent values in the same column. Reported if <90% of values seem to have same data type (either numeric or alphanumeric including punctuation):empty_column_name
-- a column in the CSV header has an empty name:duplicate_column_name
-- a column in the CSV header has a duplicate name:title_row
-- if there appears to be a title field in the first row of the CSVThere are also information messages available:
:nonrfc_line_breaks
-- uses non-CRLF line breaks, so doesn't conform to RFC4180.:assumed_header
-- the validator has assumed that a header is presentThe library supports validating data against a schema. A schema configuration can be provided as a Hash or parsed from JSON. The structure currently follows JSON Table Schema with some extensions and rudinmentary CSV on the Web Metadata.
An example JSON Table Schema schema file is:
{
"fields": [
{
"name": "id",
"constraints": {
"required": true,
"type": "http://www.w3.org/TR/xmlschema-2/#integer"
}
},
{
"name": "price",
"constraints": {
"required": true,
"minLength": 1
}
},
{
"name": "postcode",
"constraints": {
"required": true,
"pattern": "[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}"
}
}
]
}
An equivalent CSV on the Web Metadata file is:
{
"@context": "http://www.w3.org/ns/csvw",
"url": "http://example.com/example1.csv",
"tableSchema": {
"columns": [
{
"name": "id",
"required": true,
"datatype": { "base": "integer" }
},
{
"name": "price",
"required": true,
"datatype": { "base": "string", "minLength": 1 }
},
{
"name": "postcode",
"required": true
}
]
}
}
Parsing and validating with a schema (of either kind):
schema = Csvlint::Schema.load_from_json(uri)
validator = Csvlint::Validator.new( "http://example.org/data.csv", nil, schema )
This gem passes all the validation tests in the official CSV on the Web test suite (though there might still be errors or parts of the CSV on the Web standard that aren't tested by that test suite).
Supported constraints:
required
-- there must be a value for this field in every rowunique
-- the values in every row should be uniqueminLength
-- minimum number of characters in the valuemaxLength
-- maximum number of characters in the valuepattern
-- values must match the provided regular expressiontype
-- specifies an XML Schema data type. Values of the column must be a valid value for that typeminimum
-- specify a minimum range for values, the value will be parsed as specified by type
maximum
-- specify a maximum range for values, the value will be parsed as specified by type
datePattern
-- specify a strftime
compatible date pattern to be used when parsing date values and min/max constraintsSupported data types (this is still a work in progress):
http://www.w3.org/2001/XMLSchema#string
(effectively a no-op)http://www.w3.org/2001/XMLSchema#integer
or http://www.w3.org/2001/XMLSchema#int
http://www.w3.org/2001/XMLSchema#float
http://www.w3.org/2001/XMLSchema#double
http://www.w3.org/2001/XMLSchema#anyURI
http://www.w3.org/2001/XMLSchema#boolean
http://www.w3.org/2001/XMLSchema#nonPositiveInteger
http://www.w3.org/2001/XMLSchema#positiveInteger
http://www.w3.org/2001/XMLSchema#nonNegativeInteger
http://www.w3.org/2001/XMLSchema#negativeInteger
http://www.w3.org/2001/XMLSchema#date
http://www.w3.org/2001/XMLSchema#dateTime
http://www.w3.org/2001/XMLSchema#gYear
http://www.w3.org/2001/XMLSchema#gYearMonth
http://www.w3.org/2001/XMLSchema#time
Use of an unknown data type will result in the column failing to validate.
Schema validation provides some additional types of error and warning messages:
:missing_value
(error) -- a column marked as required
in the schema has no value:min_length
(error) -- a column with a minLength
constraint has a value that is too short:max_length
(error) -- a column with a maxLength
constraint has a value that is too long:pattern
(error) -- a column with a pattern
constraint has a value that doesn't match the regular expression:malformed_header
(warning) -- the header in the CSV doesn't match the schema:missing_column
(warning) -- a row in the CSV file has a missing column, that is specified in the schema. This is a warning only, as it may be legitimate:extra_column
(warning) -- a row in the CSV file has extra column.:unique
(error) -- a column with a unique
constraint contains non-unique values:below_minimum
(error) -- a column with a minimum
constraint contains a value that is below the minimum:above_maximum
(error) -- a column with a maximum
constraint contains a value that is above the maximumYou can also provide an optional options hash as the fourth argument to Validator#new. Supported options are:
options = {
limit_lines: 100
}
validator = Csvlint::Validator.new( "http://example.org/data.csv", nil, nil, options )
Validator
object. For example, this will return the current line number for every line validated:options = {
lambda: ->(validator) { puts validator.current_line }
}
validator = Csvlint::Validator.new( "http://example.org/data.csv", nil, nil, options )
=> 1
2
3
4
.....
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)The codebase includes both rspec and cucumber tests, which can be run together using:
$ rake
or separately:
$ rake spec
$ rake features
When the cucumber tests are first run, a script will create tests based on the latest version of the CSV on the Web test suite, including creating a local cache of the test files. This requires an internet connection and some patience. Following that download, the tests will run locally; there's also a batch script:
$ bin/run-csvw-tests
which will run the tests from the command line.
If you need to refresh the CSV on the Web tests:
$ rm bin/run-csvw-tests
$ rm features/csvw_validation_tests.feature
$ rm -r features/fixtures/csvw
and then run the cucumber tests again or:
$ ruby features/support/load_tests.rb
FAQs
Unknown package
We found that wjordan213-csvlint 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.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.